hello i am pretty new to programming with pygame and i have this code:
import sys, pygame
pygame.init()
screen = pygame.display.set_mode((800, 368))
background = pygame.image.load("background.png")
background.convert()
screen.blit(background, (0, 0))
speed = [1, 1]
width = 800
height = 368
ball = pygame.image.load("ball.bmp")
ballrect = ball.get_rect()
player1 = pygame.image.load("player1.png")
player1rect = player1.get_rect()
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
ballrect = ballrect.move(speed)
if ballrect.left < 0 or ballrect.right > width:
speed[0] = -speed[0]
if ballrect.top < 0 or ballrect.bottom > height:
speed[1] = -speed[1]
screen.blit(ball, ballrect)
screen.blit(player1, player1rect)
pygame.display.update()
but when i run it there comes too many balls it should only be one ball. and there comes more and more balls.
Fredrik Håård is right about re-drawing the background.
The screen
acts as an image, and when you call screen.blit()
you draw over part of that image. When the while 1:
loop repeats, your image already has one or more copies of the ball on it, and your current code simply draws another image of the ball onto screen
.
You can draw the background before you move the ball, thus avoiding adding a new variable to hold the previous ball position.
...
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.blit(background, ballrect, ballrect) #redraw background over old ball location
ballrect = ballrect.move(speed)
if ballrect.left < 0 or ballrect.right > width:
speed[0] = -speed[0]
if ballrect.top < 0 or ballrect.bottom > height:
speed[1] = -speed[1]
screen.blit(ball, ballrect)
screen.blit(player1, player1rect)
pygame.display.update()
Alternatively, you can reconstruct the entire screen
each time, by replacing screen.blit(background, ballrect, ballrect)
above with screen.blit(background, (0, 0))
, which ensures that the background is correct for each 'frame', but is significantly slower.
My preferred approach is to note that you can pass pygame.display.update()
a list of rectangles, which makes the call return much quicker. Make sure you do an initial, full screen, display update before entering the while loop:
...
pygame.display.update()
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
old_ballrect = ballrect
screen.blit(background, old_ballrect, old_ballrect) #redraw background over old ball location
ballrect = ballrect.move(speed)
if ballrect.left < 0 or ballrect.right > width:
speed[0] = -speed[0]
if ballrect.top < 0 or ballrect.bottom > height:
speed[1] = -speed[1]
screen.blit(ball, ballrect)
screen.blit(player1, player1rect)
pygame.display.update([old_ballrect, ballrect])