Reputation: 83
I've been working on a game lately in Pygame. It loads in two different backgrounds (for parallax scrolling in the future) and then ads in a sprite that can be controlled with arrow keys and can jump and move left and right. It all loads in fine when I run it until I try to control the sprite. It responds slowly and I have to keep re-pressing the arrow keys to make it move. The code I used to make the sprite move is the same that I've used before in another program that simply loaded in the background and the sprite and controlled the sprite's movement. For my new program, I just added screen resize and fullscreen options. That is when it became slow. What is slowing it down? Do I need to better optimize my code?
If this helps, I also noticed that when I rapidly hit another key along with my arrow keys it moves it at the right speed. It is like this updates it. Is some kind of updating possibly what needs to be done? Also, I've already used "Pygame.display.update()" in my if statement for sprite key control.
import pygame
from pygame.locals import *
pygame.init()
#two backgrounds
bg = pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/Llama game/Llama imaging/backgrounds concepts/Mountains/PPP_BG1.png')
fg = pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/Llama game/Llama imaging/backgrounds concepts/Mountains/PPP_fg1.png')
clock = pygame.time.Clock()
def Sresize():
#screen resize:
pygame.event.pump()
event=pygame.event.wait()
if event.type==QUIT:
pygame.quit()
elif event.type==VIDEORESIZE:
sprite.screen=pygame.display.set_mode(event.dict['size'],HWSURFACE|DOUBLEBUF|RESIZABLE)
sprite.screen.blit(pygame.transform.scale(bg,event.dict['size']),(0,0))
sprite.screen.blit(pygame.transform.scale(fg,event.dict['size']),(0,0))
pygame.display.update()
#PLAYER CLASS
class player(object):
def __init__(self,x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.velocity = 15
self.isJump = False
self.jumpCount = 7
self.right = False
self.left = False
self.walkCount = 0
self.screen = pygame.display.set_mode((1280, 800), HWSURFACE|DOUBLEBUF|RESIZABLE)
self.walkRight = [pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/Examples/sprite-Game/sprite characters main/R %s.png' % frame) for frame in range(1, 9)]
self.walkLeft = [pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/Examples/sprite-Game/sprite characters main/L %s.png' % frame) for frame in range(14, 21)]
self.char = pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/Examples/sprite-Game/sprite characters main/character 25.png')
def draw(self, screen):
if self.walkCount + 1 >= 8:
self.walkCount = 0
if self.left:
self.screen.blit(self.walkLeft[self.walkCount//1], (self.x, self.y))
self.walkCount += 1
elif self.right:
self.screen.blit(self.walkRight[self.walkCount//1], (self.x, self.y))
self.walkCount += 1
else:
self.screen.blit(self.char, (self.x, self.y))
sprite = player(4, 480, 16, 16)
def redrawGamescreen():
sprite.screen.blit(pygame.transform.scale(bg,(1280, 800)),(0,0))
sprite.screen.blit(pygame.transform.scale(fg,(1280, 800)),(0,0))
sprite.draw(sprite.screen)
pygame.display.update()
#mainloop:-----------------------------------------------------------------
run = True
while run:
keys = pygame.key.get_pressed()
Sresize()
clock.tick(20)
#left
if keys[pygame.K_LEFT] and sprite.x > sprite.velocity:
sprite.x -= sprite.velocity
sprite.left = True
sprite.right = False
#right
elif keys[pygame.K_RIGHT] and sprite.x < 1280 - sprite.width - sprite.velocity:
sprite.x += sprite.velocity
sprite.right = True
sprite.left = False
#otherwise, stand still
else:
sprite.right = False
sprite.left = False
sprite.walkCount = 0
#jumping
if not(sprite.isJump):
if keys[pygame.K_SPACE]:
sprite.isJump = True
sprite.right = False
sprite.left = False
else:
if sprite.jumpCount >= -7:
neg = 1
pygame.display.update()
if sprite.jumpCount < 0:
neg = -1
sprite.y -= (sprite.jumpCount ** 2) * 0.5 * neg
sprite.jumpCount -= 1
else:
sprite.isJump = False
sprite.jumpCount = 7
sprite.velocity = 15
redrawGamescreen()
pygame.quit()
Upvotes: 3
Views: 401
Reputation: 211277
The issue is the call to event=pygame.event.wait()
. Note pygame.event.wait()
waits for a single event from the queue. If the queue is empty this function will wait until one is created. That makes your game lag. The issue is compounded by the fact that pygame.event.pump()
is called right before.
pygame.event.pump() event=pygame.event.wait()
Use pygame.event.get()
instead:
events=pygame.event.get()
pygame.event.get()
gets removes all messages from the event queue and.
e.g.:
def HandleEvents():
events = pygame.event.get()
for event in events:
if event.type==QUIT:
pygame.quit()
elif event.type==VIDEORESIZE:
sprite.screen=pygame.display.set_mode(event.dict['size'],HWSURFACE|DOUBLEBUF|RESIZABLE)
sprite.screen.blit(pygame.transform.scale(bg,event.dict['size']),(0,0))
sprite.screen.blit(pygame.transform.scale(fg,event.dict['size']),(0,0))
pygame.display.update()
Note, for a good control flow, you have to implement on event loop in the application loop. The event loop has to process all the user inputs.
Upvotes: 3