2

So I am trying to make a game, in this game I call upon a function that I want to slowly execute, but when I use "time.sleep(x)" it pauses everything in the file instead of just pausing the process of the function. I am trying to add a jump feature to a 2-d game, so if there is a better way to do it then I would be grateful for any advice but this is just the first idea that game to me.

for n in range(15):
    Dino.rect.bottom -= 5
    update_screen(Dino, screen, cactus)
    time.sleep(0.01)
time.sleep(0.25)
inair = False
for n in range(15):
    Dino.rect.bottom += 5
    update_screen(Dino, screen, cactus)
    time.sleep(0.01)

so I have it so that when I jump, it gives me a slow jump instead of just teleporting but like I said, it pauses everything while jumping.

banana
  • 31
  • 4

1 Answers1

5

This is not a good approach to timing. As you say, this sleeps the entire program. Multi-threading is a bit complex for simply moving a sprite.

A simple way to solve this problem is to use the PyGame function time.get_ticks() which returns an ever-increasing time in milliseconds.

Using this time-stamp, record the previous-time of an operation, but then do not update again until enough time has elapsed.

For example:

DINO_UPDATE_DELAY = 100   # milliseconds

next_dino_update = 0     # time next move due

[...]

# Move dino, if necessary
time_now = pygame.time.get_ticks()
if ( time_now > next_dino_update ):
    Dino.rect.bottom += 5
    next_dino_update = time_now + DINO_UPDATE_DELAY   # in the future

# Paint the dino, wherever it is
update_screen(Dino, screen, cactus)

It's also possible to request a timer to send the event-loop a message in the future.

MOVE_DINO_EVENT = pygame.USEREVENT + 1

[...]

pygame.time.set_timer( MOVE_DINO_EVENT, DINO_UPDATE_DELAY )

EDIT: More in-depth explanation.

So basically you're implementing an animation, like an anime/cartoon. The thing on the display moves at some speed. In the above code, you seem to be moving a "dino" in the direction of y + 5 every 0.01 seconds (10 milliseconds).

Right now, you paint the dino, then sleep(), then move & paint again. When it hits the apogee of the jump, you wait 250 milliseconds, then repeat the previous phase for the down-jump.

So the problem with using sleep() is that it holds up the whole program (including the event loop, which can cause bad stuff to happen).

So instead of sleeping for some time period, the above example simply looks at the PyGame clock to determine if that same time-period has past. This allows the program to know if the animation needs to be updated.

The whole idea is to keep looking at the clock, using the time as the arbiter of what/where to draw next, rather than multiple calls to sleep().

Kingsley
  • 14,398
  • 5
  • 31
  • 53
  • It's better for his game, but didn't actually answer his questions... I think at least you should give a multi-threading version. – Yang HG Jun 03 '20 at 03:26
  • 1
    @YangHG - I did not give a multi-threaded version because I do not believe it is an appropriate answer for this question. Sometimes you answer what the OP *needs*, not what the OP *wants*. – Kingsley Jun 03 '20 at 03:31
  • @banana Ummm.... Just imagine, you write a dead loop, check system time per repeat. If the time longer than your preset, you will call `update_screen` function. If you only have `update_screen` function, nothing different. But if you have other functions, you could call them at other time point. Now, you have a simple `EventLoop`. pygame provides a more complex `EventLoop` for you, so you can use it by some helper functions. – Yang HG Jun 03 '20 at 03:39
  • @YangHG OMG I think I see what you are saying, thank you sooo much for your help!!! – banana Jun 03 '20 at 04:06