arcade icon indicating copy to clipboard operation
arcade copied to clipboard

The right way to implement a timer on screen

Open Drreeww opened this issue 3 years ago • 3 comments

Bug Report

I want to draw a timer on screen, normally it will count down per second, but it not give me the good result.

System Info

time: Wed Jul 13 10:54:19 2022 99 time: Wed Jul 13 10:54:19 2022 98 time: Wed Jul 13 10:54:19 2022 97 time: Wed Jul 13 10:54:19 2022 96 time: Wed Jul 13 10:54:19 2022 95 time: Wed Jul 13 10:54:19 2022 94 time: Wed Jul 13 10:54:19 2022 93 time: Wed Jul 13 10:54:19 2022 92 time: Wed Jul 13 10:54:20 2022 91 time: Wed Jul 13 10:54:20 2022 90 time: Wed Jul 13 10:54:20 2022 89 time: Wed Jul 13 10:54:20 2022 88 time: Wed Jul 13 10:54:20 2022 87 time: Wed Jul 13 10:54:20 2022 86 time: Wed Jul 13 10:54:20 2022 85 time: Wed Jul 13 10:54:20 2022 84 time: Wed Jul 13 10:54:20 2022 83 time: Wed Jul 13 10:54:20 2022 82 time: Wed Jul 13 10:54:20 2022 81 time: Wed Jul 13 10:54:20 2022 80 time: Wed Jul 13 10:54:20 2022 79 time: Wed Jul 13 10:54:20 2022 78 time: Wed Jul 13 10:54:20 2022 77 time: Wed Jul 13 10:54:20 2022 76 time: Wed Jul 13 10:54:20 2022 75 time: Wed Jul 13 10:54:20 2022 74 time: Wed Jul 13 10:54:20 2022 73 time: Wed Jul 13 10:54:20 2022 72 time: Wed Jul 13 10:54:20 2022 71 time: Wed Jul 13 10:54:20 2022 70 time: Wed Jul 13 10:54:20 2022 69 time: Wed Jul 13 10:54:20 2022 68 time: Wed Jul 13 10:54:20 2022 67 time: Wed Jul 13 10:54:20 2022 66 time: Wed Jul 13 10:54:20 2022 65 time: Wed Jul 13 10:54:20 2022 64 time: Wed Jul 13 10:54:20 2022 63 time: Wed Jul 13 10:54:20 2022 62 time: Wed Jul 13 10:54:20 2022 61 time: Wed Jul 13 10:54:20 2022 60 time: Wed Jul 13 10:54:20 2022 59 time: Wed Jul 13 10:54:20 2022 58 time: Wed Jul 13 10:54:20 2022 57 time: Wed Jul 13 10:54:20 2022 56 time: Wed Jul 13 10:54:20 2022 55 time: Wed Jul 13 10:54:20 2022 54 time: Wed Jul 13 10:54:20 2022 53 time: Wed Jul 13 10:54:20 2022 52 time: Wed Jul 13 10:54:20 2022 51 time: Wed Jul 13 10:54:20 2022 50 time: Wed Jul 13 10:54:20 2022 49 time: Wed Jul 13 10:54:20 2022 48 time: Wed Jul 13 10:54:20 2022 47 time: Wed Jul 13 10:54:20 2022 46 time: Wed Jul 13 10:54:20 2022 45 time: Wed Jul 13 10:54:20 2022 44 time: Wed Jul 13 10:54:20 2022 43 time: Wed Jul 13 10:54:20 2022 42 time: Wed Jul 13 10:54:20 2022 41 time: Wed Jul 13 10:54:20 2022 40 time: Wed Jul 13 10:54:20 2022 39 time: Wed Jul 13 10:54:20 2022 38 time: Wed Jul 13 10:54:20 2022 37 time: Wed Jul 13 10:54:20 2022 36 time: Wed Jul 13 10:54:20 2022 35 time: Wed Jul 13 10:54:20 2022 34 time: Wed Jul 13 10:54:20 2022 33 time: Wed Jul 13 10:54:21 2022 32 time: Wed Jul 13 10:54:21 2022 31 time: Wed Jul 13 10:54:21 2022 30 time: Wed Jul 13 10:54:21 2022 29 time: Wed Jul 13 10:54:21 2022 28 time: Wed Jul 13 10:54:21 2022 27 time: Wed Jul 13 10:54:21 2022 26 time: Wed Jul 13 10:54:21 2022 25 time: Wed Jul 13 10:54:21 2022 24 time: Wed Jul 13 10:54:21 2022 23 time: Wed Jul 13 10:54:21 2022 22 time: Wed Jul 13 10:54:21 2022 21 time: Wed Jul 13 10:54:21 2022 20 time: Wed Jul 13 10:54:21 2022 19 time: Wed Jul 13 10:54:21 2022 18 time: Wed Jul 13 10:54:21 2022 17 time: Wed Jul 13 10:54:21 2022 16 time: Wed Jul 13 10:54:21 2022 15 time: Wed Jul 13 10:54:21 2022 14 time: Wed Jul 13 10:54:21 2022 13 time: Wed Jul 13 10:54:21 2022 12 time: Wed Jul 13 10:54:21 2022 11 time: Wed Jul 13 10:54:21 2022 10 time: Wed Jul 13 10:54:21 2022 9 time: Wed Jul 13 10:54:21 2022 8 time: Wed Jul 13 10:54:21 2022 7 time: Wed Jul 13 10:54:21 2022 6 time: Wed Jul 13 10:54:21 2022 5 time: Wed Jul 13 10:54:21 2022 4 time: Wed Jul 13 10:54:21 2022 3 time: Wed Jul 13 10:54:21 2022 2 time: Wed Jul 13 10:54:21 2022 1 time: Wed Jul 13 10:54:21 2022 0 time: Wed Jul 13 10:54:21 2022 -1 time: Wed Jul 13 10:54:21 2022 -2 time: Wed Jul 13 10:54:21 2022 -3 time: Wed Jul 13 10:54:21 2022 -4 time: Wed Jul 13 10:54:21 2022 -5 time: Wed Jul 13 10:54:21 2022 -6 time: Wed Jul 13 10:54:21 2022 -7 time: Wed Jul 13 10:54:21 2022 -8

Actual behavior:

Expected behavior:

Steps to reproduce/example code:

import arcade
import time

def count_down(start):
    """ A count down timer"""
    while start > 0:
        yield start
        time.sleep(1)
        start -= 1

class TimerDemo(arcade.Window):
    def __init__(self):
        super().__init__(800, 600, 'TimerDemo')
        self.time_left = 100
        arcade.set_background_color(arcade.color.WHITE)

    def on_update(self, delta_time: float = 1.0):
        self.time_left -= 1
        print('time:', time.ctime(), self.time_left)

    def on_draw(self):
        self.clear()
        arcade.draw_text(f'Left {self.time_left} s', 10, 10, arcade.color.BLUE, 12)

def main():
    window = TimerDemo()
    arcade.run()

if __name__ == '__main__':
    main()

Drreeww avatar Jul 13 '22 03:07 Drreeww

Try using arcade.schedule. This will call a specified function at delta_time seconds. I fixed some few performance issues. You should use the arcade.Text instead of arcade.draw_text. This will increase the text drawing speed by more than 100 times. Setting the window background color as a property is much faster than setting it using the function. I also added a start and pause feature. Press W to pause and Q to resume.

import arcade

class TimerDemo(arcade.Window):
    def __init__(self):
        super().__init__(800, 600, 'TimerDemo')
        self.time_left = 100

        self.timer = arcade.Text("", 10, 10, arcade.color.BLUE, 12)
        
        arcade.schedule(self.countdown, 1) # Time unit in seconds

        self.scheduled = False

        self.background_color = arcade.color.WHITE

    def countdown(self, delta):
        if self.time_left > 0:
            self.time_left -= 1
        else:
            self.time_left = 0

    def on_draw(self):
        self.clear()
        self.timer.draw()

        self.timer.text = f'Left {self.time_left} s'
    
    def on_key_press(self, key: int, modifiers: int):
        if key == arcade.key.Q:
            if not self.scheduled:
                # Stop user from spamming S
                arcade.schedule(self.countdown, 1) # Time unit in seconds
                self.scheduled = True
        
        elif key == arcade.key.W:
            if self.scheduled:
                arcade.unschedule(self.countdown)
                self.scheduled = False
            

def main():
    window = TimerDemo()
    arcade.run()

if __name__ == '__main__':
    main()

eschan145 avatar Jul 13 '22 03:07 eschan145

Thanks a lot, @eschan145. I'm a newbie on arcade. Are there more arcade tutorial? I'm learning from the official tutorial, but I'm get confusing always, even search Google for examples.

Drreeww avatar Jul 13 '22 05:07 Drreeww

Example code for a timer is here: https://api.arcade.academy/en/latest/examples/timer.html

The delta-time in the on_update should be about 1/60th of a second. But not always. You have to account for the fact that it won't always be by exact seconds or intervals. Even if you use schedule.

pvcraven avatar Jul 13 '22 13:07 pvcraven