56 lines
2.6 KiB
Python
56 lines
2.6 KiB
Python
from pathlib import Path
|
|
|
|
import numpy as np
|
|
from PIL import Image
|
|
|
|
from spriteforge.backends import BackendContext, create_backend, implemented_backends
|
|
from spriteforge.build import build_assets
|
|
from spriteforge.manifest import AssetSpec, load_library
|
|
from spriteforge.reader import decode_sfa
|
|
|
|
|
|
def _png(path: Path, rgba: np.ndarray) -> None:
|
|
Image.fromarray(rgba, "RGBA").save(path)
|
|
|
|
|
|
def test_import_splits_sheet_and_sets_directions(tmp_path: Path):
|
|
sheet = np.zeros((4, 8, 4), dtype=np.uint8)
|
|
sheet[:, :4] = (255, 0, 0, 255); sheet[:, 4:] = (0, 255, 0, 255)
|
|
_png(tmp_path / "sheet.png", sheet)
|
|
spec = AssetSpec(backend="import", source="sheet.png", dirs=2, fps=10,
|
|
params={"frame_width": 4, "frame_height": 4})
|
|
backend = create_backend("import")
|
|
assert backend.dependencies(spec, BackendContext(tmp_path, "hero")) == (tmp_path / "sheet.png",)
|
|
asset = backend.generate(spec, BackendContext(tmp_path, "hero"))
|
|
assert len(asset.frames) == 2 and asset.directions_centidegrees == (0, 18000)
|
|
assert asset.frames[0].duration_ms == 100
|
|
|
|
|
|
def test_composite_alpha_blends_in_manifest_order(tmp_path: Path):
|
|
bottom = np.zeros((2, 2, 4), dtype=np.uint8); bottom[:] = (200, 0, 0, 255)
|
|
top = np.zeros((2, 2, 4), dtype=np.uint8); top[:] = (0, 0, 200, 128)
|
|
_png(tmp_path / "bottom.png", bottom); _png(tmp_path / "top.png", top)
|
|
spec = AssetSpec(backend="composite", layers=["bottom.png", "top.png"], dirs=1)
|
|
asset = create_backend("composite").generate(spec, BackendContext(tmp_path, "layered"))
|
|
pixel = asset.frames[0].rgba[0, 0]
|
|
assert tuple(pixel) == (100, 0, 100, 255)
|
|
assert asset.layer_count == 2
|
|
|
|
|
|
def test_all_local_backends_are_registered():
|
|
assert {"procedural", "blender", "import", "composite"} <= set(implemented_backends())
|
|
assert "image_api" not in implemented_backends()
|
|
|
|
|
|
def test_import_and_composite_build_real_sfa_files(tmp_path: Path):
|
|
red = np.zeros((4, 4, 4), dtype=np.uint8); red[:] = (200, 20, 20, 255)
|
|
blue = np.zeros((4, 4, 4), dtype=np.uint8); blue[1:3, 1:3] = (20, 20, 200, 255)
|
|
_png(tmp_path / "red.png", red); _png(tmp_path / "blue.png", blue)
|
|
manifest = tmp_path / "assets.yaml"
|
|
manifest.write_text("imported:\n backend: import\n source: red.png\nlayered:\n backend: composite\n layers: [red.png, blue.png]\n")
|
|
result = build_assets(load_library([manifest]), tmp_path / "build", cache_dir=tmp_path / "cache")
|
|
assert result.asset_count == 2
|
|
assert decode_sfa((tmp_path / "build" / "imported.sfa").read_bytes()).frames
|
|
layered = decode_sfa((tmp_path / "build" / "layered.sfa").read_bytes())
|
|
assert layered.layer_orders == ((0, 1),)
|