- si salva solo a sequenza finita: uscire a metà di una risposta o della casetta riporta a prima; la squama presa resta salvata anche senza cambiare scena; test di interruzione su soluzione e catena del ghiacciolo - «Salva su file» nella pausa e «Carica» nel titolo, con controllo di versione e contenuto prima di sostituire il salvataggio del browser - cursore del volume delle voci («bla»), 50% di partenza; il muto zittisce subito la voce, la pausa la riprende - col dito un oggetto mancato di poco si prende, e i piccoli vincono sui grandi che li contengono (la squama); verbi su due colonne nel telefono in orizzontale - sfondi caricati per vicinanza alla scena di partenza, con tentativi limitati se falliscono; a gioco fermo non si ridisegna - modalità ?debug per scrivere le scene: area calpestabile, hotspot, punti, coordinate copiabili - corretto: i crediti dal titolo restavano dietro il titolo Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ApqNBvNbNCwXqR2RLo8QJh
74 lines
3.1 KiB
JavaScript
74 lines
3.1 KiB
JavaScript
// La "frase" in costruzione sotto la scena (Usa squama con…) e cosa fa ogni clic.
|
|
// Senza verbo scelto vale il clic intelligente: l'azione più sensata per quel punto.
|
|
import { VERB_LABELS } from './game.js';
|
|
|
|
export class Command {
|
|
constructor(game) {
|
|
this.game = game;
|
|
this.verb = null;
|
|
this.item = null;
|
|
}
|
|
|
|
reset() { this.verb = null; this.item = null; }
|
|
|
|
pickVerb(verb) {
|
|
this.verb = this.verb === verb ? null : verb;
|
|
this.item = null;
|
|
}
|
|
|
|
// Testo della riga sotto la scena, con l'eventuale bersaglio sotto il puntatore.
|
|
sentence(target = null) {
|
|
const g = this.game, name = target && g.targetName(target);
|
|
if (this.item && target === this.item && this.verb === 'use') return `${VERB_LABELS.use} ${g.itemName(this.item)}`;
|
|
if (this.item) return `${VERB_LABELS[this.verb]} ${g.itemName(this.item)} ${this.verb === 'give' ? 'a' : 'con'}${name ? ' ' + name : '…'}`;
|
|
if (this.verb) return `${VERB_LABELS[this.verb]}${name ? ' ' + name : '…'}`;
|
|
if (!target) return '';
|
|
const isItem = !!g.story.items[target];
|
|
return isItem ? `Usa ${name} con…` : `${VERB_LABELS[g.defaultVerb(target)]} ${name}`;
|
|
}
|
|
|
|
// Clic sulla scena: `look` per il clic destro o la pressione lunga, `hurry` per il doppio clic (passo doppio),
|
|
// `reach` per il dito (quanto lontano dall'oggetto vale ancora come preso).
|
|
clickScene(point, { look = false, hurry = false, reach = 0 } = {}) {
|
|
const g = this.game;
|
|
g.hurry = hurry;
|
|
if (g.skip()) return 'skip';
|
|
if (g.dialogue || g.busy) return null;
|
|
const h = g.hotspotAt(point, reach);
|
|
let done;
|
|
if (look && h) done = g.act('look', h.id);
|
|
else if (!h) done = g.walkTo(point);
|
|
else if (this.item) done = g.act(this.verb, h.id, this.item);
|
|
else if (this.verb) done = g.act(this.verb, h.id);
|
|
else done = g.act(g.defaultVerb(h.id), h.id);
|
|
this.reset();
|
|
return done ? (h ? 'act' : 'walk') : null;
|
|
}
|
|
|
|
clickItem(id, { look = false } = {}) {
|
|
const g = this.game;
|
|
if (g.skip()) return 'skip';
|
|
if (g.dialogue || g.busy) return null;
|
|
if (look) { this.reset(); return g.act('look', id) && 'act'; }
|
|
// Di nuovo sullo stesso oggetto: lo si usa da solo (bere la Coca, mangiare il ghiacciolo).
|
|
if (this.item) {
|
|
const ok = this.item === id ? this.verb === 'use' && g.act('use', id) : g.act('use', id, this.item);
|
|
this.reset();
|
|
return ok ? 'act' : null;
|
|
}
|
|
// Gli oggetti che si usano solo da soli (`alone`, le bibite) non chiedono «con cosa».
|
|
if ((!this.verb || this.verb === 'use') && g.story.items[id]?.alone) {
|
|
this.reset();
|
|
return g.act('use', id) && 'act';
|
|
}
|
|
if (!this.verb || this.verb === 'use' || this.verb === 'give') {
|
|
this.verb ??= 'use';
|
|
this.item = id;
|
|
return 'select';
|
|
}
|
|
const ok = g.act(this.verb, id);
|
|
this.reset();
|
|
return ok && 'act';
|
|
}
|
|
}
|