"""原图变更后运行此脚本,更新七日活动的透明区域点击数据。需要 Pillow。""" import json from pathlib import Path from PIL import Image ROOT = Path(__file__).resolve().parents[1] images = sorted((ROOT / "assets/seven_day_gift/texture").glob("*.png")) images.append(ROOT / "assets/UI/Cat/cat.png") masks = {} for path in images: meta = json.loads(path.with_suffix(".png.meta").read_text(encoding="utf-8")) alpha = Image.open(path).convert("RGBA").getchannel("A") for frame in meta["subMetas"].values(): x, y, w, h = (frame[k] for k in ("trimX", "trimY", "width", "height")) pixels = alpha.crop((x, y, x + w, y + h)) rows, spans, lookup = [], [], {} for row in range(h): runs, start = [], None for col in range(w + 1): solid = col < w and pixels.getpixel((col, row)) >= 16 if solid and start is None: start = col elif not solid and start is not None: runs.extend((start, col)) start = None key = tuple(runs) if key not in lookup: lookup[key] = len(spans) spans.append(runs) rows.append(lookup[key]) masks[frame["uuid"]] = dict(width=w, height=h, rows=rows, spans=spans) output = ROOT / "assets/seven_day_gift/SevenDayHitMasks.ts" output.write_text( "// 自动生成的原图 Alpha 命中数据(阈值 16/255),勿手改;更新图片后运行 tools/generate-seven-hit-masks.py。\n" "export interface SevenDayHitMask { width: number; height: number; rows: number[]; spans: number[][]; }\n" "const masks: { [uuid: string]: SevenDayHitMask } = " + json.dumps(masks, separators=(",", ":")) + ";\nexport default masks;\n", encoding="utf-8", ) print(f"Generated {len(masks)} masks, {output.stat().st_size} bytes")