-
Notifications
You must be signed in to change notification settings - Fork 7
/
firescene.py
executable file
·89 lines (79 loc) · 2.19 KB
/
firescene.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
try:
from uos import urandom
except:
from os import urandom
from pixelfont import PixelFont
class FireScene:
"""This module implements an example scene with a traveling pixel"""
def __init__(self, display, config):
"""
Initialize the module.
`display` is saved as an instance variable because it is needed to
update the display via self.display.put_pixel() and .render()
"""
self.display = display
self.intensity = 32
self.remaining_frames = self.display.fps<<2
if not config:
return
if 'intensity' in config:
self.intensity = int(round(config['intensity']*255))
def reset(self):
"""
This method is called before transitioning to this scene.
Use it to (re-)initialize any state necessary for your scene.
"""
self.remaining_frames = self.display.fps<<2
def input(self, button_state):
"""
Handle button input
"""
return 0 # signal that we did not handle the input
def set_intensity(self, value=None):
if value is not None:
self.intensity -= 1
if not self.intensity:
self.intensity = 16
return self.intensity
def render(self, frame, dropped_frames, fps):
"""
Render the scene.
This method is called by the render loop with the current frame number,
the number of dropped frames since the previous invocation and the
requested frames per second (FPS).
"""
display = self.display
get_pixel = display.get_pixel
put_pixel = display.put_pixel
intensity = self.intensity
width = display.columns
max_y = display.stride - 1
# Fire source
b = intensity >> 1
for x in range(display.columns):
put_pixel(x, max_y, intensity, intensity, b)
# Spread fire
for y in range(max_y):
for x in range(width):
# Cool previous pixel
r, g, b = display.get_pixel(x, y)
if r or g or b:
r -= 1
g -= 1
b >>= 1
put_pixel(x, y, max(r, 0), max(g, 0), b)
# Spread heat from below
r, g, b = get_pixel(x, y+1)
try:
spread = (urandom(1)[0]&3) - 1
except TypeError:
spread = (ord(urandom(1)[0])&3) - 1
r -= spread
g -= 1
b >>= 2
put_pixel(x+spread, y, max(r, 0), max(g, 0), b)
display.render()
self.remaining_frames -= 1
if not self.remaining_frames:
return False
return True