Lavori in corso (non pubblicati): Bertovo al tavolo di mezzo coi rinquarti (Codex), Bini, Yuri, il Gianno e la Brauda in gara, l'Audi «Let it be», sensibilità e riquadro dello swipe, pulsanti su iPhone (Andrea)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GiECdCPptNRwbVzjzHbohi
This commit is contained in:
+40
-29
@@ -1,6 +1,6 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { newGara, update, press, presenting, INTRO, release, cancel, shoot, key, steerButton, brakeButton, aimScreen, steering, status, button, standings, player, rider, limitAt, pointAt, TRACK, CURVES, PICKUPS, BRAKE, VERGE, LAPS, COUNTDOWN, RIDERS } from '../src/engine/gara.js';
|
||||
import { SWIPE, setPower, newGara, update, press, presenting, INTRO, release, cancel, shoot, key, steerButton, brakeButton, aimScreen, steering, status, button, standings, player, rider, limitAt, pointAt, TRACK, CURVES, PICKUPS, BRAKE, VERGE, LAPS, COUNTDOWN, RIDERS } from '../src/engine/gara.js';
|
||||
import { piloti } from '../src/story/piloti.js';
|
||||
import { story } from '../src/story/story.js';
|
||||
import { Game } from '../src/engine/game.js';
|
||||
@@ -17,6 +17,8 @@ const run = (c, seconds, drive, dt = 1 / 60) => {
|
||||
return c.heard;
|
||||
};
|
||||
const skip = c => { while (c.step === 'intro') press(c); return c; };
|
||||
// Lo sterzo col dito insegue quello voluto: per leggerlo si lascia assestare.
|
||||
const settled = c => { for (let i = 0; i < 400; i++) steering(c); return steering(c); };
|
||||
const race = c => { skip(c); assert.equal(c.step, 'start'); run(c, COUNTDOWN + 0.01); assert.equal(c.step, 'race'); return c; };
|
||||
// Un dito al centro della scena indica la direzione del punto davanti al motorino.
|
||||
const swipeTo = (c, target) => {
|
||||
@@ -93,73 +95,73 @@ test('le fonti del gas sono indipendenti: lasciare un tasto non toglie quello de
|
||||
});
|
||||
|
||||
test('lo sterzo: frecce, pulsanti e il dito che trascina; il mouse che passa senza premere non sterza', () => {
|
||||
const c = race(newGara(3, { riders: RIDERS }));
|
||||
assert.ok(key(c, 'ArrowLeft', true)); assert.equal(steering(c), -1);
|
||||
key(c, 'ArrowLeft', false); assert.equal(steering(c), 0);
|
||||
steerButton(c, 1); assert.equal(steering(c), 1); steerButton(c, 0);
|
||||
const c = race(newGara(3, { riders: RIDERS })); setPower(c, 1);
|
||||
assert.ok(key(c, 'ArrowLeft', true)); assert.equal(settled(c), -1);
|
||||
key(c, 'ArrowLeft', false); assert.equal(settled(c), 0);
|
||||
steerButton(c, 1); assert.equal(settled(c), 1); steerButton(c, 0);
|
||||
// Gas da tastiera e sinistra, il mouse si muove a destra senza premere: lo sterzo resta a sinistra (P1).
|
||||
key(c, 'ArrowUp', true); key(c, 'ArrowLeft', true);
|
||||
aimScreen(c, [300, 100], 5); aimScreen(c, [360, 100], 5);
|
||||
assert.equal(steering(c), -1);
|
||||
assert.equal(settled(c), -1);
|
||||
key(c, 'ArrowUp', false); key(c, 'ArrowLeft', false);
|
||||
// Il dito indica una direzione; un altro puntatore non sposta niente.
|
||||
player(c).a = -0.5 / 2.6;
|
||||
player(c).a = -0.5 / SWIPE.hard;
|
||||
aimScreen(c, [300, 100], 9); press(c, 9);
|
||||
aimScreen(c, [314, 100], 9); assert.ok(Math.abs(steering(c) - 0.5) < 1e-10);
|
||||
aimScreen(c, [250, 100], 4); assert.ok(Math.abs(steering(c) - 0.5) < 1e-10);
|
||||
release(c, 9); assert.equal(steering(c), 0, 'lasciando il dito lo sterzo torna dritto');
|
||||
aimScreen(c, [314, 100], 9); assert.ok(Math.abs(settled(c) - 0.5) < 1e-6);
|
||||
aimScreen(c, [250, 100], 4); assert.ok(Math.abs(settled(c) - 0.5) < 1e-6);
|
||||
release(c, 9); assert.equal(settled(c), 0, 'lasciando il dito lo sterzo torna dritto');
|
||||
const a = player(c).a; key(c, 'ArrowUp', true); key(c, 'ArrowRight', true); run(c, 0.4); assert.notEqual(player(c).a, a, 'sterzando si gira');
|
||||
assert.equal(key(c, 'x', true), false, 'gli altri tasti non sono suoi');
|
||||
});
|
||||
|
||||
test('lo swipe segue lo schermo: scendendo, destra sterza negativo; avanti e piccoli movimenti vanno dritto', () => {
|
||||
const c = race(newGara(3)), r = player(c);
|
||||
const c = race(newGara(3)), r = player(c); setPower(c, 1);
|
||||
r.a = Math.PI / 2;
|
||||
aimScreen(c, [320, 180], 9); press(c, 9);
|
||||
aimScreen(c, [370, 180], 9);
|
||||
assert.equal(steering(c), -1, 'scendendo, la destra dello schermo è a sinistra del motorino');
|
||||
assert.equal(settled(c), -1, 'scendendo, la destra dello schermo è a sinistra del motorino');
|
||||
r.a = 0;
|
||||
assert.ok(Math.abs(steering(c)) < 1e-10, 'col dito fermo lo sterzo si annulla quando il motorino è allineato');
|
||||
assert.ok(Math.abs(settled(c)) < 1e-6, 'col dito fermo lo sterzo si annulla quando il motorino è allineato');
|
||||
r.a = Math.PI / 2;
|
||||
aimScreen(c, [320, 230], 9); assert.ok(Math.abs(steering(c)) < 1e-10, 'swipe in avanti');
|
||||
aimScreen(c, [323, 184], 9); assert.equal(steering(c), 0, '5 px non fanno tremare lo sterzo');
|
||||
aimScreen(c, [320, 230], 9); assert.ok(Math.abs(settled(c)) < 1e-6, 'swipe in avanti');
|
||||
aimScreen(c, [323, 184], 9); assert.equal(settled(c), 0, '5 px non fanno tremare lo sterzo');
|
||||
aimScreen(c, [330, 230], 9);
|
||||
assert.ok(Math.abs(steering(c) + Math.atan2(10, 50) * 2.6) < 1e-10, 'sterzo proporzionale all’angolo');
|
||||
assert.ok(Math.abs(settled(c) + Math.atan2(10, 50) * SWIPE.hard) < 1e-6, 'sterzo proporzionale all’angolo');
|
||||
r.a = -Math.PI + 0.1;
|
||||
aimScreen(c, [270, 180], 9);
|
||||
assert.ok(Math.abs(steering(c) + 0.26) < 1e-10, 'si gira dalla parte più breve anche passando da π a -π');
|
||||
assert.ok(Math.abs(settled(c) + 0.1 * SWIPE.hard) < 1e-6, 'si gira dalla parte più breve anche passando da π a -π');
|
||||
release(c, 9);
|
||||
assert.equal(c.holding, false); assert.equal(steering(c), 0);
|
||||
assert.equal(c.holding, false); assert.equal(settled(c), 0);
|
||||
assert.equal(c.anchor, null); assert.equal(c.finger, null);
|
||||
});
|
||||
|
||||
test('l’origine segue gli swipe lunghi e si può correggere; rilascio e annullamento puliscono il dito', () => {
|
||||
const c = race(newGara(3));
|
||||
const c = race(newGara(3)); setPower(c, 1);
|
||||
player(c).a = 0;
|
||||
aimScreen(c, [100, 100], 9); press(c, 9);
|
||||
for (const x of [200, 300, 400]) {
|
||||
aimScreen(c, [x, 100], 9);
|
||||
assert.deepEqual(c.anchor, [x - 60, 100]);
|
||||
assert.ok(Math.abs(steering(c)) < 1e-10);
|
||||
assert.ok(Math.abs(settled(c)) < 1e-6);
|
||||
}
|
||||
aimScreen(c, [400, 160], 9);
|
||||
assert.ok(Math.abs(Math.hypot(c.finger[0] - c.anchor[0], c.finger[1] - c.anchor[1]) - 60) < 1e-10);
|
||||
assert.equal(steering(c), 1, 'si corregge verso il basso senza arrivare al bordo');
|
||||
assert.ok(Math.abs(Math.hypot(c.finger[0] - c.anchor[0], c.finger[1] - c.anchor[1]) - 60) < 1e-6);
|
||||
assert.equal(settled(c), 1, 'si corregge verso il basso senza arrivare al bordo');
|
||||
key(c, 'ArrowLeft', true); shoot(c); brakeButton(c, true);
|
||||
release(c, 9);
|
||||
assert.equal(steering(c), -1, 'lasciare il dito conserva lo sterzo della tastiera');
|
||||
assert.equal(settled(c), -1, 'lasciare il dito conserva lo sterzo della tastiera');
|
||||
assert.ok(c.holding && c.braking, 'Gas e Frena del pannello restano attivi');
|
||||
key(c, 'ArrowDown', true); brakeButton(c, false);
|
||||
assert.ok(c.braking, 'il freno della tastiera resta attivo');
|
||||
aimScreen(c, [200, 200], 10); press(c, 10);
|
||||
assert.equal(c.drag, 0, 'il nuovo tocco non eredita lo swipe');
|
||||
cancel(c);
|
||||
assert.equal(c.holding, false); assert.equal(c.braking, false); assert.equal(steering(c), 0);
|
||||
assert.equal(c.holding, false); assert.equal(c.braking, false); assert.equal(settled(c), 0);
|
||||
assert.equal(c.anchor, null); assert.equal(c.finger, null);
|
||||
});
|
||||
|
||||
test('alla bona si completano tre giri usando solo un dito, senza tasti o pulsanti', () => {
|
||||
const c = race(newGara(5, { level: 'bona', riders: piloti }));
|
||||
const c = race(newGara(5, { level: 'bona', riders: piloti.filter(p => p.consenso !== null) }));
|
||||
aimScreen(c, [320, 180], 'bot'); press(c, 'bot');
|
||||
for (let t = 0; t < 180 && c.step === 'race'; t += 1 / 60) {
|
||||
swipeTo(c, pointAt(player(c).s + 50));
|
||||
@@ -196,7 +198,7 @@ test('la presentazione: uno alla volta arrivano in griglia col motorino, poi il
|
||||
});
|
||||
|
||||
test('sempre a gas e dritto si finisce nella paglia; con giudizio alla bona si vince', () => {
|
||||
const wild = newGara(5, { level: 'bona', riders: piloti });
|
||||
const wild = newGara(5, { level: 'bona', riders: piloti.filter(p => p.consenso !== null) });
|
||||
skip(wild);
|
||||
run(wild, COUNTDOWN + 60, () => true);
|
||||
assert.ok(wild.heard.has('gara-fuori:andrea'));
|
||||
@@ -204,17 +206,26 @@ test('sempre a gas e dritto si finisce nella paglia; con giudizio alla bona si v
|
||||
assert.equal(wild.step, 'race', 'dritto non si arriva');
|
||||
const heard = new Set();
|
||||
for (const seed of [1, 2, 3, 4]) {
|
||||
const c = newGara(seed, { level: 'bona', riders: piloti });
|
||||
skip(c);
|
||||
const c = newGara(seed, { level: 'bona', riders: piloti.filter(p => p.consenso !== null) });
|
||||
skip(c); setPower(c, 1); // a sensibilità piena: il dito risponde subito
|
||||
for (const k of run(c, COUNTDOWN + 120, careful)) heard.add(k);
|
||||
assert.equal(c.step, 'result'); assert.equal(c.result.winner, 'player', `seme ${seed}`);
|
||||
assert.equal(c.result.order[0], 'andrea'); assert.match(status(c), /Primo al GP di Fortezza!/);
|
||||
assert.equal(Object.keys(c.result.times).length, piloti.length);
|
||||
assert.equal(Object.keys(c.result.times).length, piloti.filter(p => p.consenso !== null).length);
|
||||
}
|
||||
assert.ok(['gara-giro:andrea', 'gara-arrivo:andrea', 'gara-turbo:andrea', 'gara-miscela:andrea'].every(k => heard.has(k)), [...heard].join());
|
||||
assert.ok(CURVES.length >= 2 && TRACK.length > 600, 'una pista con delle curve vere');
|
||||
});
|
||||
|
||||
test('alla sensibilità di partenza (bassa) lo stesso pilota non finisce mai nella paglia', () => {
|
||||
for (const seed of [1, 2, 3]) {
|
||||
const c = newGara(seed, { level: 'bona', riders: piloti.filter(p => p.consenso !== null) });
|
||||
skip(c); assert.equal(c.sens, SWIPE.sens);
|
||||
run(c, COUNTDOWN + 120, careful);
|
||||
assert.equal(c.step, 'result'); assert.equal(c.result.offs, 0, `seme ${seed}`);
|
||||
}
|
||||
});
|
||||
|
||||
test('le buche: piano si sobbalza, forte si casca; la lattina di miscela dà lo sprint', () => {
|
||||
const hole = PICKUPS.find(p => p.kind === 'buca'), can = PICKUPS.find(p => p.kind === 'miscela');
|
||||
for (const [speed, fell] of [[20, false], [80, true]]) {
|
||||
|
||||
Reference in New Issue
Block a user