summaryrefslogtreecommitdiff
path: root/scripts/make-cc0-art.py
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-21 20:22:25 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-21 20:22:25 +0800
commit63e9741816ce3717cfda4cc3354ff3a0860a3ddc (patch)
tree1511700d750758399b3a8b1d7bca9935945b8c56 /scripts/make-cc0-art.py
parent98b6b21c56c7b061578e7d4b56d52450dc7bd575 (diff)
downloadliving-village-63e9741816ce3717cfda4cc3354ff3a0860a3ddc.tar.gz
feat(art): 角色六帧动画与水面/炊烟三相循环
- 角色图集每个 (变体,方向) 由 2 帧扩到 6 帧(4 走路 + 2 待机呼吸), cellIndex=(variant*4+direction)*6+frame,图集 3840x48 - 世界图集扩到 25 格 800x32:水面第 3 相 WaterSpriteC(slot 21)、 炊烟三帧 SmokeSpriteA/B/C(slot 22-24) - 帧选择为纯函数:walk=(tick/4)%4、idle=(tick/24)%2、 water=(tick/32)%3、smoke=(tick/40)%3 - 重生成 jiangnan/cc0 图集(脚本可复现,逐字节一致)
Diffstat (limited to 'scripts/make-cc0-art.py')
-rw-r--r--scripts/make-cc0-art.py24
1 files changed, 16 insertions, 8 deletions
diff --git a/scripts/make-cc0-art.py b/scripts/make-cc0-art.py
index 897ec4f..f5c97ee 100644
--- a/scripts/make-cc0-art.py
+++ b/scripts/make-cc0-art.py
@@ -5,7 +5,7 @@ Reads the two provenanced CC0 packs in third_party/ (Kenney Tiny Farm tiles,
Puny Characters) and emits Deterministic CC0 Atlases for the prototype:
src/LivingVillage.Desktop/Assets/cc0-tiles.png 128x32 (4 ground tiles, 32px each)
- src/LivingVillage.Desktop/Assets/cc0-characters.png 2560x48 (5 variants x 4 directions x 4 frames, 32x48 cells)
+ src/LivingVillage.Desktop/Assets/cc0-characters.png 3840x48 (5 variants x 4 directions x 6 frames, 32x48 cells)
Mapping strategy (16 -> 32): integer 2x nearest-neighbour upscale of every source
sprite; ground tiles fill the 32x32 cell exactly; Puny sprites keep their
@@ -115,14 +115,18 @@ def build_cc0_tile_atlas():
def build_cc0_character_atlas():
- """5 variants x 4 directions x 4 frames of 32x48 cells from Puny characters.
+ """5 variants x 4 directions x 6 frames of 32x48 cells from Puny characters.
Layout: each 32x48 CELL = source 16x24 content band scaled 2x (32x48), anchored
bottom (feet on the ground line). Directions: the pack provides south-facing
art only; south/north use the same band (pack limitation recorded in the
commit), west/east are mirrored copies so walkers always read toward the player.
+
+ Frames 0-3 are the walk cycle (source poses 0-3). Frames 4-5 are the idle
+ breath cycle: the neutral pose (source pose 0) relaxed, then raised 1px for
+ the inhale. The pack has no dedicated idle art, so this reuses pose 0.
"""
- c = Canvas(2560, 48)
+ c = Canvas(3840, 48)
variant_files = [
"Soldier-Blue.png",
@@ -143,12 +147,16 @@ def build_cc0_character_atlas():
cell_w = 32
for vi, pose_cells in enumerate(variants):
for di in range(4):
- for frame in range(4):
- sprite = pose_cells[frame].resize((32, 48), Image.NEAREST)
+ # Walk frames reuse poses 0-3; idle frames 4-5 reuse the neutral pose 0,
+ # with frame 5 raised 1px so the pair reads as a breath.
+ frame_poses = [pose_cells[0], pose_cells[1], pose_cells[2], pose_cells[3], pose_cells[0], pose_cells[0]]
+ frame_offsets = [0, 0, 0, 0, 0, -1]
+ for frame in range(6):
+ sprite = frame_poses[frame].resize((32, 48), Image.NEAREST)
if di in (1, 3):
sprite = sprite.transpose(Image.FLIP_LEFT_RIGHT)
- ox = cell_w * ((vi * 4 + di) * 4 + frame)
- c.blit(sprite, ox, 0, scale=1)
+ ox = cell_w * ((vi * 4 + di) * 6 + frame)
+ c.blit(sprite, ox, frame_offsets[frame], scale=1)
return c
@@ -158,7 +166,7 @@ def main():
ASSETS.mkdir(parents=True, exist_ok=True)
targets = [
("cc0-tiles.png", build_cc0_tile_atlas(), 128, 32),
- ("cc0-characters.png", build_cc0_character_atlas(), 2560, 48),
+ ("cc0-characters.png", build_cc0_character_atlas(), 3840, 48),
]
for name, canvas, w, h in targets:
path = ASSETS / name