[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Newbie performance question



It runs fine for me. What sort of framerate are you getting (self.clock.get_fps())? If it really is significantly less than 60, my only suggestion would be to try running it in windowed mode instead of fullscreen and see if that makes any difference.

On Tue, Jul 17, 2018 at 2:53 PM Andreas Zielke <andreas.zielke@xxxxxxxxx> wrote:
Hi all,

I've dabbled with pygame and wrote a Pong-like game (code see below).

I've tried to follow the advice in the tips/tutorial section and also tried out the dirty-rect strategy described in 
https://www.pygame.org/docs/ref/sprite.html#comment_pygame_sprite_RenderUpdates

This did not seem to make any difference, so I reverted back to the original code.

The performance is still much less than I expecte - with a lot of stuttering on my (not so old) Windows PC, so I guess I must be making some silly mistake.

It would be very kind, if someone could give me a heads-up.

Cheers
Andreas

P.S. I'd be happy to supply additional information, if that would help.

-----------------------8< SNIP 8<-----------------------

import pygame
import random
import math


class MovingRectSprite(pygame.sprite.Sprite):
    def __init__(self, width, height, screen_width, screen_height, color, center_x=0, center_y=0):
        super().__init__()
        self.image = pygame.Surface((width, height)).convert()
        self.image.fill(color)
        self.rect = self.image.get_rect()
        self.rect.center = (center_x, center_y)
        self.screen_width = screen_width
        self.screen_height = screen_height
        self.x_speed = 0
        self.y_speed = 0

        
    def update(self):
        self.rect.x += self.x_speed
        self.rect.y += self.y_speed

        
        
class Paddle(MovingRectSprite):
    SPEED = 10
    
    def __init__(self, width, height, screen_width, screen_height, color, center_x, center_y):
        super().__init__(width, height, screen_width, screen_height, color, center_x, center_y)
        self.acceleration = 0
        self.go_up = False
        self.go_down = False
    
    
    def update(self):
        super().update()
        
        if self.rect.top < 0:
            self.rect.top = 0
            self.y_speed = 0            
        elif self.rect.bottom >= self.screen_height:
            self.rect.bottom = self.screen_height - 1
            self.y_speed = 0

            
    def key_down(self, is_up_key):
        if is_up_key:
            self.go_up = True
            self.y_speed = -self.SPEED
        else:
            self.go_down = True
            self.y_speed = self.SPEED

            
    def key_up(self, is_up_key):
        if is_up_key:
            self.go_up = False
            if self.go_down:
                self.y_speed = self.SPEED
            else:
                self.y_speed = 0
        else:
            self.go_down = False
            if self.go_up:
                self.y_speed = -self.SPEED
            else:
                self.y_speed = 0

    
            
class Pong(object):
    def __init__(self):
        pygame.init()
        self.fps = 60
        self.background = "" 0, 0)
        self.clock = pygame.time.Clock()
        self.running = False
        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN | pygame.DOUBLEBUF)

        self.sprites = pygame.sprite.Group()

        paddle_width = self.screen.get_width() / 50
        paddle_height = self.screen.get_height() / 10
        self.paddles = pygame.sprite.Group()
        
        self.paddle_left = Paddle(paddle_width, paddle_height, self.screen.get_width(), self.screen.get_height(), (192, 0, 0), paddle_width / 2, self.screen.get_height() / 2)
        self.sprites.add(self.paddle_left)
        self.paddles.add(self.paddle_left)
        
        self.paddle_right = Paddle(paddle_width, paddle_height, self.screen.get_width(), self.screen.get_height(), (0, 0, 192), self.screen.get_width() - paddle_width / 2, self.screen.get_height() / 2)
        self.sprites.add(self.paddle_right)
        self.paddles.add(self.paddle_right)
        
        self.ball = MovingRectSprite(self.screen.get_width() / 100, self.screen.get_width() / 100, self.screen.get_width(), self.screen.get_height(), (255, 255, 0), self.screen.get_width() / 2, self.screen.get_height() / 2)
        self.sprites.add(self.ball)
        
        self.score_left = 0
        self.score_right = 0

        self.init_ball()
                

    def init_ball(self):
        self.ball.rect.center = (self.screen.get_width() / 2, self.screen.get_height() / 2)
        self.ball.x_speed = random.choice([-1, 1]) * 5
        self.ball.y_speed = random.randint(-5, 5)
        
        
    def on_key_up(self, event):
        if event.key in [pygame.K_s, pygame.K_x]:
            self.paddle_left.key_up(event.key == pygame.K_s)
        elif event.key in[pygame.K_UP, pygame.K_DOWN]:
            self.paddle_right.key_up(event.key == pygame.K_UP)
        
        
    def on_key_down(self, event):
        if event.key in [pygame.K_s, pygame.K_x]:
            self.paddle_left.key_down(event.key == pygame.K_s)
        elif event.key in[pygame.K_UP, pygame.K_DOWN]:
            self.paddle_right.key_down(event.key == pygame.K_UP)
        elif event.key == pygame.K_ESCAPE:
            self.running = False
        
        
    def start(self):
        self.running = True
        while self.running:
            self.clock.tick(self.fps)
            self.handle_events()
            self.update()
            self.draw()
        pygame.quit()
        
            
    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
                break;
            elif event.type == pygame.KEYDOWN:
                self.on_key_down(event)
            elif event.type == pygame.KEYUP:
                self.on_key_up(event)

           
    def update(self):
        self.sprites.update()
        if self.ball.rect.right < 0:
            self.score_right += 1
            self.init_ball()
        elif self.ball.rect.left > self.screen.get_width():
            self.score_left += 1
            self.init_ball()
        elif self.ball.rect.top < 0 and self.ball.y_speed < 0:
            self.ball.y_speed *= -1;
        elif self.ball.rect.bottom > self.screen.get_height() and self.ball.y_speed > 0:
            self.ball.y_speed *= -1;

        paddles_hit = pygame.sprite.spritecollide(self.ball, self.paddles, False)
        if paddles_hit:
            paddle_hit = paddles_hit[0]
            if (paddle_hit == self.paddle_left and self.ball.x_speed < 0) or \
               (paddle_hit == self.paddle_right and self.ball.x_speed > 0):
                self.ball.x_speed *= -1.05
    
        if abs(self.ball.y_speed) < 2:
            self.ball.y_speed = math.copysign(2, self.ball.y_speed)


    def draw(self):
        self.screen.fill(self.background)
        self.sprites.draw(self.screen)
        pygame.display.flip()
        
                    
if __name__ == '__main__':
    pong = Pong()
    pong.start()