@@ -8,11 +8,15 @@ def color565(r, g, b):
88
99
1010class BMP16 :
11+ """Read 16-color BMP files."""
12+
1113 def __init__ (self , filename ):
1214 self .filename = filename
1315 self .colors = 0
1416
1517 def read_header (self ):
18+ """Read the file's header information."""
19+
1620 if self .colors :
1721 return
1822 with open (self .filename , 'rb' ) as f :
@@ -25,6 +29,8 @@ def read_header(self):
2529 self .colors = int .from_bytes (f .read (4 ), 'little' )
2630
2731 def read_palette (self ):
32+ """Read the color palette information."""
33+
2834 palette = array .array ('H' , 0 for i in range (16 ))
2935 with open (self .filename , 'rb' ) as f :
3036 f .seek (self .data - self .colors * 4 )
@@ -35,12 +41,22 @@ def read_palette(self):
3541 return palette
3642
3743 def read_data (self , offset = 0 , size = - 1 ):
44+ """Read the image data."""
45+
3846 with open (self .filename , 'rb' ) as f :
3947 f .seek (self .data + offset )
4048 return f .read (size )
4149
4250
4351class Bank :
52+ """
53+ Store graphics for the tiles and sprites.
54+
55+ A single bank stores exactly 16 tiles, each 16x16 pixels in 16 possible
56+ colors, and a 16-color palette. We just like the number 16.
57+
58+ """
59+
4460 def __init__ (self , buffer = None , palette = None ):
4561 self .buffer = buffer
4662 self .palette = palette
@@ -57,6 +73,11 @@ def from_bmp16(cls, filename):
5773
5874
5975class Grid :
76+ """
77+ A grid is a layer of tiles that can be displayed on the screen. Each square
78+ can contain any of the 16 tiles from the associated bank.
79+ """
80+
6081 def __init__ (self , bank , width = 8 , height = 8 , palette = None ):
6182 self .buffer = bytearray ((width * height ) >> 1 )
6283 self .x = 0
@@ -70,6 +91,8 @@ def __init__(self, bank, width=8, height=8, palette=None):
7091 self .bank .palette , self .buffer )
7192
7293 def tile (self , x , y , tile = None ):
94+ """Get or set what tile is displayed in the given place."""
95+
7396 if not 0 <= x < self .width or not 0 <= y < self .height :
7497 return 0
7598 b = self .buffer [(x * self .width + y ) >> 1 ]
@@ -82,6 +105,8 @@ def tile(self, x, y, tile=None):
82105 self .buffer [(x * self .width + y ) >> 1 ] = b
83106
84107 def move (self , x , y , z = None ):
108+ """Shift the whole layer respective to the screen."""
109+
85110 self .x = x
86111 self .y = y
87112 if z is not None :
@@ -90,6 +115,11 @@ def move(self, x, y, z=None):
90115
91116
92117class Sprite :
118+ """
119+ A sprite is a layer containing just a single tile from the associated bank,
120+ that can be positioned anywhere on the screen.
121+ """
122+
93123 def __init__ (self , bank , frame , x , y , z = 0 , rotation = 0 , palette = None ):
94124 self .bank = bank
95125 self .palette = palette or bank .palette
@@ -104,14 +134,20 @@ def __init__(self, bank, frame, x, y, z=0, rotation=0, palette=None):
104134 self .px = x
105135 self .py = y
106136
107- def move (self , x , y ):
137+ def move (self , x , y , z = None ):
138+ """Move the sprite to the given place."""
139+
108140 self .px = self .x
109141 self .py = self .y
110142 self .x = x
111143 self .y = y
144+ if z is not None :
145+ self .z = z
112146 self .layer .move (x , y )
113147
114148 def set_frame (self , frame = None , rotation = None ):
149+ """Set the current graphic and rotation of the sprite.""" "
150+
115151 if frame is not None :
116152 self .frame = frame
117153 if rotation is not None :
@@ -120,14 +156,19 @@ def set_frame(self, frame=None, rotation=None):
120156
121157
122158class Stage :
159+ """
160+ Represents what is being displayed on the screen.
161+ """
162+ buffer = bytearray (512 )
163+
123164 def __init__ (self , display , fps = 6 ):
124165 self .layers = []
125166 self .display = display
126- self .buffer = bytearray (512 )
127167 self .last_tick = time .monotonic ()
128168 self .tick_delay = 1 / fps
129169
130170 def tick (self ):
171+ """Wait for the start of the next frame."""
131172 self .last_tick += self .tick_delay
132173 wait = max (0 , self .last_tick - time .monotonic ())
133174 if wait :
@@ -136,6 +177,8 @@ def tick(self):
136177 self .last_tick = time .monotonic ()
137178
138179 def render (self , x0 , y0 , x1 , y1 ):
180+ """Update a rectangle of the screen."""
139181 layers = [l .layer for l in self .layers ]
140182 self .display .block (x0 , y0 , x1 - 1 , y1 - 1 )
141183 _stage .render (x0 , y0 , x1 , y1 , layers , self .buffer , self .display .spi )
184+
0 commit comments