This module started with just the Cooldown class, which can be used check if a specified time has passed. It is mostly indended to be used to control objects in a game loop, but it is general enough for other purposes as well.
fire_cooldown = Cooldown(1, cold=True)
while True:
if fire_shot and fire_cooldown.cold():
fire_cooldown.reset()
launch_bullet()
...With the usage of Cooldown on ramp data (e.g. a Lerp between an opaque and a
fully transparent sprite over the time of n seconds), I came up with the
LerpThing. The LerpThing gives you exactly that. A lerp between from and
to mapped onto a duration.
alpha = LerpThing(0, 255, 5)
while True:
...
sprite.set_alpha(alpha())
# or sprite.set_alpha(alpha.v)
if alpha.finished:
sprite.kill()Finally, the need to use Cooldown for scheduling the creations of game objects, the CronD class was added. It schedules functions to run after a wait period.
Note, that CronD doesn't do any magic background timer stuff, it needs to be updated in the game loop.
crond = CronD()
crond.add(1, create_enemy(screen.center))
crond.add(2, create_enemy(screen.center))
crond.add(3, create_enemy(screen.center))
crond.add(4, create_enemy(screen.center))
while True:
...
crond.update()c = Cooldown(c)Track a cooldown over a period of time.
cooldown = Cooldown(5)
while True:
do_stuff()
if key_pressed
if key == 'P':
cooldown.pause()
elif key == 'ESC':
cooldown.start()
if cooldown.cold():
launch_stuff()
cooldown.reset()Cooldown can be used to time sprite animation frame changes, weapon cooldown in shmups, all sorts of events when programming a game.
If you want to use the cooldown more as a timing gauge, e.g. to modify
acceleration of a sprite over time, have a look at the LerpThing class
in this package, which makes this incredibly easy.
When instantiated (and started), Cooldown stores the current time. The
cooldown will become cold when the given duration has passed.
While a cooldown is paused, the remaining time doesn't change.
At any time, the cooldown can be reset to its initial or a new value.
A cooldown can be compared to int/float/bool, in which case the
remaining property is used.
Cooldown provides a "copy constructor", meaning you can initialize a new
cooldown with an existing one. The full state of the initial cooldown
is used, including paused, wrap, and the remaining time.
When a cooldown is reset, depending on when you checked the cold
state, more time may have passed than the actual cooldown duration.
The wrap attribute decides, if the cooldown then is just reset back to
the duration, or if this additional time is taken into account. The
wrap argument of the reset function overwrites the default
configuration of the cooldown instance.
c0 = Cooldown(5)
c1 = Cooldown(5, wrap=True)
sleep(7)
c0.temperature, c1.temperature
--> -2.000088164 -2.0000879129999998
c0.reset()
c1.reset()
c0.temperature, c1.temperature
--> 4.999999539 2.999883194
sleep(7)
c0.temperature, c1.temperature
--> -2.000189442 -4.000306759000001
c0.reset(wrap=True)
c1.reset(wrap=False)
c0.temperature, c1.temperature
--> 2.999748423 4.999999169IMPORTANT: wrapping is meant to keep precise timing over a long period of time, while dealing with load peaks. If you constantly overshoot, you won't be able to catch back up to the full cooldown time. Your overshoot errors will accumulate.
A cooldown can be used as an iterator, returning the time remaining.
for t in Cooldown(5):
print(t)
sleep(1)
4.998921067
3.998788201
2.998640238
1.9984825379999993
0.998318566Time to cooldown in seconds
Start the cooldown already cold, e.g. for initial events.
Created the cooldown in paused state. Use cooldown.start() to
run it.
Set the reset mode to wrapped (see above).
Can be overwritten by the wrap argument to the reset function.
All attributes are read/write.
When calling reset, the cooldown is set to this value. Can be assigned
to directly or by calling cooldown.reset(duration)
The time left (or passed) until cooldown. Will go negative once the cooldown time has passed.
Same as temperature, but will not go below 0. When assigning, a negative value will be reset to 0.
returns the current "distance" in the cooldown between 0 and 1, with one being cold. Ideal for being used in an easing function or lerp.
to check if the cooldown is paused. Alternatively use cooldown.pause()/.start()/.is_paused() if you prefer methods.
Activate or deactivate wrap mode.
Cooldown provides a __repr__, the comparism methods <, <=, ==,
>=, >, can be converted to float/int/bool, and can be used as
an iterator. The 'temperature' value is used for all operations, so
results can be negative. As an iterator, StopIteration is raised when
the temperature goes below 0 though.
Has the time of the cooldown run out?
Is there stil time remaining before cooldown? This is just for
convenience to not write not cooldown.cold() all over the place.
Resets the cooldown. Without argument, resets to the current duration, otherwise the given value. See wrap for nuance.
reset() return self, so it can e.g. be chained with pause()
Pause, start, check the cooldown. Time is frozen during the pause.
Same as cooldown.temperature = val.
Same as cooldown.temperature = 0.
lt = LerpThing(vt0=32, vt1=175, duration=10, repeat=2)
sleep(1)
value = lt()A time based generic gauge that lerps between 2 points.
This class can be used for scaling, color shifts, momentum, ... It gets
initialized with 2 Values for t0 and t1, and a time duration, then it
lerps between these values.
Once the time runs out, the lerp can stop, repeat from start or bounce back and forth.
Note: if the lerp does not repeat, in contrast to e.g. python's range
function, LerpThing will not stop short of the final value, but will include
it once the time has run out.
An optional easing function can be put on top of t.
LerpThing is both iterable and an iterator.
The endpoints of the lerp at t == 0 and t == 1
The length of the lerp. This duration is mapped onto the range 0 - 1 as
t.
This is a Cooldown object, so all configuration and query options
apply, if you want to modify the lerp during its runtime.
Note: If duration is 0, vt0 is always returned.
An optional easing function to put over t
After the duration has passed, how to proceed?
0: Don't repeat, just stop transmogrifying
1: Reset and repeat from start
2: Bounce back and forth. Note, that bounce back is implemented by
swapping vt0 and vt1.
Just a conveninence wrapper for LerpThing.duration.cold()
my_class_attribute = AutoLerpThing()A descriptor class for LerpThing.
If an attribute in your class could either be a constant value, or a
LerpThing, use this descriptor to automatically handle this.
Note: This is a proof of concept. This might or might not stay in
here, the interface might or might not change. I'm not sure if this has
any advantages over a property, except not having so much boilerplate in
your class if you have multiple LerpThings in it.
Note 2: In contrast to a normal LerpThing, you access the
AutoLerpThing like a normal attribute, not like a method call.
Use it like this:
class Asteroid:
angle = AutoLerpThing()
def __init__(self):
self.angle = (0, 360, 10) # Will do one full rotation over 10 seconds
asteroid = Asteroid()
asteroid.angle
--> 107.43224363999998
asteroid.angle
--> 129.791468736
...crond = CronD()
A job manager class.
In the spirit of unix's crond, this class can be used to run functions
after a cooldown once or repeatedly. See CronJob below for how and why
to use it.
Check for due jobs and run them.
Schedule a new task.
The cooldown can be either a Cooldown object or a float
representing the number of seconds.
The task is a zero parameter callback function that is called once the
cooldown is cold.
repeat (bool, default is False) decides if the cooldown will reset and
the task will run on repeat, or if the job is a one shot that will be
removed.
A job id is returned, which can be e.g. used to remove a pending or repeating job.
Remove the scheduled job with the given id.
The project home is https://github.com/dickerdackel/pgcooldown
pip install git+https://github.com/dickerdackel/pgcooldown
pip install pgcooldown
Found at https://github.com/dickerdackel/pgcooldown/releases
This lib is under the MIT license.