Spaces:
Running
Running
🐳 13/02 - 02:41 - Now make a red character that chases after you too. He steals your points, and wins if he takes all of the points off of the board by taking them from you. He cannot lose. You have
Browse files
game.js
CHANGED
|
@@ -12,6 +12,15 @@ const player = {
|
|
| 12 |
speed: 5
|
| 13 |
};
|
| 14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
const toppings = {
|
| 16 |
beef: [],
|
| 17 |
lettuce: [],
|
|
@@ -21,6 +30,7 @@ const toppings = {
|
|
| 21 |
let score = 0;
|
| 22 |
let lives = 3;
|
| 23 |
let gameRunning = true;
|
|
|
|
| 24 |
|
| 25 |
// Initialize game
|
| 26 |
function init() {
|
|
@@ -64,6 +74,25 @@ function movePlayer(e) {
|
|
| 64 |
player.y = Math.max(player.radius, Math.min(canvas.height - player.radius, player.y));
|
| 65 |
}
|
| 66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
function checkCollision() {
|
| 68 |
// Check beef collisions
|
| 69 |
for (let i = 0; i < toppings.beef.length; i++) {
|
|
@@ -100,11 +129,35 @@ function checkCollision() {
|
|
| 100 |
break;
|
| 101 |
}
|
| 102 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
|
| 104 |
// Check win/lose conditions
|
| 105 |
if (toppings.beef.length === 0) {
|
| 106 |
gameRunning = false;
|
| 107 |
-
alert('You won! Final score: ' + score);
|
|
|
|
|
|
|
|
|
|
| 108 |
} else if (lives <= 0) {
|
| 109 |
gameRunning = false;
|
| 110 |
alert('Game over! Final score: ' + score);
|
|
@@ -121,10 +174,42 @@ function draw() {
|
|
| 121 |
ctx.fillStyle = player.color;
|
| 122 |
ctx.fill();
|
| 123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
// Draw toppings
|
| 125 |
drawToppings(toppings.beef);
|
| 126 |
drawToppings(toppings.lettuce);
|
| 127 |
drawToppings(toppings.cheese);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
}
|
| 129 |
|
| 130 |
function drawToppings(toppingArray) {
|
|
@@ -139,6 +224,7 @@ function drawToppings(toppingArray) {
|
|
| 139 |
function gameLoop() {
|
| 140 |
if (!gameRunning) return;
|
| 141 |
|
|
|
|
| 142 |
draw();
|
| 143 |
checkCollision();
|
| 144 |
requestAnimationFrame(gameLoop);
|
|
|
|
| 12 |
speed: 5
|
| 13 |
};
|
| 14 |
|
| 15 |
+
const enemy = {
|
| 16 |
+
x: 50,
|
| 17 |
+
y: 50,
|
| 18 |
+
radius: 18,
|
| 19 |
+
color: '#DC143C',
|
| 20 |
+
speed: 2.5,
|
| 21 |
+
stolenScore: 0
|
| 22 |
+
};
|
| 23 |
+
|
| 24 |
const toppings = {
|
| 25 |
beef: [],
|
| 26 |
lettuce: [],
|
|
|
|
| 30 |
let score = 0;
|
| 31 |
let lives = 3;
|
| 32 |
let gameRunning = true;
|
| 33 |
+
const TOTAL_POINTS = 200; // 20 beef * 10 points each
|
| 34 |
|
| 35 |
// Initialize game
|
| 36 |
function init() {
|
|
|
|
| 74 |
player.y = Math.max(player.radius, Math.min(canvas.height - player.radius, player.y));
|
| 75 |
}
|
| 76 |
|
| 77 |
+
function moveEnemy() {
|
| 78 |
+
if (!gameRunning) return;
|
| 79 |
+
|
| 80 |
+
// Calculate direction to player
|
| 81 |
+
const dx = player.x - enemy.x;
|
| 82 |
+
const dy = player.y - enemy.y;
|
| 83 |
+
const distance = Math.hypot(dx, dy);
|
| 84 |
+
|
| 85 |
+
if (distance > 0) {
|
| 86 |
+
// Normalize and move towards player
|
| 87 |
+
enemy.x += (dx / distance) * enemy.speed;
|
| 88 |
+
enemy.y += (dy / distance) * enemy.speed;
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
// Boundary check
|
| 92 |
+
enemy.x = Math.max(enemy.radius, Math.min(canvas.width - enemy.radius, enemy.x));
|
| 93 |
+
enemy.y = Math.max(enemy.radius, Math.min(canvas.height - enemy.radius, enemy.y));
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
function checkCollision() {
|
| 97 |
// Check beef collisions
|
| 98 |
for (let i = 0; i < toppings.beef.length; i++) {
|
|
|
|
| 129 |
break;
|
| 130 |
}
|
| 131 |
}
|
| 132 |
+
|
| 133 |
+
// Check enemy collision with player
|
| 134 |
+
const enemyDist = Math.hypot(player.x - enemy.x, player.y - enemy.y);
|
| 135 |
+
if (enemyDist < player.radius + enemy.radius) {
|
| 136 |
+
// Enemy steals points from player
|
| 137 |
+
if (score > 0) {
|
| 138 |
+
const stealAmount = Math.min(10, score); // Steal up to 10 points at a time
|
| 139 |
+
score -= stealAmount;
|
| 140 |
+
enemy.stolenScore += stealAmount;
|
| 141 |
+
scoreElement.textContent = score;
|
| 142 |
+
|
| 143 |
+
// Push player away from enemy
|
| 144 |
+
const pushAngle = Math.atan2(player.y - enemy.y, player.x - enemy.x);
|
| 145 |
+
player.x += Math.cos(pushAngle) * 30;
|
| 146 |
+
player.y += Math.sin(pushAngle) * 30;
|
| 147 |
+
|
| 148 |
+
// Boundary check after push
|
| 149 |
+
player.x = Math.max(player.radius, Math.min(canvas.width - player.radius, player.x));
|
| 150 |
+
player.y = Math.max(player.radius, Math.min(canvas.height - player.radius, player.y));
|
| 151 |
+
}
|
| 152 |
+
}
|
| 153 |
|
| 154 |
// Check win/lose conditions
|
| 155 |
if (toppings.beef.length === 0) {
|
| 156 |
gameRunning = false;
|
| 157 |
+
alert('You won! Final score: ' + score + '\nEnemy stole: ' + enemy.stolenScore + ' points');
|
| 158 |
+
} else if (enemy.stolenScore >= TOTAL_POINTS) {
|
| 159 |
+
gameRunning = false;
|
| 160 |
+
alert('The Red Devourer wins!\nIt stole all ' + enemy.stolenScore + ' points from you!\nYour final score: ' + score);
|
| 161 |
} else if (lives <= 0) {
|
| 162 |
gameRunning = false;
|
| 163 |
alert('Game over! Final score: ' + score);
|
|
|
|
| 174 |
ctx.fillStyle = player.color;
|
| 175 |
ctx.fill();
|
| 176 |
|
| 177 |
+
// Draw enemy
|
| 178 |
+
ctx.beginPath();
|
| 179 |
+
ctx.arc(enemy.x, enemy.y, enemy.radius, 0, Math.PI * 2);
|
| 180 |
+
ctx.fillStyle = enemy.color;
|
| 181 |
+
ctx.fill();
|
| 182 |
+
|
| 183 |
+
// Draw enemy eyes
|
| 184 |
+
ctx.fillStyle = 'white';
|
| 185 |
+
ctx.beginPath();
|
| 186 |
+
ctx.arc(enemy.x - 6, enemy.y - 4, 4, 0, Math.PI * 2);
|
| 187 |
+
ctx.arc(enemy.x + 6, enemy.y - 4, 4, 0, Math.PI * 2);
|
| 188 |
+
ctx.fill();
|
| 189 |
+
ctx.fillStyle = 'black';
|
| 190 |
+
ctx.beginPath();
|
| 191 |
+
ctx.arc(enemy.x - 6, enemy.y - 4, 2, 0, Math.PI * 2);
|
| 192 |
+
ctx.arc(enemy.x + 6, enemy.y - 4, 2, 0, Math.PI * 2);
|
| 193 |
+
ctx.fill();
|
| 194 |
+
|
| 195 |
// Draw toppings
|
| 196 |
drawToppings(toppings.beef);
|
| 197 |
drawToppings(toppings.lettuce);
|
| 198 |
drawToppings(toppings.cheese);
|
| 199 |
+
|
| 200 |
+
// Draw enemy threat meter
|
| 201 |
+
ctx.fillStyle = 'rgba(220, 20, 60, 0.3)';
|
| 202 |
+
ctx.fillRect(canvas.width - 210, 10, 200, 20);
|
| 203 |
+
ctx.fillStyle = '#DC143C';
|
| 204 |
+
const threatWidth = (enemy.stolenScore / TOTAL_POINTS) * 200;
|
| 205 |
+
ctx.fillRect(canvas.width - 210, 10, threatWidth, 20);
|
| 206 |
+
ctx.strokeStyle = '#8B4513';
|
| 207 |
+
ctx.lineWidth = 2;
|
| 208 |
+
ctx.strokeRect(canvas.width - 210, 10, 200, 20);
|
| 209 |
+
ctx.fillStyle = '#8B4513';
|
| 210 |
+
ctx.font = 'bold 14px Arial';
|
| 211 |
+
ctx.textAlign = 'center';
|
| 212 |
+
ctx.fillText('ENEMY THREAT: ' + enemy.stolenScore + '/' + TOTAL_POINTS, canvas.width - 110, 25);
|
| 213 |
}
|
| 214 |
|
| 215 |
function drawToppings(toppingArray) {
|
|
|
|
| 224 |
function gameLoop() {
|
| 225 |
if (!gameRunning) return;
|
| 226 |
|
| 227 |
+
moveEnemy();
|
| 228 |
draw();
|
| 229 |
checkCollision();
|
| 230 |
requestAnimationFrame(gameLoop);
|
style.css
CHANGED
|
@@ -32,3 +32,11 @@ body {
|
|
| 32 |
font-weight: bold;
|
| 33 |
font-size: 18px;
|
| 34 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
font-weight: bold;
|
| 33 |
font-size: 18px;
|
| 34 |
}
|
| 35 |
+
|
| 36 |
+
.game-info::after {
|
| 37 |
+
content: "Avoid the Red Devourer!";
|
| 38 |
+
display: block;
|
| 39 |
+
color: #DC143C;
|
| 40 |
+
font-size: 14px;
|
| 41 |
+
margin-top: 5px;
|
| 42 |
+
}
|