feat: unlock pterodactyl hazards after score threshold and duck avoidance

This commit is contained in:
OpenClaw Engineer 2026-03-03 20:41:18 -06:00
parent 85e6d8290f
commit 9394d2b9f3

View File

@ -32,6 +32,8 @@ const state = {
{ x: 2600, y: groundY - 20, width: 22, height: 20, vx: -80, alive: true },
{ x: 3400, y: groundY - 20, width: 22, height: 20, vx: -75, alive: true }
],
pterodactyls: [],
pteroSpawnTimer: 0,
player: {
x: 160,
y: 0,
@ -98,6 +100,17 @@ function drawAnts() {
}
}
function drawPterodactyls() {
ctx.fillStyle = '#6e5a8a';
for (const p of state.pterodactyls) {
const sx = p.x - state.cameraX;
if (sx + p.width < 0 || sx > canvas.width) continue;
ctx.fillRect(sx, p.y, p.width, p.height);
ctx.fillRect(sx - 8, p.y + 6, 8, 4);
ctx.fillRect(sx + p.width, p.y + 6, 8, 4);
}
}
function intersects(a, b) {
return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y;
}
@ -150,6 +163,32 @@ function updateAnts(dt) {
}
}
function updatePterodactyls(dt) {
if (state.score <= 100) return;
state.pteroSpawnTimer -= dt;
if (state.pteroSpawnTimer <= 0) {
const altitude = groundY - (state.player.standingHeight - 24);
state.pterodactyls.push({
x: state.cameraX + canvas.width + 80,
y: altitude,
width: 54,
height: 26,
vx: -280
});
state.pteroSpawnTimer = 2.2;
}
const p = state.player;
for (const flyer of state.pterodactyls) {
flyer.x += flyer.vx * dt;
if (intersects(p, flyer)) {
applyHit('Pterodactyl collision. Duck next time!');
}
}
state.pterodactyls = state.pterodactyls.filter((f) => f.x + f.width > state.cameraX - 150);
}
function updatePlayer(dt) {
const p = state.player;
let move = 0;
@ -213,11 +252,13 @@ function tick(ts) {
state.hitCooldown = Math.max(0, state.hitCooldown - dt);
updatePlayer(dt);
updateAnts(dt);
updatePterodactyls(dt);
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBackground();
drawAnts();
drawPterodactyls();
drawTRex(state.player);
drawDeathText();