I have been trying to make a basic Pygame code where the ball bounces around the screen and off your paddle. The paddle movement is smooth, but the ball flickers and is pretty choppy. Here is my complete code:
import pygame, sys
from pygame.locals import *
import random, time
pygame.init()
window = (800, 600)
background = (0, 0, 0)
back = pygame.Surface(window)
entity_color = (255, 255, 255)
x = 362.5
y = 550
ball_x = 387.5
ball_y = 50
width = 75
height = 25
clockobject = pygame.time.Clock()
screen = pygame.display.set_mode((window))
pygame.display.set_caption("Test Game")
class Ball(pygame.sprite.Sprite):
def __init__(self):
super(Ball, self).__init__()
self.surf = pygame.Surface((25, 25))
self.surf.fill((255, 255, 255))
self.rect = self.surf.get_rect()
self.dir_x = 1
self.dir_y = 1
self.speed = 2
def update(self):
global ball_x
global ball_y
if ball_x > 775:
ball_x = 775
ball.dir_x = -1
elif ball_x < 0:
ball_x = 0
ball.dir_x = 1
if ball_y < 0:
ball_y = 0
ball.dir_y = 1
elif ball_y > 600:
ball_y = 50
ball_x = 387.5
if ball_x <= x 75 and ball_x >= x and ball_y <= y and ball_y >= y - 25:
ball.dir_y = -1
ball_x = ball_x ball.speed * ball.dir_x
ball_y = ball_y ball.speed * ball.dir_y
class Player(pygame.sprite.Sprite):
def __init__(self):
super(Player, self).__init__()
self.image_s = pygame.image.load("paddle.png")
self.image_b = self.image_s.get_rect()
self.surf = pygame.Surface((75, 25))
self.surf.fill((255, 255, 255))
self.rect = self.surf.get_rect()
def update(self):
global x
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x = x - 5
elif keys[pygame.K_RIGHT]:
x = x 5
def checkboundaries(self):
global x
if x > 725:
x = 725
if x < 0:
x = 0
ball = Ball()
player = Player()
waiting = True
while waiting:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
elif event.key == pygame.K_SPACE:
running = True
waiting = False
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
player.update()
ball.update()
player.checkboundaries()
screen.blit(back, (0,0))
screen.blit(player.surf, (x, y))
screen.blit(ball.surf, (ball_x, ball_y))
pygame.display.flip()
clockobject.tick(360)
pygame.quit()
sys.exit()
Is this because of something wrong in my code that is running slowly, or am I missing something?
CodePudding user response:
If you are using pygame.sprite.Sprite
, you should also use pygame.sprite.Group
.
pygame.sprite.Group.draw()
and pygame.sprite.Group.update()
are methods which are provided by pygame.sprite.Group
.
The latter delegates to the update
method of the contained pygame.sprite.Sprite
s — you have to implement the method. See pygame.sprite.Group.update()
:
Calls the
update()
method on all Sprites in the Group. [...]
The former uses the image
and rect
attributes of the contained pygame.sprite.Sprite
s to draw the objects — you have to ensure that the pygame.sprite.Sprite
s have the required attributes. See pygame.sprite.Group.draw()
:
Draws the contained Sprites to the Surface argument. This uses the
Sprite.image
attribute for the source surface, andSprite.rect
. [...]
e.g.:
import pygame, sys
from pygame.locals import *
pygame.init()
clockobject = pygame.time.Clock()
screen = pygame.display.set_mode((800, 600))
back = pygame.Surface(screen.get_size())
pygame.display.set_caption("Test Game")
class Ball(pygame.sprite.Sprite):
def __init__(self):
super(Ball, self).__init__()
self.image = pygame.Surface((25, 25))
self.image.fill((255, 255, 255))
self.rect = self.image.get_rect(topleft = (387, 50))
self.dir_x = 1
self.dir_y = 1
self.speed = 2
def update(self):
if self.rect.x > 775:
self.rect.x = 775
self.dir_x = -1
elif self.rect.x < 0:
self.rect.x = 0
self.dir_x = 1
if self.rect.y < 0:
self.rect.y = 0
self.dir_y = 1
elif self.rect.y > 600:
self.rect.topleft = (387, 50)
if self.rect.colliderect(player.rect):
ball.dir_y = -1
self.rect.x = ball.speed * ball.dir_x
self.rect.y = ball.speed * ball.dir_y
class Player(pygame.sprite.Sprite):
def __init__(self):
super(Player, self).__init__()
self.image = pygame.Surface((75, 25))
self.image.fill((255, 255, 255))
self.rect = self.image.get_rect(topleft = (363, 550))
def update(self):
keys = pygame.key.get_pressed()
self.rect.x = (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * 5
self.rect.clamp_ip(screen.get_rect())
ball = Ball()
player = Player()
all_sprites = pygame.sprite.Group([ball, player])
started = False
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_SPACE:
started = True
screen.blit(back, (0,0))
if started:
all_sprites.update()
all_sprites.draw(screen)
pygame.display.flip()
clockobject.tick(100)
pygame.quit()
sys.exit()