diffs / #2
feat(#2): the cat
Requested-by: SEED (built by us pre-launch)
+ BUILD+ UNIT TESTS+ LINT+ DIFF GATE+ PAGE CLASSIFIER+ PLAYWRIGHT
src/player.jsNEW+26 −0
| 1 | +// Seed #2: the white pixel cat. Arrows/WASD to move, Space/Up to jump, E/Down at a door. | ||
| 2 | +import { blit } from "./sprites.js"; | ||
| 3 | +import { solidBelow } from "./world.js"; | ||
| 4 | +export const SPEED = 82, JUMP = 205, GRAV = 560; | ||
| 5 | +export function makePlayer() { | ||
| 6 | + return { | ||
| 7 | + x: 24, y: 40, vx: 0, vy: 0, f: 1, onGround: false, walk: 0, emote: null, emoteT: 0, jumps: 1, | ||
| 8 | + update(dt, w, input) { | ||
| 9 | + const dir = (input.held("right") ? 1 : 0) - (input.held("left") ? 1 : 0); | ||
| 10 | + this.vx = dir * SPEED; if (dir) this.f = dir; | ||
| 11 | + this.walk = dir && this.onGround ? this.walk + dt : 0; | ||
| 12 | + if (input.take("jump") && (this.onGround || this.jumpsLeft > 0)) { if (!this.onGround) this.jumpsLeft--; this.vy = -JUMP; this.onGround = false; } | ||
| 13 | + for (let i = 0; i < 4; i++) if (input.take("e" + i)) { this.emote = i; this.emoteT = 2; } | ||
| 14 | + this.emoteT = Math.max(0, this.emoteT - dt); if (!this.emoteT) this.emote = null; | ||
| 15 | + this.vy = Math.min(320, this.vy + GRAV * dt); | ||
| 16 | + const ny = this.y + this.vy * dt; | ||
| 17 | + const floor = this.vy >= 0 ? solidBelow(w.level, this.x, this.y - 0.01, ny) : null; | ||
| 18 | + if (floor != null) { this.y = floor; this.vy = 0; this.onGround = true; this.jumpsLeft = this.jumps - 1; } else { this.y = ny; this.onGround = false; } | ||
| 19 | + this.x += this.vx * dt; | ||
| 20 | + }, | ||
| 21 | + draw(g) { | ||
| 22 | + blit(g, Math.floor(this.walk * 8) % 2 ? "catWalk" : "cat", this.x - 6, this.y - 11, this.f < 0); | ||
| 23 | + if (this.emote != null) blit(g, ["heart", "wave", "bang", "ask"][this.emote], this.x - 2, this.y - 19); | ||
| 24 | + }, | ||
| 25 | + }; | ||
| 26 | +} |
1+// Seed #2: the white pixel cat. Arrows/WASD to move, Space/Up to jump, E/Down at a door.
2+import { blit } from "./sprites.js";
3+import { solidBelow } from "./world.js";
4+export const SPEED = 82, JUMP = 205, GRAV = 560;
5+export function makePlayer() {
6+ return {
7+ x: 24, y: 40, vx: 0, vy: 0, f: 1, onGround: false, walk: 0, emote: null, emoteT: 0, jumps: 1,
8+ update(dt, w, input) {
9+ const dir = (input.held("right") ? 1 : 0) - (input.held("left") ? 1 : 0);
10+ this.vx = dir * SPEED; if (dir) this.f = dir;
11+ this.walk = dir && this.onGround ? this.walk + dt : 0;
12+ if (input.take("jump") && (this.onGround || this.jumpsLeft > 0)) { if (!this.onGround) this.jumpsLeft--; this.vy = -JUMP; this.onGround = false; }
13+ for (let i = 0; i < 4; i++) if (input.take("e" + i)) { this.emote = i; this.emoteT = 2; }
14+ this.emoteT = Math.max(0, this.emoteT - dt); if (!this.emoteT) this.emote = null;
15+ this.vy = Math.min(320, this.vy + GRAV * dt);
16+ const ny = this.y + this.vy * dt;
17+ const floor = this.vy >= 0 ? solidBelow(w.level, this.x, this.y - 0.01, ny) : null;
18+ if (floor != null) { this.y = floor; this.vy = 0; this.onGround = true; this.jumpsLeft = this.jumps - 1; } else { this.y = ny; this.onGround = false; }
19+ this.x += this.vx * dt;
20+ },
21+ draw(g) {
22+ blit(g, Math.floor(this.walk * 8) % 2 ? "catWalk" : "cat", this.x - 6, this.y - 11, this.f < 0);
23+ if (this.emote != null) blit(g, ["heart", "wave", "bang", "ask"][this.emote], this.x - 2, this.y - 19);
24+ },
25+ };
26+}


CI log tail
$ ci:build (850 ms, exit 0) $ ci:test (165 ms, exit 0) TAP version 13 # Subtest: palette: valid hex, at most 40 colours ok 1 - palette: valid hex, at most 40 colours --- duration_ms: 0.925623 type: 'test' ... # Subtest: sprites: rectangular-ish rows of known keys ok 2 - sprites: rectangular-ish rows of known keys --- duration_ms: 1.252025 type: 'test' ... # Subtest: levels: every room has a name, platforms and a draw function ok 3 - levels: every room has a name, platforms and a draw function --- duration_ms: 1.209405 type: 'test' ... # Subtest: bosses: every file exports a class with update/draw ok 4 - bosses: every file exports a class with update/draw --- duration_ms: 3.314907 type: 'test' ... # Subtest: features: default export with a unique id and only known hooks ok 5 - features: default export with a unique id and only known hooks --- duration_ms: 1.5381 type: 'test' ... # Subtest: no network, storage or parent access anywhere in src ok 6 - no network, storage or parent access anywhere in src --- duration_ms: 1.040648 type: 'test' ... 1..6 # tests 6 # suites 0 # pass 6 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 99.213971 $ ci:lint (493 ms, exit 0) $ playwright 960x540 fps 60 long tasks 0 console errors 0