1"""
2bitarray.py
3===========
4
5.. figure:: /_static/bitarray.png
6 :align: center
7
8 An example using map_bitarray_to_rgb565 to draw sprites
9"""
10
11# pylint: disable=import-error
12import random
13import time
14import gc9a01
15import tft_config
16
17
18tft = tft_config.config(1)
19
20#
21SPRITE_WIDTH = 16
22SPRITE_HEIGHT = 16
23SPRITE_STEPS = 3
24# fmt: off
25SPRITE_BITMAPS = [
26 bytearray([
27 0b00000000, 0b00000000,
28 0b00000001, 0b11110000,
29 0b00000111, 0b11110000,
30 0b00001111, 0b11100000,
31 0b00001111, 0b11000000,
32 0b00011111, 0b10000000,
33 0b00011111, 0b00000000,
34 0b00011110, 0b00000000,
35 0b00011111, 0b00000000,
36 0b00011111, 0b10000000,
37 0b00001111, 0b11000000,
38 0b00001111, 0b11100000,
39 0b00000111, 0b11110000,
40 0b00000001, 0b11110000,
41 0b00000000, 0b00000000,
42 0b00000000, 0b00000000]),
43
44 bytearray([
45 0b00000000, 0b00000000,
46 0b00000011, 0b11100000,
47 0b00001111, 0b11111000,
48 0b00011111, 0b11111100,
49 0b00011111, 0b11111100,
50 0b00111111, 0b11110000,
51 0b00111111, 0b10000000,
52 0b00111100, 0b00000000,
53 0b00111111, 0b10000000,
54 0b00111111, 0b11110000,
55 0b00011111, 0b11111100,
56 0b00011111, 0b11111100,
57 0b00001111, 0b11111000,
58 0b00000011, 0b11100000,
59 0b00000000, 0b00000000,
60 0b00000000, 0b00000000]),
61
62 bytearray([
63 0b00000000, 0b00000000,
64 0b00000111, 0b11000000,
65 0b00011111, 0b11110000,
66 0b00111111, 0b11111000,
67 0b00111111, 0b11111000,
68 0b01111111, 0b11111100,
69 0b01111111, 0b11111100,
70 0b01111111, 0b11111100,
71 0b01111111, 0b11111100,
72 0b01111111, 0b11111100,
73 0b00111111, 0b11111000,
74 0b00111111, 0b11111000,
75 0b00011111, 0b11110000,
76 0b00000111, 0b11000000,
77 0b00000000, 0b00000000,
78 0b00000000, 0b00000000]),
79
80 bytearray([
81 0b00000000, 0b00000000,
82 0b00000000, 0b00000000,
83 0b00000000, 0b00000000,
84 0b00000000, 0b00000000,
85 0b00000000, 0b00000000,
86 0b00000000, 0b00000000,
87 0b00000000, 0b00000000,
88 0b00000000, 0b00000000,
89 0b00000000, 0b00000000,
90 0b00000000, 0b00000000,
91 0b00000000, 0b00000000,
92 0b00000000, 0b00000000,
93 0b00000000, 0b00000000,
94 0b00000000, 0b00000000,
95 0b00000000, 0b00000000,
96 0b00000000, 0b00000000])]
97
98# fmt: on
99
100
101def collide(first, second):
102 """return true if two sprites collide or overlap"""
103
104 return (
105 first.sprite_x + first.width > second.sprite_x
106 and first.sprite_x < second.sprite_x + second.width
107 and first.sprite_y + first.height > second.sprite_y
108 and first.sprite_y < second.sprite_y + second.height
109 )
110
111
112class Pacman:
113 """
114 Pacman class to keep track of a sprites location and step
115 """
116
117 def __init__(self, sprites, width, height, steps):
118 """create a new pacman sprite that does not overlap another sprite"""
119 self.sprite_x = 0
120 self.sprite_y = 0
121 self.steps = steps
122 self.step = random.randint(0, self.steps)
123 self.width = width
124 self.height = height
125
126 # Big problem if there are too many sprites for the size of the display
127 while True:
128 self.sprite_x = random.randint(0, tft.width() - width)
129 self.sprite_y = random.randint(0, tft.height() - height)
130 # if this sprite does not overlap another sprite then break
131 if not any(collide(self, sprite) for sprite in sprites):
132 break
133
134 def move(self):
135 """move the sprite one step"""
136 max_x = tft.width() - SPRITE_WIDTH
137 self.step += 1
138 self.step %= SPRITE_STEPS
139 self.sprite_x += 1
140 if self.sprite_x == max_x - 1:
141 self.step = SPRITE_STEPS
142
143 self.sprite_x %= max_x
144
145 def draw(self, blitable):
146 """draw the sprite on the screen"""
147 tft.blit_buffer(blitable, self.sprite_x, self.sprite_y, self.width, self.height)
148
149
150def main():
151 """
152 Draw on screen using map_bitarray_to_rgb565
153 """
154
155 # enable display and clear screen
156 tft.init()
157 tft.fill(gc9a01.BLACK)
158
159 # convert bitmaps into rgb565 blitable buffers
160 blitable = []
161 for sprite_bitmap in SPRITE_BITMAPS:
162 sprite = bytearray(512)
163 tft.map_bitarray_to_rgb565(
164 sprite_bitmap, sprite, SPRITE_WIDTH, gc9a01.YELLOW, gc9a01.BLACK
165 )
166 blitable.append(sprite)
167
168 sprite_count = tft.width() // SPRITE_WIDTH * tft.height() // SPRITE_HEIGHT // 4
169
170 # create pacman spites in random positions
171 sprites = []
172 for _ in range(sprite_count):
173 sprites.append(Pacman(sprites, SPRITE_WIDTH, SPRITE_HEIGHT, SPRITE_STEPS))
174
175 # move and draw sprites
176 while True:
177 for sprite in sprites:
178 sprite.move()
179 sprite.draw(blitable[sprite.step])
180 time.sleep(0.05)
181
182
183main()