Pygame player movement is being weird - python

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.

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().

Stop an object from glitching in pygame

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()

How can i give my image an initial position before it starts moving with the mouse?

I'm working on this pygame game and i'm just getting started but got a bit confused because i want the image to move in the x-axis along with the mouse but when i run the program i want the image to show up at the center or the 'floor' but appears at the left side instead. This is my code and a screenshot of what's happening.
import pygame
import sys
pygame.init()
pygame.mixer.init()
WIDTH, HEIGHT = 400, 500
FPS = 60
TITLE = 'FOOD DROP'
SIZE = 190
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE_SKY = (152, 166, 255)
# Display
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
# Surfaces
floor_surface = pygame.Surface((WIDTH, 100))
floor_surface.fill(BLUE_SKY)
floor_rect = floor_surface.get_rect(midbottom=(200, 500))
# Images
LOAD_DITTO = pygame.image.load('Graphics/ditto.png')
DITTO = pygame.transform.scale(LOAD_DITTO, (SIZE, SIZE))
# Time
CLOCK = pygame.time.Clock()
class Figure:
def draw_figure(self, mouse_x):
SCREEN.blit(DITTO, (mouse_x - 90, 330))
# Game loop
SCREEN_UPDATE = pygame.USEREVENT
# main_game = Main()
figure = Figure()
running = True
while running:
CLOCK.tick(FPS)
mx, my = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
SCREEN.fill(WHITE)
SCREEN.blit(floor_surface, floor_rect)
figure.draw_figure(mx)
pygame.display.update()
When i run the program, this happens:
And i want the image to appear right at the center or the x-axis, not the border, i don't know why is this happening. Just to state, that screenshot was taken when the mouse hadn't been placed over the display.
If the mouse pointer is not in the window (out of focus), the initial position of the mouse pointer is (0, 0). Therefore pygame.mouse.get_pos returns (0, 0). It is also not possible to set the mouse position with pygame.mouse.set_pos if it is not in the window.
Initialize the variables mx and mx with the center of the window. Change the mouse position only when the mouse pointer is in the window (in focus). pygame.mouse.get_focused can be used to test whether the mouse is in the window.
mx, my = SCREEN.get_rect().center
running = True
while running:
CLOCK.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if pygame.mouse.get_focused():
mx, my = pygame.mouse.get_pos()
SCREEN.fill(WHITE)
SCREEN.blit(floor_surface, floor_rect)
figure.draw_figure(mx)
pygame.display.update()
pygame.quit()
sys.exit()

How Do I Fix My Ball Animation In Pygame? [duplicate]

This question already has an answer here:
How can I move the ball instead of leaving a trail all over the screen in pygame?
(1 answer)
Closed 1 year ago.
So my ball animation for my multiplayer pong game is broken. Instead of moving and bouncing normally, the ball draws it self again after moving.
How do i fix the ball to not like clone itself after it moves 5 pixels? This is the animation code:
enter code here
import pygame
pygame.init()
#Creating the window
screen_width, screen_height = 1000, 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Pong")
#FPS
FPS = 60
clock = pygame.time.Clock()
#Game Variables
light_grey = (170,170,170)
#Paddles
paddle_1 = pygame.Rect(screen_width - 30, screen_height/2 - 70, 20,100)
paddle_2 = pygame.Rect(10, screen_height/2 - 70, 20, 100)
#Ball
ball = pygame.Rect(screen_width/2, screen_height/2, 30, 30)
ball_xVel = 5
ball_yVel = 5
def ball_animation():
global ball_xVel, ball_yVel
ball.x += ball_xVel
ball.y += ball_yVel
if ball.x > screen_width or ball.x < 0:
ball_xVel *= -1
if ball.y > screen_height or ball.y < 0:
ball_yVel *= -1
def draw():
pygame.draw.ellipse(screen, light_grey, ball)
pygame.draw.rect(screen, light_grey, paddle_1)
pygame.draw.rect(screen, light_grey, paddle_2)
def main():
#main game loop
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
draw()
ball_animation()
pygame.display.update()
clock.tick(FPS)
pygame.quit()
if __name__ == "__main__":
main()
You have to clear the display in every frame with pygame.Surface.fill:
screen.fill(0)
The typical PyGame application loop has to:
handle the events by 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 either pygame.display.update() or pygame.display.flip()
limit frames per second to limit CPU usage with pygame.time.Clock.tick
def main():
# main application loop
run = True
while run:
# event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# update and move objects
ball_animation()
# clear the display
screen.fill(0)
# draw the scene
draw()
# update the display
pygame.display.update()
# limit frames per second
clock.tick(FPS)
pygame.quit()
exit()

surface doesn't disappear at the next frame

I'm pretty new to Python and programming in general.
I'm trying to draw a square (200px by 200px) on the screen when the user clicks on the screen.
I tried to create a surface and a rect around the surface ( when the user clicks on the screen) and then using the rect, placed the surface on the screen using the blit method.
for the x and y of the rect I used mouse position.
So, this in my head should have changed the position of the square whenever a user clicks somewhere else on the screen but it rather creates a new square every time.
so I have a couple of questions:
If the way I'm implementing this is wrong, then how can I implement this feature?
Shouldn't the square change place as Pygame draws it every frame?
Thank you :)
pygame.init()
# --- Column --------------- #
col_num = 8
col_size = 120
# --- Screen --------------- #
screen = pygame.display.set_mode((col_num * col_size, col_num * col_size))
screen.fill((255, 255, 255))
draw_board()
# --- Clock ---------------- #
clock = pygame.time.Clock()
white_player = Player()
# --- test surface --------- #
surface = pygame.Surface((200, 200))
surface.fill((255, 255, 255))
# --- Main Loop ------------ #
check = False
while True:
white_player.draw_piece()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(), sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
check = True
a_rect = surface.get_rect(center=pygame.mouse.get_pos())
print('here!')
if check:
screen.blit(surface, a_rect)
pygame.display.update()
clock.tick(60)
Output:
Even trying with a simple surface and a screen it doesn't work.
It adds another surface to the screen with the new x.
import pygame as pg
import sys
pg.init()
screen = pg.display.set_mode((400, 400))
clock = pg.time.Clock()
surface = pg.Surface((200, 200))
surface.fill((255, 255, 255))
xpos = 50
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit(), sys.exit()
xpos += 1
screen.blit(surface, (xpos, 100))
pg.display.flip()
clock.tick(60)
Oh, I just realized I forgot to fill the screen before each frame. fixed

Categories

Resources