#!/usr/bin/env python3 """Генератор спрайтов для examples/space (raw-ленты для mkatlas.py). asteroid.raw — 16×16×4 (LOOP): серый астероид, кратеры вращаются по фазам (шаг 22.5°). explode.raw — 16×16×4 (ONCE): расширяющийся взрыв (жёлтое ядро → кольца → разлёт искр). beacon.raw — 16×16×4 (PINGPONG): пульсирующий маяк (крест с растущим свечением). Палитра — дефолтная EGA (индексы 0..15), 0xFF = прозрачно. """ import math T = 0xFF # прозрачный W = H = 16 CX = CY = 7.5 def blank(): return [[T] * W for _ in range(H)] def disc(px, cx, cy, r, c): for y in range(H): for x in range(W): if (x - cx) ** 2 + (y - cy) ** 2 <= r * r: px[y][x] = c def ring(px, cx, cy, r, c): for a in range(0, 360, 4): x = int(round(cx + r * math.cos(math.radians(a)))) y = int(round(cy + r * math.sin(math.radians(a)))) if 0 <= x < W and 0 <= y < H: px[y][x] = c def dot(px, x, y, c): if 0 <= x < W and 0 <= y < H: px[int(y)][int(x)] = c def asteroid(phase): px = blank() disc(px, CX, CY, 6.8, 7) # LIGHTGRAY тело ring(px, CX, CY, 6.8, 8) # DARKGRAY контур for i in range(3): # кратеры на орбите a = math.radians(phase * 22.5 + i * 120) disc(px, CX + 3.6 * math.cos(a), CY + 3.6 * math.sin(a), 1.4, 8) dot(px, CX - 2, CY - 3, 15) # блик WHITE return px def explode(phase): px = blank() if phase == 0: disc(px, CX, CY, 2.2, 14) # YELLOW ядро elif phase == 1: disc(px, CX, CY, 3.8, 14) ring(px, CX, CY, 4.6, 12) # LIGHTRED elif phase == 2: ring(px, CX, CY, 4.2, 14) ring(px, CX, CY, 6.0, 12) ring(px, CX, CY, 7.0, 4) # RED else: for a in range(0, 360, 30): # разлёт искр r = 6.5 dot(px, CX + r * math.cos(math.radians(a)), CY + r * math.sin(math.radians(a)), 4) dot(px, CX + 4 * math.cos(math.radians(a + 15)), CY + 4 * math.sin(math.radians(a + 15)), 6) # BROWN return px def beacon(phase): px = blank() r = 2 + phase * 1.6 for d in range(int(r) + 1): # крест-лучи for xx, yy in ((CX - d, CY), (CX + d, CY), (CX, CY - d), (CX, CY + d)): dot(px, round(xx), round(yy), 11) # LIGHTCYAN disc(px, CX, CY, 1.4, 15) # WHITE ядро if phase >= 2: ring(px, CX, CY, r + 1, 9) # LIGHTBLUE ореол return px def save(name, frames): with open(name, "wb") as f: for fr in frames: for row in fr: f.write(bytes(row)) print(f"gen_sprites: {name} ({len(frames)} кадров)") save("asteroid.raw", [asteroid(k) for k in range(4)]) save("explode.raw", [explode(k) for k in range(4)]) save("beacon.raw", [beacon(k) for k in range(4)])