feat: add ants with stomp-crush and collision heart damage
This commit is contained in:
parent
5de53553ca
commit
85e6d8290f
63
js/game.js
63
js/game.js
@ -25,6 +25,13 @@ const state = {
|
|||||||
stepCarry: 0,
|
stepCarry: 0,
|
||||||
cameraX: 0,
|
cameraX: 0,
|
||||||
hearts: 3,
|
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: {
|
player: {
|
||||||
x: 160,
|
x: 160,
|
||||||
y: 0,
|
y: 0,
|
||||||
@ -79,6 +86,22 @@ function drawTRex(p) {
|
|||||||
ctx.fillRect(sx + p.width - 24, p.y + p.height - 8, 14, 8);
|
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() {
|
function updateHeartsUI() {
|
||||||
heartsEl.textContent = '❤'.repeat(state.hearts) + '🖤'.repeat(Math.max(0, 3 - state.hearts));
|
heartsEl.textContent = '❤'.repeat(state.hearts) + '🖤'.repeat(Math.max(0, 3 - state.hearts));
|
||||||
}
|
}
|
||||||
@ -89,11 +112,44 @@ function kill(reason) {
|
|||||||
state.deadReason = 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) {
|
function isOverWater(player) {
|
||||||
const centerX = player.x + player.width / 2;
|
const centerX = player.x + player.width / 2;
|
||||||
return waterGaps.some((g) => centerX >= g.x && centerX <= g.x + g.width);
|
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) {
|
function updatePlayer(dt) {
|
||||||
const p = state.player;
|
const p = state.player;
|
||||||
let move = 0;
|
let move = 0;
|
||||||
@ -153,10 +209,15 @@ function tick(ts) {
|
|||||||
const dt = Math.min((ts - state.lastTs) / 1000, 0.05);
|
const dt = Math.min((ts - state.lastTs) / 1000, 0.05);
|
||||||
state.lastTs = ts;
|
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);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
drawBackground();
|
drawBackground();
|
||||||
|
drawAnts();
|
||||||
drawTRex(state.player);
|
drawTRex(state.player);
|
||||||
drawDeathText();
|
drawDeathText();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user