189 lines
4.7 KiB
JavaScript
189 lines
4.7 KiB
JavaScript
|
document.addEventListener('DOMContentLoaded', () => {
|
||
|
const canvas = document.getElementById('gameCanvas');
|
||
|
const ctx = canvas.getContext('2d');
|
||
|
|
||
|
let score = 0;
|
||
|
let gameOver = false;
|
||
|
|
||
|
class Cookie {
|
||
|
constructor(x, y, size) {
|
||
|
this.x = x;
|
||
|
this.y = y;
|
||
|
this.size = size;
|
||
|
this.speed = Math.random() * 0.5 + 0.2; // Reduced speed range
|
||
|
this.angle = Math.random() * Math.PI * 2;
|
||
|
this.image = new Image();
|
||
|
this.image.src = '/assets/images/cookie.png';
|
||
|
}
|
||
|
|
||
|
update() {
|
||
|
this.x += Math.cos(this.angle) * this.speed;
|
||
|
this.y += Math.sin(this.angle) * this.speed;
|
||
|
|
||
|
if (this.x < 0) this.x = canvas.width;
|
||
|
if (this.x > canvas.width) this.x = 0;
|
||
|
if (this.y < 0) this.y = canvas.height;
|
||
|
if (this.y > canvas.height) this.y = 0;
|
||
|
}
|
||
|
|
||
|
draw() {
|
||
|
ctx.drawImage(this.image, this.x - this.size / 2, this.y - this.size / 2, this.size, this.size);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class Ship {
|
||
|
constructor() {
|
||
|
this.x = canvas.width / 2;
|
||
|
this.y = canvas.height / 2;
|
||
|
this.angle = 0;
|
||
|
this.size = 40;
|
||
|
this.image = new Image();
|
||
|
this.image.src = '/assets/images/monster.png';
|
||
|
this.speed = 0;
|
||
|
this.rotationSpeed = 0.2; // Increased rotation speed
|
||
|
}
|
||
|
|
||
|
update() {
|
||
|
this.x += Math.cos(this.angle) * this.speed;
|
||
|
this.y += Math.sin(this.angle) * this.speed;
|
||
|
|
||
|
if (this.x < 0) this.x = canvas.width;
|
||
|
if (this.x > canvas.width) this.x = 0;
|
||
|
if (this.y < 0) this.y = canvas.height;
|
||
|
if (this.y > canvas.height) this.y = 0;
|
||
|
|
||
|
this.speed *= 0.98; // Add friction
|
||
|
}
|
||
|
|
||
|
draw() {
|
||
|
ctx.save();
|
||
|
ctx.translate(this.x, this.y);
|
||
|
ctx.rotate(this.angle);
|
||
|
ctx.drawImage(this.image, -this.size / 2, -this.size / 2, this.size, this.size);
|
||
|
ctx.restore();
|
||
|
}
|
||
|
|
||
|
rotate(direction) {
|
||
|
this.angle += this.rotationSpeed * direction;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class Bullet {
|
||
|
constructor(x, y, angle) {
|
||
|
this.x = x;
|
||
|
this.y = y;
|
||
|
this.angle = angle;
|
||
|
this.speed = 5;
|
||
|
this.size = 5;
|
||
|
}
|
||
|
|
||
|
update() {
|
||
|
this.x += Math.cos(this.angle) * this.speed;
|
||
|
this.y += Math.sin(this.angle) * this.speed;
|
||
|
}
|
||
|
|
||
|
draw() {
|
||
|
ctx.fillStyle = 'yellow';
|
||
|
ctx.beginPath();
|
||
|
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
|
||
|
ctx.fill();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const cookies = [];
|
||
|
const ship = new Ship();
|
||
|
const bullets = [];
|
||
|
|
||
|
function spawnCookies() {
|
||
|
if (cookies.length < 10) {
|
||
|
cookies.push(new Cookie(Math.random() * canvas.width, Math.random() * canvas.height, 30));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function checkCollisions() {
|
||
|
// Ship-Cookie collision
|
||
|
cookies.forEach((cookie, cookieIndex) => {
|
||
|
const dx = ship.x - cookie.x;
|
||
|
const dy = ship.y - cookie.y;
|
||
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
||
|
|
||
|
if (distance < ship.size / 2 + cookie.size / 2) {
|
||
|
gameOver = true;
|
||
|
}
|
||
|
|
||
|
// Bullet-Cookie collision
|
||
|
bullets.forEach((bullet, bulletIndex) => {
|
||
|
const bulletDx = bullet.x - cookie.x;
|
||
|
const bulletDy = bullet.y - cookie.y;
|
||
|
const bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy);
|
||
|
|
||
|
if (bulletDistance < bullet.size + cookie.size / 2) {
|
||
|
cookies.splice(cookieIndex, 1);
|
||
|
bullets.splice(bulletIndex, 1);
|
||
|
score += 10;
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function gameLoop() {
|
||
|
// Set the background to black
|
||
|
ctx.fillStyle = 'black';
|
||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||
|
|
||
|
if (gameOver) {
|
||
|
ctx.fillStyle = 'white';
|
||
|
ctx.font = '48px Arial';
|
||
|
ctx.fillText('Game Over', canvas.width / 2 - 100, canvas.height / 2);
|
||
|
ctx.font = '24px Arial';
|
||
|
ctx.fillText(`Score: ${score}`, canvas.width / 2 - 50, canvas.height / 2 + 40);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ship.update();
|
||
|
ship.draw();
|
||
|
|
||
|
cookies.forEach((cookie, index) => {
|
||
|
cookie.update();
|
||
|
cookie.draw();
|
||
|
});
|
||
|
|
||
|
bullets.forEach((bullet, index) => {
|
||
|
bullet.update();
|
||
|
bullet.draw();
|
||
|
|
||
|
if (bullet.x < 0 || bullet.x > canvas.width || bullet.y < 0 || bullet.y > canvas.height) {
|
||
|
bullets.splice(index, 1);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
spawnCookies();
|
||
|
checkCollisions();
|
||
|
|
||
|
// Draw score
|
||
|
ctx.fillStyle = 'white';
|
||
|
ctx.font = '24px Arial';
|
||
|
ctx.fillText(`Score: ${score}`, 10, 30);
|
||
|
|
||
|
requestAnimationFrame(gameLoop);
|
||
|
}
|
||
|
|
||
|
document.addEventListener('keydown', (event) => {
|
||
|
switch(event.key) {
|
||
|
case 'ArrowLeft':
|
||
|
ship.rotate(-1); // Rotate counterclockwise
|
||
|
break;
|
||
|
case 'ArrowRight':
|
||
|
ship.rotate(1); // Rotate clockwise
|
||
|
break;
|
||
|
case 'ArrowUp':
|
||
|
ship.speed = 5;
|
||
|
break;
|
||
|
case ' ':
|
||
|
bullets.push(new Bullet(ship.x, ship.y, ship.angle));
|
||
|
break;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
gameLoop();
|
||
|
});
|