Andrea vero: camminata, parlato, prendere e di spalle dal foglio sprite

tools/slice_sprites.py da Manzolo Rush e tools/prepare_character.py, che allinea
i fotogrammi sul busto e sui piedi; il motore sceglie il fotogramma da quello
che Andrea sta facendo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 01:00:36 +02:00
co-authored by Claude Opus 5.5
parent 7133c46891
commit f7f65a74fd
12 changed files with 803 additions and 19 deletions
+23
View File
@@ -140,3 +140,26 @@ test('lo stato salvato si ricarica uguale', () => {
const again = new Game(mini(), { state: JSON.parse(JSON.stringify(g.snapshot())) });
assert.deepEqual(again.snapshot(), g.snapshot());
});
test('il fotogramma segue quello che fa Andrea', () => {
const g = new Game(mini());
assert.equal(g.pose(), 'stand');
g.walkTo([150, 50]);
const seen = new Set();
for (let i = 0; i < 40; i++) { g.update(0.05); if (g.walking) seen.add(g.pose()); }
assert.deepEqual([...seen].sort(), ['walk_1', 'walk_2', 'walk_3', 'walk_4']);
g.queue.push({ face: 'up' });
settle(g);
assert.equal(g.pose(), 'back');
g.queue.push({ give: 'sasso' });
g.update(0.01);
assert.equal(g.pose(), 'take');
assert.ok(g.busy, 'mentre prende qualcosa non si interrompe');
settle(g);
assert.equal(g.pose(), 'stand');
g.queue.push({ say: 'Ciao a tutti.' });
g.update(0.01);
const poses = new Set();
for (let i = 0; i < 10; i++) { g.time += 0.1; poses.add(g.pose()); }
assert.deepEqual([...poses].sort(), ['stand', 'talk']);
});
+11 -1
View File
@@ -4,7 +4,7 @@ import { story } from '../src/story/story.js';
import { solution } from '../src/story/solution.js';
import { Game, VERBS } from '../src/engine/game.js';
import { inside } from '../src/engine/geometry.js';
import { existsSync } from 'node:fs';
import { existsSync, readFileSync } from 'node:fs';
import { settle } from './helpers.mjs';
const EFFECTS = ['say', 'walk', 'face', 'give', 'drop', 'set', 'unset', 'if', 'dialogue', 'node', 'endDialogue', 'go', 'end'];
@@ -95,3 +95,13 @@ test('la soluzione si percorre tutta dall\'inizio alla fine', () => {
assert.ok(g.state.flags.indizio_regolo);
assert.ok(saves.at(-1).ended, 'la fine non è salvata');
});
test('i fogli dei personaggi hanno tutti i fotogrammi e l\'immagine', () => {
for (const [id, c] of Object.entries(story.characters)) {
if (!c.sprite) continue;
const url = new URL('../' + c.sprite, import.meta.url);
const atlas = JSON.parse(readFileSync(url, 'utf8'));
assert.ok(existsSync(new URL(atlas.image, url)), `${id}: manca ${atlas.image}`);
for (const f of ['walk_1', 'walk_2', 'walk_3', 'walk_4', 'stand', 'talk', 'take', 'back']) assert.ok(atlas.frames[f], `${id}: manca ${f}`);
}
});