用HTML5画板和ES6面向对象实现飞机大战完整版 !DOCTYPE html html lang=en head meta charset=UTF-8 meta http-equiv=X-UA-Compatible content=IE=edge meta name=viewport content=width=device-width initial-scale=10 titleDocumen
// mine.js
class Mine { constructor() { this.canvas = document.getElementById('canvas'); this.ctx = this.canvas.getContext('2d'); this.sky = new Sky(this.ctx); this.load = new Load(this.ctx); this.hero = new Hero(this.ctx); this.bullets = []; this.enemies = []; this.score = 0; this.gameover = false; this.init(); }
init() { this.sky.draw(); this.load.draw(); setTimeout(() => { this.run(); }, 2000); this.bindEvent(); }
run() { this.checkHit(); this.update(); this.clear(); this.draw(); if (!this.gameover) { requestAnimationFrame(() => { this.run(); }); } }
update() { this.hero.update(); this.bullets.forEach((bullet, index) => { bullet.update(); if (bullet.y < -bullet.height) { this.bullets.splice(index, 1); } }); this.enemies.forEach((enemy, index) => { enemy.update(); if (enemy.y > this.canvas.height) { this.enemies.splice(index, 1); } }); if (Math.floor(Math.random() * 100) < 2) { this.enemies.push(new Enemy(this.ctx)); } }
clear() { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); }
draw() { this.sky.draw(); this.hero.draw(); this.bullets.forEach(bullet => { bullet.draw(); }); this.enemies.forEach(enemy => { enemy.draw(); }); this.drawScore(); if (this.gameover) { this.drawGameOver(); } }
drawScore() {
this.ctx.fillStyle = '#fff';
this.ctx.font = '16px Arial';
this.ctx.fillText(Score: ${this.score}, 10, 30);
}
drawGameOver() { this.ctx.fillStyle = '#fff'; this.ctx.font = '32px Arial'; this.ctx.fillText('Game Over!', 100, 300); }
bindEvent() { this.canvas.addEventListener('mousemove', e => { const x = e.offsetX; const y = e.offsetY; this.hero.moveTo(x, y); }); this.canvas.addEventListener('click', e => { this.bullets.push(new Bullet(this.ctx, this.hero.x + this.hero.width / 2, this.hero.y)); }); }
checkHit() { this.bullets.forEach((bullet, index) => { this.enemies.forEach((enemy, index2) => { if (this.checkBulletHit(bullet, enemy)) { this.bullets.splice(index, 1); this.enemies.splice(index2, 1); this.score += 10; } }); }); this.enemies.forEach(enemy => { if (this.checkHeroHit(enemy)) { this.gameover = true; } }); }
checkBulletHit(bullet, enemy) { const centerX1 = bullet.x + bullet.width / 2; const centerY1 = bullet.y + bullet.height / 2; const centerX2 = enemy.x + enemy.width / 2; const centerY2 = enemy.y + enemy.height / 2; const distanceX = Math.abs(centerX1 - centerX2); const distanceY = Math.abs(centerY1 - centerY2); if (distanceX < (bullet.width + enemy.width) / 2 && distanceY < (bullet.height + enemy.height) / 2) { return true; } return false; }
checkHeroHit(enemy) { const centerX1 = this.hero.x + this.hero.width / 2; const centerY1 = this.hero.y + this.hero.height / 2; const centerX2 = enemy.x + enemy.width / 2; const centerY2 = enemy.y + enemy.height / 2; const distanceX = Math.abs(centerX1 - centerX2); const distanceY = Math.abs(centerY1 - centerY2); if (distanceX < (this.hero.width + enemy.width) / 2 && distanceY < (this.hero.height + enemy.height) / 2) { return true; } return false; } }
const mine = new Mine();
// sky.js
class Sky { constructor(ctx) { this.ctx = ctx; this.width = 480; this.height = 650; this.y = 0; this.img = new Image(); this.img.src = 'img/bg.jpg'; }
draw() { this.ctx.drawImage(this.img, 0, this.y, this.width, this.height); this.ctx.drawImage(this.img, 0, this.y - this.height, this.width, this.height); this.y++; if (this.y >= this.height) { this.y = 0; } } }
// load.js
class Load { constructor(ctx) { this.ctx = ctx; this.width = 135; this.height = 32; this.x = (480 - this.width) / 2; this.y = 300; this.img = new Image(); this.img.src = 'img/loading.gif'; }
draw() { this.ctx.drawImage(this.img, this.x, this.y, this.width, this.height); } }
// hero.js
class Hero { constructor(ctx) { this.ctx = ctx; this.width = 66; this.height = 82; this.x = (480 - this.width) / 2; this.y = 550; this.speed = 5; this.img = new Image(); this.img.src = 'img/hero.png'; }
draw() { this.ctx.drawImage(this.img, this.x, this.y, this.width, this.height); }
moveTo(x, y) { const centerX = this.x + this.width / 2; const centerY = this.y + this.height / 2; if (Math.abs(centerX - x) < this.speed && Math.abs(centerY - y) < this.speed) { return; } if (x > centerX) { this.x += this.speed; } else { this.x -= this.speed; } if (y > centerY) { this.y += this.speed; } else { this.y -= this.speed; } this.checkBoundary(); }
checkBoundary() { if (this.x < 0) { this.x = 0; } if (this.x > 480 - this.width) { this.x = 480 - this.width; } if (this.y < 0) { this.y = 0; } if (this.y > 650 - this.height) { this.y = 650 - this.height; } }
update() {} }
// Bullet.js
class Bullet { constructor(ctx, x, y) { this.ctx = ctx; this.width = 6; this.height = 14; this.x = x - this.width / 2; this.y = y - this.height; this.speed = 10; this.img = new Image(); this.img.src = 'img/bullet.png'; }
draw() { this.ctx.drawImage(this.img, this.x, this.y, this.width, this.height); }
update() { this.y -= this.speed; } }
// enemy.js
class Enemy { constructor(ctx) { this.ctx = ctx; this.width = 46; this.height = 60; this.x = Math.floor(Math.random() * (480 - this.width)); this.y = -this.height; this.speed = Math.floor(Math.random() * 3) + 1; this.img = new Image(); this.img.src = 'img/enemy.png'; }
draw() { this.ctx.drawImage(this.img, this.x, this.y, this.width, this.height); }
update() { this.y += this.speed; }
原文地址: http://www.cveoy.top/t/topic/cm76 著作权归作者所有。请勿转载和采集!