2

I am making a game in which u have to carry move objects from one place to another. I can move my character to the zone in which I need to put something. I want the player to wait in the zone for 5 secs before the object is placed there, however, if i do this you cannot move anymore if u decide u dont want to place the object in the zone as the whole script would be paused.


Is there a way to make one part of the script wait while the rest of it runs?

Glitchd
  • 361
  • 2
  • 12
  • have you considered creating a thread? – Jake P Jul 17 '19 at 19:14
  • @JakeP whats that? is that how u run things at same time? – Glitchd Jul 17 '19 at 19:21
  • Allows you to run code simultaneously. Information [here](https://stackoverflow.com/a/2906014/7690862). `thread.join()` (see link for code) would make the main thread wait until the started thread has completed to continue running. – Jake P Jul 17 '19 at 19:24
  • @JakeP ok could u answer wth a breif example of how to do it in this situation? – Glitchd Jul 17 '19 at 19:27
  • then ull get reputation – Glitchd Jul 17 '19 at 19:28
  • use `pygame.time.get_ticks` to get current time in every loop of mainloop. This way you check if you wait 5 seconds and it will not stop mainloop. – furas Jul 17 '19 at 19:31
  • pls can u provide a breif example as an answer @furas as it will help me understand – Glitchd Jul 17 '19 at 19:33
  • when you start waiting then you set variable `end = pygame.time.get_ticks() + 5000` (ms) and in next loops you check `if end > pygame.time.get_ticks():` – furas Jul 17 '19 at 19:33
  • go on my GitHub [python-examples/pygame](https://github.com/furas/python-examples/tree/master/pygame) and see "clock", "time-control-object", "time-draw-item", "time-execute-function" – furas Jul 17 '19 at 19:36

2 Answers2

3

Every game needs one clock to keep the game loop in sync and to control timing. Pygame has a pygame.time.Clock object with a tick() method. Here's what a game loop could look like to get the behaviour you want (not complete code, just an example).

clock = pygame.time.Clock()

wait_time = 0
have_visited_zone = False
waiting_for_block_placement = False

# Game loop.
while True:

    # Get the time (in milliseconds) since last loop (and lock framerate at 60 FPS).
    dt = clock.tick(60)

    # Move the player.
    player.position += player.velocity * dt

    # Player enters the zone for the first time.
    if player.rect.colliderect(zone.rect) and not have_visited_zone:
        have_visited_zone = True            # Remember to set this to True!
        waiting_for_block_placement = True  # We're now waiting.
        wait_time = 5000                    # We'll wait 5000 milliseconds.

    # Check if we're currently waiting for the block-placing action.
    if waiting_for_block_placement:
        wait_time -= dt                          # Decrease the time if we're waiting.
        if wait_time <= 0:                       # If the time has gone to 0 (or past 0)
            waiting_for_block_placement = False  # stop waiting
            place_block()                        # and place the block.
Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50
1

Example with threading:

from threading import Thread

def threaded_function(arg):
    # check if it's been 5 seconds or user has left

thread = Thread(target = threaded_function, args = (10, ))
if user is in zone:
    thread.start()
# continue normal code

Another potential solution is to check the time the user went into the zone and continuously check the current time to see if it's been 5 seconds

Time check example:

import time

entered = false
while true:
    if user has entered zone:
        entered_time = time.time()
        entered = true
    if entered and time.time() - entered_time >= 5: # i believe time.time() is in seconds not milliseconds
        # it has been 5 seconds
    if user has left:
        entered=false
    #other game code
Jake P
  • 480
  • 3
  • 19
  • When i was trying to think of a logical solution i was thinking of something like the 2nd one but didnt know how to do it XD ty for the help – Glitchd Jul 17 '19 at 19:38
  • 1
    pygame has [pygame.time.get_ticks](https://www.pygame.org/docs/ref/time.html#pygame.time.get_ticks) which you could use instead `time` – furas Jul 17 '19 at 19:39
  • 1
    @furas yes that would work the same by just changing the `5` to `5000` to convert to millisecond – Jake P Jul 17 '19 at 19:41
  • @JakeP in ur thread example it says check if its been 5 secs. would i be able to use pygame.wait(5) and then drop the object? – Glitchd Jul 17 '19 at 19:47
  • 1
    If believe so, if you use `sleep(5)` in the threaded function it will not affect the main thread, i'm not sure how `pygame.wait(5)` behaves – Jake P Jul 17 '19 at 19:53
  • with sleep 5 how will i stop the sleep if i leave the zone? – Glitchd Jul 17 '19 at 19:55
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/196594/discussion-between-glitchd-and-jake-p). – Glitchd Jul 17 '19 at 19:57
  • @Glitchd I would strongly suggest not using threads for this. Although it might work, you'll introduce a ton of complexity. You have to think about synchronisation, data races, and all other nasty stuff. Also, due to Python's GIL, it'll probably be slower than a sequential solution. – Ted Klein Bergman Jul 18 '19 at 01:45
  • @Glitchd Also, there is some functionality that doesn't work with threads, or give unexpected behaviour. For example, the event system can only be called in the same thread that initialized the video mode. So it's likely you'll encounter weird bugs due to some underlying restriction. These bugs are extremely hard to locate unless you know about these restrictions. – Ted Klein Bergman Jul 18 '19 at 02:09
  • @Glitchd [Here's](https://stackoverflow.com/questions/54470051/multithreading-with-pygame-program-crashing/54470842#54470842) a problem someone had regarding multithreading in pygame just some months ago. In that case I suggested using the event system for timing, which could work in your case as well. [Here's](https://stackoverflow.com/questions/50232714/how-do-you-delay-specific-events-in-a-while-loop/50237012#50237012) an example on how to use the event system to start animations. – Ted Klein Bergman Jul 18 '19 at 02:18