품종 스프라이트 8종 재생성본 적용 (다리 5개 문제 해결)
- 앉은 자세 idle·측면 뷰 걷기·단일 앞발 work·양발 숟가락 cook으로 해부학 오류를 원천 차단한 재생성 시트로 전량 교체 - 걷기: 측면 보폭 교대 2프레임 복원 (200ms), 기울임 보정 제거 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
이전 너비: | 높이: | 크기: 82 KiB 이후 너비: | 높이: | 크기: 90 KiB |
|
이전 너비: | 높이: | 크기: 79 KiB 이후 너비: | 높이: | 크기: 88 KiB |
|
이전 너비: | 높이: | 크기: 75 KiB 이후 너비: | 높이: | 크기: 83 KiB |
|
이전 너비: | 높이: | 크기: 80 KiB 이후 너비: | 높이: | 크기: 86 KiB |
|
이전 너비: | 높이: | 크기: 80 KiB 이후 너비: | 높이: | 크기: 85 KiB |
|
이전 너비: | 높이: | 크기: 86 KiB 이후 너비: | 높이: | 크기: 87 KiB |
|
이전 너비: | 높이: | 크기: 77 KiB 이후 너비: | 높이: | 크기: 84 KiB |
|
이전 너비: | 높이: | 크기: 77 KiB 이후 너비: | 높이: | 크기: 84 KiB |
|
이전 너비: | 높이: | 크기: 69 KiB 이후 너비: | 높이: | 크기: 69 KiB |
|
이전 너비: | 높이: | 크기: 72 KiB 이후 너비: | 높이: | 크기: 94 KiB |
|
이전 너비: | 높이: | 크기: 74 KiB 이후 너비: | 높이: | 크기: 92 KiB |
|
이전 너비: | 높이: | 크기: 81 KiB 이후 너비: | 높이: | 크기: 78 KiB |
|
이전 너비: | 높이: | 크기: 83 KiB 이후 너비: | 높이: | 크기: 89 KiB |
|
이전 너비: | 높이: | 크기: 78 KiB 이후 너비: | 높이: | 크기: 90 KiB |
|
이전 너비: | 높이: | 크기: 66 KiB 이후 너비: | 높이: | 크기: 86 KiB |
|
이전 너비: | 높이: | 크기: 78 KiB 이후 너비: | 높이: | 크기: 85 KiB |
|
이전 너비: | 높이: | 크기: 80 KiB 이후 너비: | 높이: | 크기: 87 KiB |
|
이전 너비: | 높이: | 크기: 88 KiB 이후 너비: | 높이: | 크기: 82 KiB |
|
이전 너비: | 높이: | 크기: 65 KiB 이후 너비: | 높이: | 크기: 83 KiB |
|
이전 너비: | 높이: | 크기: 64 KiB 이후 너비: | 높이: | 크기: 81 KiB |
|
이전 너비: | 높이: | 크기: 52 KiB 이후 너비: | 높이: | 크기: 69 KiB |
|
이전 너비: | 높이: | 크기: 62 KiB 이후 너비: | 높이: | 크기: 80 KiB |
|
이전 너비: | 높이: | 크기: 58 KiB 이후 너비: | 높이: | 크기: 77 KiB |
|
이전 너비: | 높이: | 크기: 66 KiB 이후 너비: | 높이: | 크기: 79 KiB |
|
이전 너비: | 높이: | 크기: 80 KiB 이후 너비: | 높이: | 크기: 93 KiB |
|
이전 너비: | 높이: | 크기: 74 KiB 이후 너비: | 높이: | 크기: 89 KiB |
|
이전 너비: | 높이: | 크기: 69 KiB 이후 너비: | 높이: | 크기: 82 KiB |
|
이전 너비: | 높이: | 크기: 73 KiB 이후 너비: | 높이: | 크기: 86 KiB |
|
이전 너비: | 높이: | 크기: 79 KiB 이후 너비: | 높이: | 크기: 92 KiB |
|
이전 너비: | 높이: | 크기: 75 KiB 이후 너비: | 높이: | 크기: 81 KiB |
|
이전 너비: | 높이: | 크기: 68 KiB 이후 너비: | 높이: | 크기: 86 KiB |
|
이전 너비: | 높이: | 크기: 68 KiB 이후 너비: | 높이: | 크기: 82 KiB |
|
이전 너비: | 높이: | 크기: 49 KiB 이후 너비: | 높이: | 크기: 63 KiB |
|
이전 너비: | 높이: | 크기: 66 KiB 이후 너비: | 높이: | 크기: 77 KiB |
|
이전 너비: | 높이: | 크기: 66 KiB 이후 너비: | 높이: | 크기: 73 KiB |
|
이전 너비: | 높이: | 크기: 69 KiB 이후 너비: | 높이: | 크기: 81 KiB |
|
이전 너비: | 높이: | 크기: 66 KiB 이후 너비: | 높이: | 크기: 78 KiB |
|
이전 너비: | 높이: | 크기: 67 KiB 이후 너비: | 높이: | 크기: 73 KiB |
|
이전 너비: | 높이: | 크기: 56 KiB 이후 너비: | 높이: | 크기: 70 KiB |
|
이전 너비: | 높이: | 크기: 63 KiB 이후 너비: | 높이: | 크기: 81 KiB |
|
이전 너비: | 높이: | 크기: 61 KiB 이후 너비: | 높이: | 크기: 78 KiB |
|
이전 너비: | 높이: | 크기: 69 KiB 이후 너비: | 높이: | 크기: 72 KiB |
|
이전 너비: | 높이: | 크기: 65 KiB 이후 너비: | 높이: | 크기: 67 KiB |
|
이전 너비: | 높이: | 크기: 61 KiB 이후 너비: | 높이: | 크기: 64 KiB |
|
이전 너비: | 높이: | 크기: 55 KiB 이후 너비: | 높이: | 크기: 66 KiB |
|
이전 너비: | 높이: | 크기: 60 KiB 이후 너비: | 높이: | 크기: 65 KiB |
|
이전 너비: | 높이: | 크기: 60 KiB 이후 너비: | 높이: | 크기: 63 KiB |
|
이전 너비: | 높이: | 크기: 67 KiB 이후 너비: | 높이: | 크기: 62 KiB |
@@ -529,8 +529,7 @@ export default function VillageView({
|
|||||||
y: anim.y,
|
y: anim.y,
|
||||||
draw: () => {
|
draw: () => {
|
||||||
shadow(anim.x, anim.y + 2, 11);
|
shadow(anim.x, anim.y + 2, 11);
|
||||||
// 걷기는 프레임 교대 대신 한 프레임 + 총총 바운스 + 미세 기울임
|
// 걷기: 측면 보폭 교대 2프레임 (재생성 시트는 몸통이 고정되어 교대 가능)
|
||||||
// (두 걷기 프레임의 몸통 각도가 달라 교대 시 도리도리처럼 보이는 문제 회피)
|
|
||||||
const atKitchen =
|
const atKitchen =
|
||||||
working &&
|
working &&
|
||||||
state.buildings.find((b) => b.id === cat.assignedTo)?.type === "kitchen";
|
state.buildings.find((b) => b.id === cat.assignedTo)?.type === "kitchen";
|
||||||
@@ -539,7 +538,9 @@ export default function VillageView({
|
|||||||
? "cook"
|
? "cook"
|
||||||
: "work"
|
: "work"
|
||||||
: moving
|
: moving
|
||||||
? "walk1"
|
? Math.floor(now / 200) % 2 === 0
|
||||||
|
? "walk1"
|
||||||
|
: "walk2"
|
||||||
: "idle";
|
: "idle";
|
||||||
// 품종 스프라이트 → (cook 없으면 work) → 기본 스프라이트 순 폴백
|
// 품종 스프라이트 → (cook 없으면 work) → 기본 스프라이트 순 폴백
|
||||||
let sprite = getImage(catSprite(cat.breed, frameName));
|
let sprite = getImage(catSprite(cat.breed, frameName));
|
||||||
@@ -552,10 +553,8 @@ export default function VillageView({
|
|||||||
if (sprite) {
|
if (sprite) {
|
||||||
const sh = 42;
|
const sh = 42;
|
||||||
const sw = (sprite.width / sprite.height) * sh;
|
const sw = (sprite.width / sprite.height) * sh;
|
||||||
const tilt = moving ? Math.sin(now / 150) * 0.06 : 0;
|
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.translate(anim.x, anim.y + bob);
|
ctx.translate(anim.x, anim.y + bob);
|
||||||
ctx.rotate(tilt);
|
|
||||||
if (anim.flip) ctx.scale(-1, 1);
|
if (anim.flip) ctx.scale(-1, 1);
|
||||||
ctx.drawImage(sprite, -sw / 2, -sh + 4, sw, sh);
|
ctx.drawImage(sprite, -sw / 2, -sh + 4, sw, sh);
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
|
|||||||