Answer the playtest: a net for the lock, and a duel that pays
The hang: I could not reproduce it or pin it on one latch, so this is two things. A root-cause fix — iOS does not guarantee a touchend when you switch apps mid-drag, and the held G.aim it leaves behind blocks the uncaught-toss retoss forever — and a watchdog for whatever else is out there. The watchdog does not time how long you have been blocked, because a horde blocks you for fifteen honest seconds; it watches whether the clock that should release you is moving, and logs the frozen state before letting go. The duel: past about game 20 all four tins sit at wCap and a won duel handed over literally nothing. It falls through to the barrel weapons now. The prize also stops borrowing the praise channel — arriving in the same slot as PERFECT made it read as another compliment. It gets a card with its own icon. The turn into zombie mode was unwatchable because the zoom started ON it, and the curve render applies is zero at t=0, so the camera only arrived half a second after he had changed. It peaks on the turn now, and the swap lands on a hitstop, a flash and a burst so it reads as an event rather than a glitch. Laser down from 0.55 to 0.22 — zap() sums four voices, so its vol was never one voice's level. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
20a742fbf3
commit
a1a8a61422
7 files changed
+130
-17
No files matched your search
@@ -1050,11 +1050,19 @@ function drawRack() {
|
||||
|
||||
// the centered milestone 'block': a real pause, front and center. Shared by the sudden-death duel
|
||||
// and the SET announcement so both read as the same interruption. Assumes textAlign is already set.
|
||||
function drawCard(title, sub1, sub2, color) {
|
||||
function drawCard(title, sub1, sub2, color, icon) {
|
||||
// 80 tall, not 72: the second sub line ends at H/2+26 and the band used to stop at +30, so it sat
|
||||
// all but touching the edge. The band now clears it by 10 px, the same air it has at the top.
|
||||
ctx.fillStyle = 'rgba(10,6,8,0.66)'; ctx.fillRect(0, H / 2 - 44, W, 80);
|
||||
// An ICON (the won-duel tin) needs its own room above the title, so the band grows for it rather
|
||||
// than the art crowding the type.
|
||||
const img = icon && SPR[icon], ih = img ? 34 : 0;
|
||||
ctx.fillStyle = 'rgba(10,6,8,0.66)'; ctx.fillRect(0, H / 2 - 44 - ih, W, 80 + ih);
|
||||
ctx.textAlign = 'center';
|
||||
if (img) { // the tin itself, at its own aspect, sat on the title
|
||||
const w = Math.round(img.width * (ih - 6) / img.height);
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
ctx.drawImage(img, Math.round(W / 2 - w / 2), Math.round(H / 2 - 44 - ih + 3), w, ih - 6);
|
||||
}
|
||||
// the title SHOUTS (Bangers, twice the old size); the subs stay Silkscreen, because they are the
|
||||
// detail you read second and a whole card in the loud face is just noise
|
||||
ctx.font = B(30); shadowText(title, W / 2, H / 2 - 34, color);
|
||||
@@ -1623,7 +1631,7 @@ export function render() {
|
||||
}
|
||||
// the SET milestone card (the duel's own announcement is a real modal now, not a timed card)
|
||||
if (G.card && G.card.t > 0 && !(G.card.wait > 0)) // `wait` holds it OFF the screen (a boss dying under it)
|
||||
drawCard(G.card.title, G.card.sub1, G.card.sub2, G.card.color);
|
||||
drawCard(G.card.title, G.card.sub1, G.card.sub2, G.card.color, G.card.icon);
|
||||
if (TUNE.missHud && G.lastMiss && G.idleT - G.lastMiss.at < 3.5) { // last miss reason, live
|
||||
ctx.font = F(8); ctx.fillStyle = '#ff9060';
|
||||
ctx.fillText(G.lastMiss.text.toUpperCase(), W / 2, H - 28);
|
||||
|
||||
Reference in new issue
Block a user