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()
Related
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.
import pygame
import sys
pygame.init()
weight=550
height=400
screen = pygame.display.set_mode((weight,height))
image=pygame.image.load("Capture.jpg").convert()
ix= 70
iy = 80
speed =10
imageplace = screen.blit(image,(ix,iy))
pygame.display.update()
running=True
while running:
for event in pygame.event.get():
pygame.time.delay(10)
if event.type == pygame.QUIT:
running=False
keys=pygame.key.get_pressed()
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
pos_x = pos[0]
pos_y = pos[1]
if (keys[pygame.K_LEFT] or keys[pygame.K_a]) and ix > 0:
ix-=speed
if (keys[pygame.K_RIGHT] or keys[pygame.K_d]) and ix > 0:
ix+=speed
if (keys[pygame.K_UP] or keys[pygame.K_w]) and ix > 0:
iy-=speed
if (keys[pygame.K_DOWN] or keys[pygame.K_s]) and ix > 0:
iy+=speed
if imageplace.collidepoint(pos_x,pos_y):
print("You have clicked on button")
else:
print("Wrong Direction")
I tried to move an image with pygame but it didn't work. I am new at this. I couldn't find anything on internet and I didn't understand it.
See How can I make a sprite move when key is held down and you must redraw the scene in ever 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()
Example based on your code:
import pygame
pygame.init()
width, height = 550, 400
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
image = pygame.image.load("Capture.jpg").convert()
imageplace = image.get_rect(topleft = (70, 80))
speed = 5
running=True
while running:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running=False
if event.type == pygame.MOUSEBUTTONDOWN:
if imageplace.collidepoint(event.pos):
print("You have clicked on button")
else:
print("Wrong Direction")
keys = pygame.key.get_pressed()
if (keys[pygame.K_LEFT] or keys[pygame.K_a]) and imageplace.left > 0:
imageplace.x -= speed
if (keys[pygame.K_RIGHT] or keys[pygame.K_d]) and imageplace.right < width:
imageplace.x += speed
if (keys[pygame.K_UP] or keys[pygame.K_w]) and imageplace.top > 0:
imageplace.y -= speed
if (keys[pygame.K_DOWN] or keys[pygame.K_s]) and imageplace.bottom < height:
imageplace.y += speed
screen.fill((0, 0, 0))
screen.blit(image, imageplace)
pygame.display.update()
pygame.quit()
I am making a pong game and the ball object leaves a trail when it moves and I was wondering how to stop it from doing this any help would be greatly appreciated. Thank you in advance.
Here is my code:
import sys
import pygame
pygame.init()
clock = pygame.time.Clock()
# screen setup
screen_width = 1200
screen_height = 700
screen = pygame.display.set_mode((screen_width, screen_height))
background = pygame.image.load("spacebackground.png").convert_alpha()
pygame.mouse.set_visible(False)
pygame.display.set_caption('pong')
# set up player and opponent and ball rect
player = pygame.Rect(screen_width - 20,screen_height/2 - 70,10,140)
opponent = pygame.Rect(10,screen_height/2 - 70,10,140 )
ball = pygame.Rect(screen_width/2-15, screen_height/2 - 15,30, 30)
ball_speed_x = 7
ball_speed_y = 7
# defining clock and colour
red = (0,0,0)
clock = pygame.time.Clock()
while True:
pygame.display.update(ball)
pygame.display.flip()
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
ball.x += ball_speed_x
ball.y += ball_speed_y
# Drawing the rects
pygame.draw.rect(background, red, player)
pygame.draw.rect(background, red, opponent)
pygame.draw.ellipse(background, red, ball)
pygame.display.update(ball)
clock.tick(60)
Draw the objects on the screen instead of on the background:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
ball.x += ball_speed_x
ball.y += ball_speed_y
# draw background on the screen
screen.blit(background, (0, 0))
# draw objects on the screen
pygame.draw.rect(screen, red, player)
pygame.draw.rect(screen, red, opponent)
pygame.draw.ellipse(screen, red, ball)
# update the display
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
lately I've been trying to create a ping pong game with Pygame but I can't seem to figure out why? or how the ball started tracing when I made it a moving object in the game. how can I go about fixing this problem?
import pygame, sys
def ball_ani():
global speedx, speedy
ball.x += speedx
ball.y += speedy
if ball.top <= 0 or ball.bottom >= h:
speedy *= -1
if ball.left <= 0 or ball.right >= w:
speedx *= -1
if ball.colliderect(player) or ball.colliderect(player2):
speedx *= -1
pygame.init()
clock = pygame.time.Clock()
w, h = 1000, 500
pygame.display.set_caption('Fut Pong')
win = pygame.display.set_mode((w, h))
win.fill("black")
pygame.draw.line(win, "white", (w//2, 0), (w//2, h), 3)
ball = pygame.Rect(w//2 - 10, h//2 - 10, 20, 20)
player = pygame.Rect(w - 15, h//2 - 50, 10, 100)
player2 = pygame.Rect(5, h//2 - 50, 10, 100)
speedx, speedy = 7, 7
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
ball_ani()
pygame.draw.ellipse(win, "green", ball)
pygame.draw.rect(win, "white", player)
pygame.draw.rect(win, "white", player2)
pygame.display.flip()
clock.tick(60)
You must clear the display in ever frame:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = Fasle
ball_ani()
win.fill("black") # <--- this is missing
pygame.draw.ellipse(win, "green", ball)
pygame.draw.rect(win, "white", player)
pygame.draw.rect(win, "white", player2)
pygame.display.flip()
clock.tick(60)
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()
I have to move the rectangular object straight through the pygame window. I have tried some code with pygame. The code is
import pygame
from itertools import cycle
pygame.init()
screen = pygame.display.set_mode((300, 300))
s_r = screen.get_rect()
player = pygame.Rect((100, 100, 50, 50))
timer = pygame.time.Clock()
movement = "straight"
x = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
raise
if movement == 'straight':
x += 50
screen.fill(pygame.color.Color('Black'))
pygame.draw.rect(screen, pygame.color.Color('Grey'), player)
pygame.display.flip()
timer.tick(25)
Here the image didnt moves. What I need is that the image must be moved in a straight way.
x is adding, but that does not affect player, which actually affects the drawing of the rectangle.
import pygame
from itertools import cycle
pygame.init()
screen = pygame.display.set_mode((300, 300))
s_r = screen.get_rect()
timer = pygame.time.Clock()
movement = "straight"
x = 0
player = pygame.Rect((x, 100, 50, 50))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
raise
if movement == 'straight':
x += 10
player = pygame.Rect((x, 100, 50, 50))
if x >= 300:
x = 0
screen.fill(pygame.color.Color('Black'))
pygame.draw.rect(screen, pygame.color.Color('Grey'), player)
pygame.display.flip()
timer.tick(25)
You need to adjust the player rectangle each time you change x. From http://www.pygame.org/docs/ref/rect.html, you can see that the first two arguments are "left" and "top". So, if you want to the rectangle to move from left to right, you'll want something like this:
player = pygame.Rect((100 + x, 100, 50, 50))
pygame.draw.rect(screen, pygame.color.Color('Grey'), player)
import pygame
BLACK = pygame.color.Color('Black')
GREY = pygame.color.Color('Grey')
pygame.init()
screen = pygame.display.set_mode((300, 300))
screen_rect = screen.get_rect()
timer = pygame.time.Clock()
movement = "straight"
player = pygame.Rect(0, 100, 50, 50) # four aguments in place of tuple (,,,)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if movement == 'straight':
player.x += 10
if player.x >= 300: # check only when `player.x` was changed
player.x = 0
screen.fill(BLACK)
pygame.draw.rect(screen, GREY, player)
pygame.display.flip()
timer.tick(25)
BTW:
don't use raise to exit program.
use readable variable - not s_r but screen_rect
you don't need x - you have player.x
you can create rectangle only once
remove repeated empty lines when you add code to question