Sign in to follow this  

sprite walking [pygame]

This topic is 4105 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Well, after fooling around in pygame tonight, I have a sprite that uses a combination of three images to 'walk' across the screen. Only problem is that it appears to happen so fast, that you can't really see the walking 'animation'. My code is a little primitive, but I won't focus on that now. . .
import pygame, sys,os
from pygame.locals import *
pygame.init()
window = pygame.display.set_mode((1024,768), FULLSCREEN)
screen = pygame.display.get_surface()
the_sprite_file = os.path.join("pics", "guy.bmp")
the_sprite_file_walk_one = os.path.join("pics", "walkone.bmp")
the_sprite_file_walk_two = os.path.join("pics", "walktwo.bmp")
sprite_surface = pygame.image.load(the_sprite_file)
sprite_surface_walkone = pygame.image.load(the_sprite_file_walk_one)
sprite_surface_walktwo = pygame.image.load(the_sprite_file_walk_two)
screen.blit(sprite_surface, (50,100))
pygame.display.flip()
x = 50
game_loop = True
while game_loop:
    for event in pygame.event.get():
         walking = 1
         if event.type == KEYDOWN and event.key == 27:
             game_loop = False
         elif event.type == QUIT:
             game_loop = False
         if event.type == KEYDOWN and event.key == 100 and walking == 1:
             x = x + 2
             white = 255, 255, 255
             screen.fill(white)
             screen.blit(sprite_surface_walkone, (x, 100))
             pygame.display.flip()
             walking = 2
         if event.type == KEYDOWN and event.key == 100 and walking == 2:
             x = x + 2
             white = 255, 255, 255
             screen.fill(white)
             screen.blit(sprite_surface, (x, 100))
             pygame.display.flip()
             walking = 3
         if event.type == KEYDOWN and event.key == 100 and walking == 3:
             x = x + 2
             white = 255, 255, 255
             screen.fill(white)
             screen.blit(sprite_surface_walktwo, (x, 100))
             pygame.display.flip()
             walking = 1

pygame.quit()
Anyway to slow this process down?

Share this post


Link to post
Share on other sites
Having never worked with pygame before, but with some good experience with graphics, I can tell you that your problem is the absence of a screen delay.

In one frame, you have the character make three different animations. You need to have several frames where the character keeps the same animation before moving to the next one in order to avoid schizophrenia sprites.

And, as a side note, use comments. Some text after a pound sign can really help people read your code so, so much. And it'll help you remember how you did this a month from now. Comments also help you work out logic like
# This block of code creates a frame delay for the animation. 

will help you remember the importance of a frame delay to begin with.

Share this post


Link to post
Share on other sites
Quote:
Original post by Splinter of Chaos
Having never worked with pygame before, but with some good experience with graphics, I can tell you that your problem is the absence of a screen delay.

In one frame, you have the character make three different animations. You need to have several frames where the character keeps the same animation before moving to the next one in order to avoid schizophrenia sprites.

And, as a side note, use comments. Some text after a pound sign can really help people read your code so, so much. And it'll help you remember how you did this a month from now. Comments also help you work out logic like *** Source Snippet Removed *** will help you remember the importance of a frame delay to begin with.


Thanks, I would use comments, but this app is so badly programmed that I don't feel like bothering. [grin] I'm currently using pygame.time.delay, but looking for a more efficient method that won't stop the entire app to delay.

I have an unrelated question, what's the best way to make an intro movie still using sprites?

Share this post


Link to post
Share on other sites
Quote:

Thanks, I would use comments, but this app is so badly programmed that I don't feel like bothering


I'd say that's your primary problem. Of course it's difficult to find solutions, since the program is just horrible. Why different individual variables to hold animation frames? That's what lists are for:


sprite_files=[os.path.join("pics","walkone.bmp",
os.path.join("pics","guy.bmp",
os.path.join("picks","walktwo.bmp"]
sprites=[]
for sprite_file in sprite_files:
sprites.append(pygame.image.load(sprite_file))




Note: you can subsitute the last 3 lines with a list comprehension. I didn't mention it because I don't know if you're familiar with them. Anyway, it goes like this:

sprite=[pygame.image.load(sprite_file) for sprite_file in sprite_files]

Now you have a list that contains 3 images that you can index with sprites[walking]. If you want to slow the animation, you just increase "walking" in smaller steps each frame, for instance walking=(walking+0.1)%3. The "%" is the modulus operator so walking takes only values ranging [0,3). Of course, lists are indexed with ints and walking needs to be rounded down, so in order to get the current frame you just do sprites[int(walking)]

Share this post


Link to post
Share on other sites
Didn't we discuss this - at length - last night?


import pygame, sys,os
from pygame.locals import *

pygame.init()
window = pygame.display.set_mode((1024,768), FULLSCREEN)
screen = pygame.display.get_surface()
sprite_names = [os.path.join("pics", s) for s in ["guy.bmp", "walkone.bmp", "walktwo.bmp"]]
sprites = [pygame.image.load(s) for s in sprite_names]

tLastUpdate = 0
fr = 0 # frame counter
running = True
while running:
tNow = pygame.time.get_ticks()
if tNow - tLastUpdate > DESIRED_FRAME_TIME:
tLastUpdate = tNow
fr = (fr + 1) % 3
screen.blit(sprites[fr])

for evt in pygame.event.get():
if evt.type == QUIT:
running = False

pygame.quit()



The above source does not handle input. It merely renders your sprites at the desired frame rate (DESIRED_FRAME_TIME == 1 / (desired frame rate)) until you quit the application.

You could use pygame.time.delay, but that delays the entire program - events would back up just because you wanted to sync your rendering, for instance. Not pretty.

You could use Clock.tock_busy_loop, but that's CPU intensive, though how intensive exactly is an open question, and it might be sufficient for your needs. In any case, the above works fine. Remember to replace DESIRED_FRAME_TIME by an appropriate value/variable.

Share this post


Link to post
Share on other sites
Olu, I made this post before we talked last night. :)
The fr part makes so no sense to me though, wont it return the remainder of 1/3 the first time?

[Edited by - kevtimc on September 17, 2006 2:11:28 PM]

Share this post


Link to post
Share on other sites

This topic is 4105 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this