diff --git a/js/game.js b/js/game.js index efe280d..7a69b12 100644 --- a/js/game.js +++ b/js/game.js @@ -25,6 +25,13 @@ const state = { stepCarry: 0, cameraX: 0, hearts: 3, + hitCooldown: 0, + ants: [ + { x: 1000, y: groundY - 20, width: 22, height: 20, vx: -65, alive: true }, + { x: 1750, y: groundY - 20, width: 22, height: 20, vx: -70, alive: true }, + { 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 } + ], player: { x: 160, y: 0, @@ -79,6 +86,22 @@ function drawTRex(p) { ctx.fillRect(sx + p.width - 24, p.y + p.height - 8, 14, 8); } +function drawAnts() { + ctx.fillStyle = '#5a1e0d'; + for (const ant of state.ants) { + if (!ant.alive) continue; + const sx = ant.x - state.cameraX; + if (sx + ant.width < 0 || sx > canvas.width) continue; + ctx.fillRect(sx, ant.y, ant.width, ant.height); + ctx.fillRect(sx - 4, ant.y + 6, 4, 4); + ctx.fillRect(sx + ant.width, ant.y + 6, 4, 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; +} + function updateHeartsUI() { heartsEl.textContent = '❤'.repeat(state.hearts) + '🖤'.repeat(Math.max(0, 3 - state.hearts)); } @@ -89,11 +112,44 @@ function kill(reason) { state.deadReason = reason; } +function applyHit(reason) { + if (state.hitCooldown > 0 || state.dead) return; + state.hearts -= 1; + state.hitCooldown = 1.0; + if (state.hearts <= 0) { + kill(reason); + } +} + function isOverWater(player) { const centerX = player.x + player.width / 2; return waterGaps.some((g) => centerX >= g.x && centerX <= g.x + g.width); } +function updateAnts(dt) { + const p = state.player; + const prevBottom = p.y + p.height - p.vy * dt; + + for (const ant of state.ants) { + if (!ant.alive) continue; + + ant.x += ant.vx * dt; + if (ant.x < 200) ant.vx = Math.abs(ant.vx); + if (ant.x > worldWidth - 200) ant.vx = -Math.abs(ant.vx); + + if (intersects(p, ant)) { + const playerBottom = p.y + p.height; + const stomped = p.vy > 0 && prevBottom <= ant.y + 4 && playerBottom >= ant.y; + if (stomped) { + ant.alive = false; + p.vy = -380; + } else { + applyHit('A swarm of ants got you.'); + } + } + } +} + function updatePlayer(dt) { const p = state.player; let move = 0; @@ -153,10 +209,15 @@ function tick(ts) { const dt = Math.min((ts - state.lastTs) / 1000, 0.05); state.lastTs = ts; - if (state.running) updatePlayer(dt); + if (state.running) { + state.hitCooldown = Math.max(0, state.hitCooldown - dt); + updatePlayer(dt); + updateAnts(dt); + } ctx.clearRect(0, 0, canvas.width, canvas.height); drawBackground(); + drawAnts(); drawTRex(state.player); drawDeathText();