bascenev1lib.actor.onscreentimer

Defines Actor(s).

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Defines Actor(s)."""
  4from __future__ import annotations
  5
  6from typing import TYPE_CHECKING, override
  7import logging
  8
  9import bascenev1 as bs
 10
 11if TYPE_CHECKING:
 12    from typing import Any
 13
 14
 15class OnScreenTimer(bs.Actor):
 16    """A handy on-screen timer.
 17
 18    category: Gameplay Classes
 19
 20    Useful for time-based games where time increases.
 21    """
 22
 23    def __init__(self) -> None:
 24        super().__init__()
 25        self._starttime_ms: int | None = None
 26        self.node = bs.newnode(
 27            'text',
 28            attrs={
 29                'v_attach': 'top',
 30                'h_attach': 'center',
 31                'h_align': 'center',
 32                'color': (1, 1, 0.5, 1),
 33                'flatness': 0.5,
 34                'shadow': 0.5,
 35                'position': (0, -70),
 36                'scale': 1.4,
 37                'text': '',
 38            },
 39        )
 40        self.inputnode = bs.newnode(
 41            'timedisplay', attrs={'timemin': 0, 'showsubseconds': True}
 42        )
 43        self.inputnode.connectattr('output', self.node, 'text')
 44
 45    def start(self) -> None:
 46        """Start the timer."""
 47        tval = int(bs.time() * 1000.0)
 48        assert isinstance(tval, int)
 49        self._starttime_ms = tval
 50        self.inputnode.time1 = self._starttime_ms
 51        bs.getactivity().globalsnode.connectattr(
 52            'time', self.inputnode, 'time2'
 53        )
 54
 55    def has_started(self) -> bool:
 56        """Return whether this timer has started yet."""
 57        return self._starttime_ms is not None
 58
 59    def stop(self, endtime: int | float | None = None) -> None:
 60        """End the timer.
 61
 62        If 'endtime' is not None, it is used when calculating
 63        the final display time; otherwise the current time is used.
 64        """
 65        if endtime is None:
 66            endtime = bs.time()
 67
 68        if self._starttime_ms is None:
 69            logging.warning(
 70                'OnScreenTimer.stop() called without first calling start()'
 71            )
 72        else:
 73            endtime_ms = int(endtime * 1000)
 74            self.inputnode.timemax = endtime_ms - self._starttime_ms
 75
 76    def getstarttime(self) -> float:
 77        """Return the scene-time when start() was called.
 78
 79        Time will be returned in seconds if timeformat is SECONDS or
 80        milliseconds if it is MILLISECONDS.
 81        """
 82        val_ms: Any
 83        if self._starttime_ms is None:
 84            print('WARNING: getstarttime() called on un-started timer')
 85            val_ms = int(bs.time() * 1000.0)
 86        else:
 87            val_ms = self._starttime_ms
 88        assert isinstance(val_ms, int)
 89        return 0.001 * val_ms
 90
 91    @property
 92    def starttime(self) -> float:
 93        """Shortcut for start time in seconds."""
 94        return self.getstarttime()
 95
 96    @override
 97    def handlemessage(self, msg: Any) -> Any:
 98        # if we're asked to die, just kill our node/timer
 99        if isinstance(msg, bs.DieMessage):
100            if self.node:
101                self.node.delete()
class OnScreenTimer(bascenev1._actor.Actor):
 16class OnScreenTimer(bs.Actor):
 17    """A handy on-screen timer.
 18
 19    category: Gameplay Classes
 20
 21    Useful for time-based games where time increases.
 22    """
 23
 24    def __init__(self) -> None:
 25        super().__init__()
 26        self._starttime_ms: int | None = None
 27        self.node = bs.newnode(
 28            'text',
 29            attrs={
 30                'v_attach': 'top',
 31                'h_attach': 'center',
 32                'h_align': 'center',
 33                'color': (1, 1, 0.5, 1),
 34                'flatness': 0.5,
 35                'shadow': 0.5,
 36                'position': (0, -70),
 37                'scale': 1.4,
 38                'text': '',
 39            },
 40        )
 41        self.inputnode = bs.newnode(
 42            'timedisplay', attrs={'timemin': 0, 'showsubseconds': True}
 43        )
 44        self.inputnode.connectattr('output', self.node, 'text')
 45
 46    def start(self) -> None:
 47        """Start the timer."""
 48        tval = int(bs.time() * 1000.0)
 49        assert isinstance(tval, int)
 50        self._starttime_ms = tval
 51        self.inputnode.time1 = self._starttime_ms
 52        bs.getactivity().globalsnode.connectattr(
 53            'time', self.inputnode, 'time2'
 54        )
 55
 56    def has_started(self) -> bool:
 57        """Return whether this timer has started yet."""
 58        return self._starttime_ms is not None
 59
 60    def stop(self, endtime: int | float | None = None) -> None:
 61        """End the timer.
 62
 63        If 'endtime' is not None, it is used when calculating
 64        the final display time; otherwise the current time is used.
 65        """
 66        if endtime is None:
 67            endtime = bs.time()
 68
 69        if self._starttime_ms is None:
 70            logging.warning(
 71                'OnScreenTimer.stop() called without first calling start()'
 72            )
 73        else:
 74            endtime_ms = int(endtime * 1000)
 75            self.inputnode.timemax = endtime_ms - self._starttime_ms
 76
 77    def getstarttime(self) -> float:
 78        """Return the scene-time when start() was called.
 79
 80        Time will be returned in seconds if timeformat is SECONDS or
 81        milliseconds if it is MILLISECONDS.
 82        """
 83        val_ms: Any
 84        if self._starttime_ms is None:
 85            print('WARNING: getstarttime() called on un-started timer')
 86            val_ms = int(bs.time() * 1000.0)
 87        else:
 88            val_ms = self._starttime_ms
 89        assert isinstance(val_ms, int)
 90        return 0.001 * val_ms
 91
 92    @property
 93    def starttime(self) -> float:
 94        """Shortcut for start time in seconds."""
 95        return self.getstarttime()
 96
 97    @override
 98    def handlemessage(self, msg: Any) -> Any:
 99        # if we're asked to die, just kill our node/timer
100        if isinstance(msg, bs.DieMessage):
101            if self.node:
102                self.node.delete()

A handy on-screen timer.

category: Gameplay Classes

Useful for time-based games where time increases.

OnScreenTimer()
24    def __init__(self) -> None:
25        super().__init__()
26        self._starttime_ms: int | None = None
27        self.node = bs.newnode(
28            'text',
29            attrs={
30                'v_attach': 'top',
31                'h_attach': 'center',
32                'h_align': 'center',
33                'color': (1, 1, 0.5, 1),
34                'flatness': 0.5,
35                'shadow': 0.5,
36                'position': (0, -70),
37                'scale': 1.4,
38                'text': '',
39            },
40        )
41        self.inputnode = bs.newnode(
42            'timedisplay', attrs={'timemin': 0, 'showsubseconds': True}
43        )
44        self.inputnode.connectattr('output', self.node, 'text')

Instantiates an Actor in the current bascenev1.Activity.

node
inputnode
def start(self) -> None:
46    def start(self) -> None:
47        """Start the timer."""
48        tval = int(bs.time() * 1000.0)
49        assert isinstance(tval, int)
50        self._starttime_ms = tval
51        self.inputnode.time1 = self._starttime_ms
52        bs.getactivity().globalsnode.connectattr(
53            'time', self.inputnode, 'time2'
54        )

Start the timer.

def has_started(self) -> bool:
56    def has_started(self) -> bool:
57        """Return whether this timer has started yet."""
58        return self._starttime_ms is not None

Return whether this timer has started yet.

def stop(self, endtime: int | float | None = None) -> None:
60    def stop(self, endtime: int | float | None = None) -> None:
61        """End the timer.
62
63        If 'endtime' is not None, it is used when calculating
64        the final display time; otherwise the current time is used.
65        """
66        if endtime is None:
67            endtime = bs.time()
68
69        if self._starttime_ms is None:
70            logging.warning(
71                'OnScreenTimer.stop() called without first calling start()'
72            )
73        else:
74            endtime_ms = int(endtime * 1000)
75            self.inputnode.timemax = endtime_ms - self._starttime_ms

End the timer.

If 'endtime' is not None, it is used when calculating the final display time; otherwise the current time is used.

def getstarttime(self) -> float:
77    def getstarttime(self) -> float:
78        """Return the scene-time when start() was called.
79
80        Time will be returned in seconds if timeformat is SECONDS or
81        milliseconds if it is MILLISECONDS.
82        """
83        val_ms: Any
84        if self._starttime_ms is None:
85            print('WARNING: getstarttime() called on un-started timer')
86            val_ms = int(bs.time() * 1000.0)
87        else:
88            val_ms = self._starttime_ms
89        assert isinstance(val_ms, int)
90        return 0.001 * val_ms

Return the scene-time when start() was called.

Time will be returned in seconds if timeformat is SECONDS or milliseconds if it is MILLISECONDS.

starttime: float
92    @property
93    def starttime(self) -> float:
94        """Shortcut for start time in seconds."""
95        return self.getstarttime()

Shortcut for start time in seconds.

@override
def handlemessage(self, msg: Any) -> Any:
 97    @override
 98    def handlemessage(self, msg: Any) -> Any:
 99        # if we're asked to die, just kill our node/timer
100        if isinstance(msg, bs.DieMessage):
101            if self.node:
102                self.node.delete()

General message handling; can be passed any message object.