Stop an object from glitching in pygame - python

I am trying to make a game like pong using pygame I currently have the two rectangles however one glitches I dont know why, I commented win.fill((0, 0, 0)) and it stops one of the rectangles from glitching but the other one does not this is what I have:
# import pygame module in this program
import pygame
# activate the pygame library .
# initiate pygame and give permission
# to use pygame's functionality.
pygame.init()
# create the display surface object
# of specific dimension..e(500, 500).
win = pygame.display.set_mode((1280, 720))
# set the pygame window name
pygame.display.set_caption("Pong")
# object1 current co-ordinates
x = 15
y = 280
# object2 current co-ordinates
x1 = 1245
y1 = 280
# dimensions of the object1
width = 20
height = 130
# dimensions of the object2
width1 = 20
height1 = 130
# velocity / speed of movement
vel = 10
# Indicates pygame is running
run = True
# infinite loop
while run:
# creates time delay of 10ms
pygame.time.delay(0)
# iterate over the list of Event objects
# that was returned by pygame.event.get() method.
for event in pygame.event.get():
# if event object type is QUIT
# then quitting the pygame
# and program both.
if event.type == pygame.QUIT:
# it will make exit the while loop
run = False
# stores keys pressed
keys = pygame.key.get_pressed()
# if left arrow key is pressed
if keys[pygame.K_w] and y > 0:
# decrement in y co-ordinate
y -= vel
# if left arrow key is pressed
if keys[pygame.K_s] and y < 720-height:
# increment in y co-ordinate
y += vel
# completely fill the surface object
# with black colour
win.fill((0, 0, 0))
# drawing object on screen which is rectangle here
pygame.draw.rect(win, (0, 0, 255), (x, y, width, height))
# it refreshes the window
pygame.display.update()
keys2 = pygame.key.get_pressed()
# if left arrow key is pressed
if keys2[pygame.K_UP] and y1 > 0:
# decrement in y co-ordinate
y1 -= vel
# if left arrow key is pressed
if keys2[pygame.K_DOWN] and y1 < 720-height:
# increment in y co-ordinate
y1 += vel
# completely fill the surface object
# with black colour
win.fill((0, 0, 0))
# drawing object on screen which is rectangle here
pygame.draw.rect(win, (255, 255, 255), (x1, y1, width1, height1))
# it refreshes the window
pygame.display.update()
# closes the pygame window
pygame.quit()

Call pygame.disaply.update() only once at the end of the application loop. Multiple calls to pygame.display.update() or pygame.display.flip() cause flickering. See Why is the PyGame animation is flickering. Also clear the display only once per frame.
You are actually drawing on a Surface object. If you draw on the Surface associated to the PyGame display, this is not immediately visible in the display. The changes become visible, when the display is updated with either pygame.display.update() or pygame.display.flip().
If you clear the display, all previously drawn elements become invisible. Therefore, clear the display once at the beginning of the frame and update it once at the end of the frame.
The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
clock = pygame.time.Clock()
run = True
# application loop
while run:
# limit the frames per second to limit CPU usage
clock.tick(100)
# handle the events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# update the game states and positions of objects
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and y > 0:
y -= vel
if keys[pygame.K_s] and y < 720-height:
y += vel
if keys[pygame.K_UP] and y1 > 0:
y1 -= vel
if keys[pygame.K_DOWN] and y1 < 720-height:
y1 += vel
# clear the display
win.fill((0, 0, 0))
# draw the entire scene
pygame.draw.rect(win, (0, 0, 255), (x, y, width, height))
pygame.draw.rect(win, (255, 255, 255), (x1, y1, width1, height1))
# update the display
pygame.display.update()

Related

i cant figure out my python game keep crashing

please help when i press space, e, or f my game crashes but i cant find out why also can you help me make this dam block move upwards. please help me i will go insane if i cant figure this out.
`
# import the pygame module
import pygame
import keyboard
import time
xb = 30
yb = 670
x = 30
y = 670
o = 0
# Define the background colour
# using RGB color coding.
background_colour = (10,10,10)
# Define the dimensions of
# screen object(width,height)
screen = pygame.display.set_mode((800, 750),pygame.RESIZABLE)
# Set the caption of the screen
pygame.display.set_caption('shoter')
# Fill the background colour to the screen
screen.fill(background_colour)
def player():
color = (40,40,45)
pygame.draw.rect(screen, color, pygame.Rect(x, y, 60, 60))
pygame.draw.polygon(screen, color, ((x+60,y), (x+30,y-80), (x,y)))
pygame.draw.polygon(screen, color, ((x-20,y+52.5), (x+30,y+70), (x+80,y+52.5)))
color = (60,60,65)
pygame.draw.rect(screen, color, pygame.Rect((x-70), (y+20), 200, 30))
color = (40,40,45)
pygame.draw.rect(screen, color, pygame.Rect(x-70, y-20, 20, 40))
pygame.draw.rect(screen, color, pygame.Rect(x+110, y-20, 20, 40))
# Update the display using flip
pygame.display.flip()
# Variable to keep our game loop running
running = True
while running:
for event in pygame.event.get():
# Check for QUIT event
if event.type == pygame.QUIT:
running = False
if keyboard.is_pressed("a") or keyboard.is_pressed("w") or keyboard.is_pressed("left arrow"):
print("left")
screen.fill(background_colour)
x = (x + -3.75)
player()
time.sleep(0.005)
pygame.display.flip()
if keyboard.is_pressed("d") or keyboard.is_pressed("s") or keyboard.is_pressed("right arrow"):
print("right")
screen.fill(background_colour)
x = (x + 3.75)
player()
time.sleep(0.005)
pygame.display.flip()
if keyboard.is_pressed("space") or keyboard.is_pressed("f") or keyboard.is_pressed("e"):
color = (255,0,0)
pygame.draw.rect(screen, color, pygame.Rect(xb, yb, 60, 60))
while (yb > -40):
yb = yb + 5
time.sleep(0.5)
print("shot")
pygame.display.flip()
time.sleep(0.01)
`
please help me ive tried to almost everything to make it work but everytime i press space it crashes
i think this is because of the while loop?
In PyGame, the 0,0 co-ordinate is in the upper-left corner of the window. In your game the player is positioned at the bottom, so the projectile moves up the display, going from a large y-coordinate to a smaller one, and eventually negative once off-screen.
As #Chris Doyle points out in a comment, your code has a tight loop where yb is increased, but then is tested for being < -40. Since yb is already positive, this can never happen. So your program is locking up at this point, as the loop exiting condition can never be satisfied.
Looking at your code, there's a few tweaks necessary for the projectile logic.
First it's best to try to paint everything on the screen from one place, then you're not re-painting (or accidentally erasing) items on every loop.
I also moved the logic of the bullet movement out into the main loop. So pressing space only starts the bullet. The movement happens when the main loop "sees" a bullet on the screen (when firing is True).
Other tweaks: I don't have the keyboard module, so I ported this to standard PyGame keys. And I took the liberty of renaming the x,y and xb,yb to player_x, player_y and projectile_x, projectile_y. I hope that's OK.
# import the pygame module
import pygame
#import keyboard
import time
projectile_x = 30
projectile_y = 670
player_x = 30
player_y = 670
o = 0
# Define the background colour
# using RGB color coding.
background_colour = (10,10,10)
# Define the dimensions of
# screen object(width,height)
screen = pygame.display.set_mode((800, 750),pygame.RESIZABLE)
# Set the caption of the screen
pygame.display.set_caption('shoter')
# Fill the background colour to the screen
screen.fill(background_colour)
def player():
color = (40,40,45)
pygame.draw.rect(screen, color, pygame.Rect(player_x, player_y, 60, 60))
pygame.draw.polygon(screen, color, ((player_x+60,player_y), (player_x+30,player_y-80), (player_x,player_y)))
pygame.draw.polygon(screen, color, ((player_x-20,player_y+52.5), (player_x+30,player_y+70), (player_x+80,player_y+52.5)))
color = (60,60,65)
pygame.draw.rect(screen, color, pygame.Rect((player_x-70), (player_y+20), 200, 30))
color = (40,40,45)
pygame.draw.rect(screen, color, pygame.Rect(player_x-70, player_y-20, 20, 40))
pygame.draw.rect(screen, color, pygame.Rect(player_x+110, player_y-20, 20, 40))
# Update the display using flip
pygame.display.flip()
# Is a projectile on screen?
firing = False
# Variable to keep our game loop running
running = True
clock = pygame.time.Clock()
while running:
for event in pygame.event.get():
# Check for QUIT event
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
a_w_left = keys[pygame.K_LEFT] or keys[pygame.K_a] or keys[pygame.K_w]
d_s_right = keys[pygame.K_RIGHT] or keys[pygame.K_d] or keys[pygame.K_s]
e_f_space = keys[pygame.K_SPACE] or keys[pygame.K_e] or keys[pygame.K_f]
if a_w_left:
print("left")
player_x = (player_x + -3.75)
if d_s_right:
print("right")
player_x = (player_x + 3.75)
if e_f_space:
if ( not firing ):
firing = True
projectile_x = player_x
projectile_y = player_y - 10
print("shot")
# repaint the screen
screen.fill(background_colour)
player()
if ( firing ):
color = (255,0,0)
pygame.draw.rect(screen, color, pygame.Rect(projectile_x, projectile_y, 60, 60))
projectile_y = projectile_y - 5
if ( projectile_y < -60 ):
firing = False # bullet off screen
pygame.display.flip()
clock.tick( 60 ) # limit FPS
Also, it's not good practice to use time.sleep() to control movement (etc.) in a PyGame program, because it blocks everything up. It's better to use the real-time millisecond clock provided by pygame.time.get_ticks().

How can I limit the screen in pygame? [duplicate]

This question already has answers here:
Setting up an invisible boundary for my sprite
(1 answer)
Use vector2 in pygame. Collide with the window frame and restrict the ball to the rectangular area
(1 answer)
How to make ball bounce off wall with PyGame?
(1 answer)
Not letting the character move out of the window
(2 answers)
Closed 10 months ago.
I just started trying out pygame, so I watched a tutorial. When the guy showed, how to create edges left and right from the screen, it just didn't work when I did it, even though I've written it 100% equal as the tutorial guy. The tutorial is already two years old, so maybe pygame just has changed. Can somebody help me?
That's my code:
import pygame
import sys
pygame.init()
background = pygame.image.load("C:\Programmieren\Python\Grafiken\pygame test1 - background.png")
screen = pygame.display.set_mode([1200,595])
clock = pygame.time.Clock()
pygame.display.set_caption("pygame test1")
def draw():
screen.blit(background, (0, 0))
pygame.draw.rect(screen, (0, 0, 255), (x, y, width, height))
pygame.display.update()
x = 300
y = 300
speed = 3
width = 40
height = 80
left_wall = pygame.draw.rect(screen, (0,0,0), (-2,0,2,600), 0)
right_wall = pygame.draw.rect(screen, (0,0,0), (1201,0,2,600), 0)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
character = pygame.Rect(x,y,width, height)
pressed = pygame.key.get_pressed()
if presses[pygame.K_UP] or pressed[pygame.K_w] or pressed[pygame.K_SPACE]:
y -= speed
if pressed[pygame.K_RIGHT] or pressed[pygame.K_d] and not character.colliderect(right_wall):
x += speed
if pressed[pygame.K_DOWN] or pressed[pygame.K_s]:
y += speed
if pressed[pygame.K_LEFT] or pressed[pygame.K_a] and not character.colliderect(left_wall):
x -= speed
draw()
clock.tick(60)
The following code works for me after replacing the background.png path with a picture that exists on my computer. I changed left_wall and right_wall to call pygame.Rect instead of pygame.draw.rect and copied the draw.rect calls that were previously assigned to left_wall and right_wall to draw() function, and added some needed parentheses in two of the if statements. Also fixed a typo where pressed was spelled presses.
Without the parentheses, the character would always move right when right key is pressed even past the right edge of the window. When "d" is pressed, it would check against colliderect. Same for left arrow and "a" keys. or short-circuits, so if K_RIGHT or K_LEFT is pressed, it doesn't check the right hand side of the or in the if statements. With the parentheses added, the "move right" if statement always checks colliderect when K_RIGHT or K_d is pressed, instead of only when K_d is pressed.
import pygame
import sys
pygame.init()
background = pygame.image.load("C:\Programmieren\Python\Grafiken\pygame test1 - background.png")
screen = pygame.display.set_mode([1200,595])
clock = pygame.time.Clock()
pygame.display.set_caption("pygame test1")
def draw():
screen.blit(background, (0, 0))
pygame.draw.rect(screen, (0, 0, 255), (x, y, width, height))
pygame.draw.rect(screen, (0,0,0), left_wall, 0)
pygame.draw.rect(screen, (0,0,0), right_wall, 0)
pygame.display.update()
x = 300
y = 300
speed = 3
width = 40
height = 80
left_wall = pygame.Rect(-2,0,2,600)
right_wall = pygame.Rect(1201,0,2,600)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
character = pygame.Rect(x,y,width, height)
pressed = pygame.key.get_pressed()
if pressed[pygame.K_UP] or pressed[pygame.K_w] or pressed[pygame.K_SPACE]:
y -= speed
if (pressed[pygame.K_RIGHT] or pressed[pygame.K_d]) and not character.colliderect(right_wall):
x += speed
if pressed[pygame.K_DOWN] or pressed[pygame.K_s]:
y += speed
if (pressed[pygame.K_LEFT] or pressed[pygame.K_a]) and not character.colliderect(left_wall):
x -= speed
draw()
clock.tick(60)

Pygame player movement is being weird

I was making a pygame project and i made a square move and It would summon a square every frame and there would just be a line of squares.
I tried to update the screen every frame (Because i hadn't yet), but that did not work. Here is my code:
#Import Pygame
import pygame
#screen object(width, height)
screen_x = 750
screen_y = 600
screen = pygame.display.set_mode((screen_x, screen_y))
#Set the caption of the screen
pygame.display.set_caption('Game')
#Define a velocity, x, and y variable
velocity = 2.5x = 0.0y = 0.0
#Variable to keep our game loop running
running = True
#Game loop
while running:
# Initialing Color
color = (255,0,0)
if pygame.key.get_pressed()[pygame.K_w]:
y += 2.5
if pygame.key.get_pressed()[pygame.K_s]:
y -= 2.5
if pygame.key.get_pressed()[pygame.K_a]:
x -= 2.5
if pygame.key.get_pressed()[pygame.K_d]:
x += 2.5
# Drawing Rectangle
pygame.draw.rect(screen, color, pygame.Rect(x, y, 50, 50))
pygame.display.flip()
pygame.display.update()
# for loop through the event queue
for event in pygame.event.get():
# Check for QUIT event
if event.type == pygame.QUIT:
running = False
The entire scene is redrawn in every frame, therefore you have to clear the display in every frame:
import pygame
#screen object(width, height)
screen_x = 750
screen_y = 600
screen = pygame.display.set_mode((screen_x, screen_y))
#Set the caption of the screen
pygame.display.set_caption('Game')
#Define a velocity, x, and y variable
velocity = 2.5
x, y = 0, 0
color = (255,0,0)
clock = pygame.time.Clock()
running = True
while running:
clock.tick(100)
# for loop through the event queue
for event in pygame.event.get():
# Check for QUIT event
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
x += (keys[pygame.K_d] - keys[pygame.K_a]) * velocity
y += (keys[pygame.K_s] - keys[pygame.K_w]) * velocity
# clear display
screen.fill((0, 0, 0))
# Drawing Rectangle
pygame.draw.rect(screen, color, pygame.Rect(x, y, 50, 50))
# update display
pygame.display.flip()
pygame.quit()
exit()
The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
The solution is very simple. You forgot to fill the screen with a color. Because your code just draw's a square to the screen surface every frame, and that's why it's drawing a line of squares. You have to fill the screen before drawing the things, because otherwise you will see an empty screen with that color, that you filled the surface with. Hope it helped.

pygame movement speed is not constant [duplicate]

This question already has answers here:
Pygame clock and event loops
(1 answer)
Framerate affect the speed of the game
(1 answer)
Closed last year.
I recently started with pygame and im trying to create movement but when I move my rectangle the speed changes at various times. it becomes slower and faster at various times
import pygame
pygame.init() # inisializing pygame
WIN = pygame.display.set_mode((500, 500)) # the width and hieght of the window
pygame.display.set_caption('pygame tutorial') # give the window a title
x = 50
y = 50 # character x and y positions
width = 40
height = 60 # rectangle width and height
vel = 5 # velocity (speed)
run = True # boolean variable
while run: # forever loop
for event in pygame.event.get(): # specifing the event
if event.type == pygame.QUIT: # pygame.QUIT makes the red x work so you can close the window
run = False # run = false so the while loop stops
key = pygame.key.get_pressed()
if key [pygame.K_a]:
x -= vel
if key[pygame.K_d]:
x += vel
if key[pygame.K_w]:
y -= vel
if key[pygame.K_s]:
y += vel
WIN.fill((0,0,0))
pygame.draw.rect(WIN, (255, 0, 0), (x, y, width, height))
'''
create a rectangle with 3 arguements, the window, the rgb colour, and the x,y positions width and height
'''
pygame.display.update()
pygame.quit()
You have wrong indentations so some code is executed inside many times in for-loop but it should be executed only once after for-loop
After changing indentations code work too fast and I needed to add clock.tick(60) to reduce speed to max 60 frames per second. This way it should run with the same speed on computers with older and newer CPU.
WIN = pygame.display.set_mode((500, 500)) # the width and hieght of the window
pygame.display.set_caption('pygame tutorial') # give the window a title
x = 50
y = 50 # character x and y positions
width = 40
height = 60 # rectangle width and height
vel = 5 # velocity (speed)
run = True # boolean variable
clock = pygame.time.Clock()
while run: # forever loop
for event in pygame.event.get(): # specifying the event
if event.type == pygame.QUIT: # pygame.QUIT makes the red x work so you can close the window
run = False # run = false so the while loop stops
# --- after loop --
key = pygame.key.get_pressed()
if key [pygame.K_a]:
x -= vel
if key[pygame.K_d]:
x += vel
if key[pygame.K_w]:
y -= vel
if key[pygame.K_s]:
y += vel
WIN.fill((0,0,0))
pygame.draw.rect(WIN, (255, 0, 0), (x, y, width, height))
'''
create a rectangle with 3 arguments, the window, the rgb colour, and the x,y positions width and height
'''
pygame.display.update()
clock.tick(60) # reduce speed to max 60 frames per seconds
pygame.quit()

display issue with pygame in python3

This is the output of my code. I can't figure out how to fix this issue.
This code is showing weird lines in the window created using Pygame.
I was learning about using arrow keys in Pygame and con not get rid of this glich in the window.
The code that I made changes to is on geeks for geeks here : https://www.geeksforgeeks.org/python-drawing-design-using-arrow-keys-in-pygame/
This works just fine but when I use a different sized window and a different shape to draw it shows the weird lines in the window.
import pygame
import tkinter
pygame.init()
# create the display surfce object of specific dimensions (1000x1000).
win = pygame.display.set_mode((500, 500))
# Setting the window name
pygame.display.set_caption("Dungen World")
# Current coordinates
x = 250
y = 250
# dimensions of the player
width = 10
height = 10
# Speed of movement
vel = 2.5
# Indicator that pygame is running
running = True
# Main game loop
while running:
# Time delay(milliseconds)
pygame.time.delay(10)
# Iterate over the list of event objects
# that was returned by the pygame.event.get()
for event in pygame.event.get():
# if event object type is QUIT
# then quitting the pygame
# and program both
if event.type == pygame.QUIT:
# This will exit the while loop
running = False
# Stores the key pressed
keys = pygame.key.get_pressed()
# If left arrow key is pressed
if keys[pygame.K_LEFT] and x > 5:
# Decrement in x coordinates
x -= vel
# If left arrow key is pressed
if keys[pygame.K_RIGHT] and x < 500 - width:
# Decrement in x coordinates
x += vel
# If left arrow key is pressed
if keys[pygame.K_UP] and y > 5:
# Decrement in x coordinates
y -= vel
# If left arrow key is pressed
if keys[pygame.K_DOWN] and y < 500 - height:
# Decrement in x coordinates
y += vel
# drawing the square on screen
pygame.draw.circle(win, (255, 255, 255), (x, y), width/2)
# To refresh the window
pygame.display.update()
# Closes the pygame window
pygame.quit()
Add win.fill((0, 0, 0)) (or whatever background color you want) at the beginning of your game loop. For some reason, macOS freaks out if the background doesn't have a color.
Your code should look like this:
import pygame
import tkinter
pygame.init()
# create the display surfce object of specific dimensions (1000x1000).
win = pygame.display.set_mode((500, 500))
# Setting the window name
pygame.display.set_caption("Dungen World")
# Current coordinates
x = 250
y = 250
# dimensions of the player
width = 10
height = 10
# Speed of movement
vel = 2.5
# Indicator that pygame is running
running = True
# Main game loop
while running:
# Time delay(milliseconds)
pygame.time.delay(10)
# Fill entire window with black
win.fill((0, 0, 0))
# Iterate over the list of event objects
# that was returned by the pygame.event.get()
for event in pygame.event.get():
# if event object type is QUIT
# then quitting the pygame
# and program both
if event.type == pygame.QUIT:
# This will exit the while loop
running = False
# Stores the key pressed
keys = pygame.key.get_pressed()
# If left arrow key is pressed
if keys[pygame.K_LEFT] and x > 5:
# Decrement in x coordinates
x -= vel
# If left arrow key is pressed
if keys[pygame.K_RIGHT] and x < 500 - width:
# Decrement in x coordinates
x += vel
# If left arrow key is pressed
if keys[pygame.K_UP] and y > 5:
# Decrement in x coordinates
y -= vel
# If left arrow key is pressed
if keys[pygame.K_DOWN] and y < 500 - height:
# Decrement in x coordinates
y += vel
# drawing the square on screen
pygame.draw.circle(win, (255, 255, 255), (x, y), width/2)
# To refresh the window
pygame.display.update()
# Closes the pygame window
pygame.quit()
Edit:
Without this piece of code, the player doesn't actually "move" and acts more like a drawing app than a game.

Categories

Resources