Skip to content

Commit 17519fe

Browse files
committed
Basic documentation
1 parent ac08c4d commit 17519fe

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
Stage – a tile and sprite engine for CircuitPython
2-
**************************************************
1+
Stage – a Tile and Sprite Engine
2+
********************************
33

44
Stage is a library that lets you display tile grids and sprites on SPI-based
55
RGB displays in CircuitPython. It is mostly made with video games in mind, but

stage.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ def color565(r, g, b):
88

99

1010
class 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

4351
class 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

5975
class 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

92117
class 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

122158
class 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

Comments
 (0)