Skip to content

Commit 2c89a32

Browse files
committed
Add the font generation and examples
1 parent c8d2c3f commit 2c89a32

File tree

6 files changed

+195
-0
lines changed

6 files changed

+195
-0
lines changed

examples/ball/main.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import ugame
2+
import stage
3+
4+
5+
class Ball(stage.Sprite):
6+
def __init__(self, x, y):
7+
super().__init__(bank, 1, x, y)
8+
self.dx = 2
9+
self.dy = 1
10+
11+
def update(self):
12+
super().update()
13+
self.set_frame(self.frame % 4 + 1)
14+
self.move(self.x + self.dx, self.y + self.dy)
15+
if not 0 < self.x < 112:
16+
self.dx = -self.dx
17+
if not 0 < self.y < 112:
18+
self.dy = -self.dy
19+
20+
21+
bank = stage.Bank.from_bmp16("ball.bmp")
22+
background = stage.Grid(bank)
23+
text = stage.Text(12, 1)
24+
text.move(16, 60)
25+
text.text("Hello world!")
26+
ball1 = Ball(64, 0)
27+
ball2 = Ball(0, 76)
28+
ball3 = Ball(111, 64)
29+
game = stage.Stage(ugame.display, 12)
30+
sprites = [ball1, ball2, ball3]
31+
game.layers = [text, ball1, ball2, ball3, background]
32+
game.render_block(0, 0, 128, 128)
33+
34+
while True:
35+
for sprite in sprites:
36+
sprite.update()
37+
game.render_sprites(sprites)
38+
game.tick()

examples/rpg/ground.bmp

2.18 KB
Binary file not shown.

examples/rpg/main.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import random
2+
import ugame
3+
import stage
4+
5+
6+
g = stage.Bank.from_bmp16("ground.bmp")
7+
b = stage.Bank.from_bmp16("tiles.bmp")
8+
l1 = stage.Grid(g)
9+
l0 = stage.Grid(b, 10, 9)
10+
l0.tile(0, 0, 13)
11+
l0.move(-8, -8)
12+
for y in range(8):
13+
for x in range(8):
14+
l1.tile(x, y, random.randint(0, 4))
15+
for y in range(9):
16+
for x in range(9):
17+
t = 0
18+
bit = 1
19+
for dx in (0, -1):
20+
for dy in (-1, 0):
21+
if l1.tile(x + dx, y + dy) == 4:
22+
t |= bit
23+
bit <<= 1
24+
l0.tile(x, y, 15 - t)
25+
p = stage.Sprite(g, 15, 10, 10)
26+
t = stage.Text(14, 14)
27+
t.move(8, 8)
28+
t.text("Hello world!")
29+
30+
game = stage.Stage(ugame.display, 12)
31+
sprites = [
32+
stage.Sprite(g, 15, 60, 50),
33+
stage.Sprite(g, 15, 70, 60),
34+
stage.Sprite(g, 15, 80, 70),
35+
stage.Sprite(g, 15, 90, 80),
36+
stage.Sprite(g, 15, 100, 90),
37+
p,
38+
]
39+
game.layers = [t, l0] + sprites + [l1]
40+
game.render(0, 0, 128, 128)
41+
42+
frame = 0
43+
while True:
44+
frame = (frame + 1) % 8
45+
keys = ugame.buttons.get_pressed()
46+
if keys & ugame.K_RIGHT:
47+
p.move(p.x, p.y + 2)
48+
p.set_frame(12 + frame // 4, 0)
49+
elif keys & ugame.K_LEFT:
50+
p.move(p.x, p.y - 2)
51+
p.set_frame(12 + frame // 4, 4)
52+
elif keys & ugame.K_UP:
53+
p.move(p.x + 2, p.y)
54+
p.set_frame(14, (frame // 4) * 4)
55+
elif keys & ugame.K_DOWN:
56+
p.move(p.x - 2, p.y)
57+
p.set_frame(15, (frame // 4) * 4)
58+
else:
59+
p.set_frame(15, (frame // 4) * 4)
60+
for sprite in sprites:
61+
if sprite != p:
62+
sprite.set_frame(15, (frame // 4) * 4)
63+
x0 = min(sprite.px, sprite.x)
64+
y0 = min(sprite.py, sprite.y)
65+
x1 = max(sprite.px, sprite.x) + 16
66+
y1 = max(sprite.py, sprite.y) + 16
67+
game.render(x0, y0, x1, y1)
68+
game.tick()

examples/rpg/tiles.bmp

2.17 KB
Binary file not shown.

font/font2.bmp

4.15 KB
Binary file not shown.

font/genfont2.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import array
2+
import pprint
3+
4+
5+
def color565(r, g, b):
6+
return (r & 0xf8) << 8 | (g & 0xfc) << 3 | b >> 3
7+
8+
9+
class BMP16:
10+
"""Read 16-color BMP files."""
11+
12+
def __init__(self, filename):
13+
self.filename = filename
14+
self.colors = 0
15+
16+
def read_header(self):
17+
"""Read the file's header information."""
18+
19+
if self.colors:
20+
return
21+
with open(self.filename, 'rb') as f:
22+
f.seek(10)
23+
self.data = int.from_bytes(f.read(4), 'little')
24+
f.seek(18)
25+
self.width = int.from_bytes(f.read(4), 'little')
26+
self.height = int.from_bytes(f.read(4), 'little')
27+
f.seek(46)
28+
self.colors = int.from_bytes(f.read(4), 'little')
29+
30+
def read_palette(self):
31+
"""Read the color palette information."""
32+
33+
palette = array.array('H', (0 for i in range(16)))
34+
with open(self.filename, 'rb') as f:
35+
f.seek(self.data - self.colors * 4)
36+
for color in range(self.colors):
37+
buffer = f.read(4)
38+
c = color565(buffer[2], buffer[1], buffer[0])
39+
palette[color] = ((c & 0xff) << 8) | (c >> 8)
40+
return palette
41+
42+
def read_data(self, offset=0, size=-1):
43+
"""Read the image data."""
44+
45+
with open(self.filename, 'rb') as f:
46+
f.seek(self.data + offset)
47+
return f.read(size)
48+
49+
50+
class Font:
51+
def __init__(self, buffer):
52+
self.buffer = buffer
53+
54+
@classmethod
55+
def from_bmp16(cls, filename):
56+
bmp = BMP16(filename)
57+
bmp.read_header()
58+
if bmp.width != 8 or bmp.height != 1024:
59+
raise ValueError("A 8x1024 16-color BMP expected!")
60+
data = bmp.read_data()
61+
self = cls(bytearray(2048))
62+
c = 0
63+
x = 0
64+
y = 7
65+
for b in data:
66+
self.pixel(c, x, y, b >> 4)
67+
x += 1
68+
self.pixel(c, x, y, b & 0x0f)
69+
x += 1
70+
if x >= 8:
71+
x = 0
72+
y -= 1
73+
if y < 0:
74+
y = 7
75+
c += 1
76+
del data
77+
self.palette = bmp.read_palette()
78+
return self
79+
80+
def pixel(self, c, x, y, color):
81+
index = (127 - c) * 16 + 2 * y + x // 4
82+
bit = (x % 4) * 2
83+
color = color & 0x03
84+
self.buffer[index] |= color << bit
85+
86+
87+
font = Font.from_bmp16("font2.bmp")
88+
pprint.pprint(font.buffer)
89+
pprint.pprint(font.palette.tobytes())

0 commit comments

Comments
 (0)