CHAT
TREE
can you make a 2 player game where you are squirles and you have machin guns and you fight dears
BUDDY
Heck yes — squirrels with machine guns vs deer is now a real game! Player 1 uses WASD to move and F to shoot, Player 2 uses arrow keys and / (slash) to shoot. Deer pop up and chase you — shoot them before they bonk you three times! Want me to add a score board or power-ups next?
CODE
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Squirrel Wars</title> <style> html, body { margin: 0; padding: 0; background: #7ec850; overflow: hidden; font-family: sans-serif; } #game { display: block; background: #a9dc76; margin: 0 auto; } #ui { position: absolute; top: 0; left: 0; width: 100%; text-align: center; color: white; font-size: 22px; font-weight: bold; text-shadow: 2px 2px 3px #333; pointer-events: none; } #banner { position: absolute; top: 40%; left: 50%; transform: translate(-50%, -50%); font-size: 48px; color: white; text-shadow: 3px 3px 5px black; text-align: center; display: none; } #restartBtn { display: none; position: absolute; top: 58%; left: 50%; transform: translate(-50%, -50%); font-size: 24px; padding: 10px 20px; border-radius: 12px; border: none; background: #ffcc33; cursor: pointer; } </style> </head> <body> <div id="ui"> <span id="p1score">P1 Squirrel: 3 lives</span> <span id="p2score">P2 Squirrel: 3 lives</span> </div> <div id="banner"></div> <button id="restartBtn" onclick="restartGame()">Play Again</button> <canvas id="game" width="900" height="600"></canvas> <script> const canvas = document.getElementById('game'); const ctx = canvas.getContext('2d'); const W = canvas.width, H = canvas.height; let keys = {}; window.addEventListener('keydown', e => { keys[e.key.toLowerCase()] = true; }); window.addEventListener('keyup', e => { keys[e.key.toLowerCase()] = false; }); function makePlayer(x, y, color, controls) { return { x, y, color, controls, w: 36, h: 36, speed: 4, lives: 3, dir: {x: 1, y: 0}, cooldown: 0, invuln: 0, alive: true }; } let p1 = makePlayer(150, 300, '#a0522d', {up:'w', down:'s', left:'a', right:'d', shoot:'f'}); let p2 = makePlayer(750, 300, '#8b4513', {up:'arrowup', down:'arrowdown', left:'arrowleft', right:'arrowright', shoot:'/'}); let bullets = []; let deer = []; let deerTimer = 0; let gameOver = false; function spawnDeer() { let side = Math.floor(Math.random()*4); let x, y; if (side === 0) { x = Math.random()*W; y = -30; } else if (side === 1) { x = Math.random()*W; y = H+30; } else if (side === 2) { x = -30; y = Math.random()*H; } else { x = W+30; y = Math.random()*H; } deer.push({ x, y, w: 40, h: 40, speed: 1 + Math.random()*1.2, hp: 3, hitFlash: 0 }); } function rectsOverlap(a, b) { return a.x - a.w/2 < b.x + b.w/2 && a.x + a.w/2 > b.x - b.w/2 && a.y - a.h/2 < b.y + b.h/2 && a.y + a.h/2 > b.y - b.h/2; } function updatePlayer(p) { if (!p.alive) return; let dx = 0, dy = 0; if (keys[p.controls.up]) dy -= 1; if (keys[p.controls.down]) dy += 1; if (keys[p.controls.left]) dx -= 1; if (keys[p.controls.right]) dx += 1; if (dx !== 0 || dy !== 0) { let len = Math.sqrt(dx*dx + dy*dy); dx /= len; dy /= len; p.dir = {x: dx, y: dy}; p.x += dx * p.speed; p.y += dy * p.speed; } p.x = Math.max(p.w/2, Math.min(W - p.w/2, p.x)); p.y = Math.max(p.h/2, Math.min(H - p.h/2, p.y)); if (p.cooldown > 0) p.cooldown--; if (p.invuln > 0) p.invuln--; if (keys[p.controls.shoot] && p.cooldown <= 0) { bullets.push({ x: p.x + p.dir.x * 20, y: p.y + p.dir.y * 20, vx: p.dir.x * 10, vy: p.dir.y * 10, owner: p }); p.cooldown = 8; } } function update() { if (gameOver) return; updatePlayer(p1); updatePlayer(p2); // bullets for (let i = bullets.length - 1; i >= 0; i--) { let b = bullets[i]; b.x += b.vx; b.y += b.vy; if (b.x < -20 || b.x > W+20 || b.y < -20 || b.y > H+20) { bullets.splice(i, 1); continue; } for (let j = deer.length - 1; j >= 0; j--) { let d = deer[j]; if (Math.abs(b.x - d.x) < d.w/2 && Math.abs(b.y - d.y) < d.h/2) { d.hp--; d.hitFlash = 6; bullets.splice(i, 1); if (d.hp <= 0) { deer.splice(j, 1); let scoreEl = b.owner === p1 ? p1 : p2; scoreEl.score = (scoreEl.score || 0) + 1; } break; } } } // deer movement deerTimer++; if (deerTimer > 60) { spawnDeer(); deerTimer = 0; } deer.forEach(d => { // chase nearest alive player let targets = [p1, p2].filter(p => p.alive); if (targets.length === 0) return; let target = targets[0]; if (targets.length === 2) { let d1 = Math.hypot(p1.x-d.x, p1.y-d.y); let d2 = Math.hypot(p2.x-d.x, p2.y-d.y); target = d1 < d2 ? p1 : p2; } let dx = target.x - d.x, dy = target.y - d.y; let len = Math.sqrt(dx*dx + dy*dy) || 1; d.x += (dx/len) * d.speed; d.y += (dy/len) * d.speed; if (d.hitFlash > 0) d.hitFlash--; // collide with players [p1, p2].forEach(p => { if (p.alive && p.invuln <= 0 && rectsOverlap(p, d)) { p.lives--; p.invuln = 60; d.x -= (dx/len) * 40; d.y -= (dy/len) * 40; if (p.lives <= 0) { p.alive = false; } } }); }); document.getElementById('p1score').textContent = 'P1 Squirrel: ' + Math.max(p1.lives,0) + ' lives'; document.getElementById('p2score').textContent = 'P2 Squirrel: ' + Math.max(p2.lives,0) + ' lives'; if (!p1.alive || !p2.alive) { gameOver = true; let banner = document.getElementById('banner'); banner.style.display = 'block'; if (!p1.alive && !p2.alive) banner.textContent = "Deer Win! Both squirrels down!"; else if (!p1.alive) banner.textContent = "Player 2 Wins!"; else banner.textContent = "Player 1 Wins!"; document.getElementById('restartBtn').style.display = 'block'; } } function drawSquirrel(p) { if (!p.alive) return; ctx.save(); if (p.invuln > 0 && Math.floor(p.invuln/5) % 2 === 0) { ctx.globalAlpha = 0.4; } ctx.translate(p.x, p.y); // body ctx.fillStyle = p.color; ctx.beginPath(); ctx.ellipse(0, 0, 16, 14, 0, 0, Math.PI*2); ctx.fill(); // head ctx.beginPath(); ctx.arc(p.dir.x*14, p.dir.y*14 - 4, 10, 0, Math.PI*2); ctx.fill(); // ears ctx.beginPath(); ctx.arc(p.dir.x*14 - 5, p.dir.y*14 - 12, 3, 0, Math.PI*2); ctx.arc(p.dir.x*14 + 5, p.dir.y*14 - 12, 3, 0, Math.PI*2); ctx.fill(); // tail ctx.fillStyle = p.color; ctx.beginPath(); ctx.ellipse(-p.dir.x*18, -p.dir.y*18, 14, 9, Math.atan2(p.dir.y, p.dir.x), 0, Math.PI*2); ctx.fill(); // gun ctx.fillStyle = '#333'; ctx.fillRect(p.dir.x*10, p.dir.y*10 - 3, 22, 6); ctx.restore(); } function drawDeer(d) { ctx.save(); ctx.translate(d.x, d.y); ctx.fillStyle = d.hitFlash > 0 ? '#ff5555' : '#c68642'; ctx.beginPath(); ctx.ellipse(0, 0, 16, 13, 0, 0, Math.PI*2); ctx.fill(); ctx.beginPath(); ctx.arc(0, -14, 9, 0, Math.PI*2); ctx.fill(); // antlers ctx.strokeStyle = '#7a5230'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(-5, -20); ctx.lineTo(-9, -28); ctx.moveTo(5, -20); ctx.lineTo(9, -28); ctx.stroke(); // hp bar ctx.fillStyle = 'black'; ctx.fillRect(-15, -30, 30, 4); ctx.fillStyle = 'lime'; ctx.fillRect(-15, -30, 30 * (d.hp/3), 4); ctx.restore(); } function drawBullets() { ctx.fillStyle = 'yellow'; bullets.forEach(b => { ctx.beginPath(); ctx.arc(b.x, b.y, 4, 0, Math.PI*2); ctx.fill(); }); } function draw() { ctx.clearRect(0, 0, W, H); // grass texture ctx.fillStyle = '#a9dc76'; ctx.fillRect(0, 0, W, H); ctx.strokeStyle = 'rgba(0,0,0,0.05)'; for (let i = 0; i < W; i += 40) { ctx.beginPath(); ctx.moveTo(i,0); ctx.lineTo(i,H); ctx.stroke(); } deer.forEach(drawDeer); drawBullets(); drawSquirrel(p1); drawSquirrel(p2); } function loop() { update(); draw(); requestAnimationFrame(loop); } function restartGame() { p1 = makePlayer(150, 300, '#a0522d', {up:'w', down:'s', left:'a', right:'d', shoot:'f'}); p2 = makePlayer(750, 300, '#8b4513', {up:'arrowup', down:'arrowdown', left:'arrowleft', right:'arrowright', shoot:'/'}); bullets = []; deer = []; deerTimer = 0; gameOver = false; document.getElementById('banner').style.display = 'none'; document.getElementById('restartBtn').style.display = 'none'; } loop(); </script> </body> </html>
PREVIEW
PICTURES0/50
No pictures yet. Add one, then ask your buddy to put it in your app!