html
<body>
<canvas id="game" width="480" height="850"></canvas>
<audio id="audio" src="media/ThePhoenix.mp3"></audio>
<script src="js/planeWar.js"></script>
</body>
planeWar.js
/** @type {HTMLCanvasElement} */
var game = document.getElementById("game");
var ctx = game.getContext("2d");
//游戏开始
const START = 0;
//加载中
const LOADING = 1;
// 运行游戏
const RUNNING = 2;
//暂停游戏
const PAUSE = 3;
//游戏结束
const GAMEOVER = 4;
// 拿到宽高度
const WIDTH = game.width;
const HEIGHT = game.height;
// 游戏状态
var state = 0;
// 初始生命值
var life = 3;
// 初始得分
var score = 0;
var bgimg = new Image();
// bgimg.src = "img/background.png";
bgimg.src = "img/background.jpg";
// bgimg.src = "img/background2.jpg";
var startImg = new Image();
startImg.src = "img/start.png";
// 背景构造函数
function Background(bgimg) {
this.width = WIDTH;
this.height = HEIGHT;
this.x1 = 0;
this.y1 = 0;
this.x2 = 0;
this.y2 = -this.height;
this.paint = function() {
ctx.drawImage(bgimg, this.x1, this.y1, this.width, this.height)
ctx.drawImage(bgimg, this.x2, this.y2, this.width, this.height)
}
this.time = 0;
this.step = function() {
this.time++;
if (this.time % 5 == 0) {
this.y1++;
this.y2++;
if (this.y1 == this.height) {
this.y1 = 0;
this.y2 = -this.height;
}
}
}
}
// 实例化一个背景
var _background = new Background(bgimg);
game.addEventListener("click", function(e = e || window.e) {
// console.log(e.offsetX, e.offsetY);
var audio = document.getElementById("audio");
if (state === START) {
if (e.offsetX > 180 && e.offsetX < 305 && e.offsetY > 503 && e.offsetY < 535) {
state = LOADING;
}
if (e.offsetX > 217 && e.offsetX < 270 && e.offsetY > 582 && e.offsetY < 609) {
if (audio.paused) {
audio.play();
} else {
audio.pause();
}
}
}
if (state == PAUSE) {
if (e.offsetX > 180 && e.offsetX < 305 && e.offsetY > 503 && e.offsetY < 535) {
state = RUNNING;
}
if (e.offsetX > 217 && e.offsetX < 270 && e.offsetY > 582 && e.offsetY < 609) {
if (audio.paused) {
audio.play();
} else {
audio.pause();
}
}
}
if (state == GAMEOVER) {
// console.log(e.offsetX, e.offsetY);
if (e.offsetX > 188 && e.offsetX < 297 && e.offsetY > 551 && e.offsetY < 576) {
life = 3;
score = 0;
_loadingImgs.index = 0;
_myPlane.index = 0;
state = LOADING;
timer = setInterval(gameControl, 10);
}
}
})
var loadingImgs = [];
loadingImgs[0] = new Image();
loadingImgs[0].src = "img/game_loading1.png";
loadingImgs[1] = new Image();
loadingImgs[1].src = "img/game_loading2.png";
loadingImgs[2] = new Image();
loadingImgs[2].src = "img/game_loading3.png";
loadingImgs[3] = new Image();
loadingImgs[3].src = "img/game_loading4.png";
loadingImgs[4] = new Image();
loadingImgs[4].src = "img/game_loading5.png";
loadingImgs[5] = new Image();
loadingImgs[5].src = "img/game_loading6.png";
loadingImgs[6] = new Image();
loadingImgs[6].src = "img/game_loading7.png";
loadingImgs[7] = new Image();
loadingImgs[7].src = "img/game_loading8.png";
loadingImgs[8] = new Image();
loadingImgs[8].src = "img/game_loading9.png";
loadingImgs[9] = new Image();
loadingImgs[9].src = "img/game_loading10.png";
var LOADINGIMGS = {
imgs: loadingImgs,
length: loadingImgs.length,
width: 400,
height: 128,
}
function LoadingImgs(parameter) {
this.imgs = parameter.imgs;
this.length = parameter.length;
this.width = parameter.width;
this.height = parameter.height;
this.index = 0;
this.paint = function() {
ctx.drawImage(this.imgs[this.index], 40, 198);
}
this.time = 0;
this.step = function() {
this.time++;
if (this.time % 5 == 0) {
this.index++;
}
if (this.index === this.length) {
state = RUNNING;
}
}
}
var _loadingImgs = new LoadingImgs(LOADINGIMGS);
var myPlanes = [];
myPlanes[0] = new Image();
myPlanes[0].src = "img/hero1.png"
myPlanes[1] = new Image();
myPlanes[1].src = "img/hero2.png"
myPlanes[2] = new Image();
myPlanes[2].src = "img/hero_blowup_n1.png"
myPlanes[3] = new Image();
myPlanes[3].src = "img/hero_blowup_n2.png"
myPlanes[4] = new Image();
myPlanes[4].src = "img/hero_blowup_n3.png"
myPlanes[5] = new Image();
myPlanes[5].src = "img/hero_blowup_n4.png";
var MYPLANES = {
imgs: myPlanes,
length: myPlanes.length,
width: 99,
height: 124
}
function MyPlanes(parameter) {
this.imgs = parameter.imgs;
this.length = parameter.length;
this.width = parameter.width;
this.height = parameter.height;
this.x = WIDTH / 2 - this.width / 2;
this.y = HEIGHT - this.height - 10;
this.index = 0;
this.isCrashed = false;
this.paint = function() {
ctx.drawImage(this.imgs[this.index], this.x, this.y);
}
this.step = function() {
if (this.isCrashed) {
//发生了碰撞
this.index++;
if (this.index == this.length - 1) {
life--;
// console.log(life);
if (life == 0) {
state = GAMEOVER;
} else {
_myPlane = new MyPlanes(MYPLANES);
}
}
} else {
if (this.index == 0) {
this.index = 1;
} else {
this.index = 0;
}
}
}
this.crashed = function() {
this.isCrashed = true;
}
this.time = 0;
this.shoot = function() {
this.time++;
if (this.time % 10 == 0) {
var bul = new Bullet(BULLET);
bul.type = 0;
shootOutBullets.push(bul);
var bul1 = new Bullet(BULLET);
bul1.type = 1;
shootOutBullets.push(bul1);
var bul2 = new Bullet(BULLET);
bul2.type = -1;
shootOutBullets.push(bul2);
}
}
}
var _myPlane = new MyPlanes(MYPLANES);
var bullet = new Image();
bullet.src = "img/bullet1.png";
var BULLET = {
imgs: bullet,
width: 15,
height: 45,
type: 0,
}
function Bullet(parameter) {
this.imgs = parameter.imgs;
this.width = parameter.width;
this.height = parameter.height;
this.x = _myPlane.x + _myPlane.width / 2 - this.width / 2;
this.y = _myPlane.y - this.height + 40;
this.isDisappear = false;
this.paint = function() {
if (this.type == 0) {
ctx.drawImage(this.imgs, this.x, this.y);
} else if (this.type == 1) {
ctx.drawImage(this.imgs, this.x - 30, this.y + 20);
} else if (this.type == -1) {
ctx.drawImage(this.imgs, this.x + 30, this.y + 20);
}
}
this.step = function() {
this.y -= 5;
}
this.crashed = function() {
this.isDisappear = true;
}
}
var shootOutBullets = [];
function paintShootOutBullets() {
for (let i = 0; i < shootOutBullets.length; i++) {
shootOutBullets[i].paint();
}
}
function stepShootOutBullets() {
for (let i = 0; i < shootOutBullets.length; i++) {
shootOutBullets[i].step();
}
}
function delShootOutBullets() {
for (let i = 0; i < shootOutBullets.length; i++) {
if (shootOutBullets[i].y < -shootOutBullets[i].height || shootOutBullets[i].isDisappear) {
shootOutBullets.splice(i, 1)
}
}
}
game.addEventListener("mousemove", function(e = e || window.e) {
if (state == RUNNING) {
this.style.cursor = "none";
_myPlane.x = e.offsetX - _myPlane.width / 2;
_myPlane.y = e.offsetY - _myPlane.height / 2;
} else {
this.style.cursor = "pointer";
}
// console.log(e.offsetY);
})
window.addEventListener("keydown", function(e = e || window.e) {
if (state == RUNNING) {
if (e.keyCode == 37) {
_myPlane.x -= 10;
}
if (e.keyCode == 38) {
_myPlane.y -= 10;
}
if (e.keyCode == 39) {
_myPlane.x += 10;
}
if (e.keyCode == 40) {
_myPlane.y += 10;
}
// this.console.log(e.keyCode);
}
})
// 小飞机数组
var sPlane = [];
sPlane[0] = new Image();
sPlane[0].src = "img/enemy1.png";
sPlane[1] = new Image();
sPlane[1].src = "img/enemy1_down1.png";
sPlane[2] = new Image();
sPlane[2].src = "img/enemy1_down2.png";
sPlane[3] = new Image();
sPlane[3].src = "img/enemy1_down3.png";
sPlane[4] = new Image();
sPlane[4].src = "img/enemy1_down4.png";
// 小飞机信息
var SPLANE = {
imgs: sPlane,
length: sPlane.length,
width: 57,
height: 51,
planeType: 1,
life: 1,
score: 5,
}
// 中等飞机
var mPlane = [];
mPlane[0] = new Image();
mPlane[0].src = "img/enemy2.png"
mPlane[1] = new Image();
mPlane[1].src = "img/enemy2_down1.png"
mPlane[2] = new Image();
mPlane[2].src = "img/enemy2_down2.png"
mPlane[3] = new Image();
mPlane[3].src = "img/enemy2_down3.png"
mPlane[4] = new Image();
mPlane[4].src = "img/enemy2_down4.png"
// 中等飞机信息
var MPLANE = {
imgs: mPlane,
length: mPlane.length,
width: 69,
height: 95,
planeType: 2,
life: 3,
score: 10,
}
// 大飞机
var lPlane = [];
lPlane[0] = new Image();
lPlane[0].src = "img/enemy3_n1.png"
lPlane[1] = new Image();
lPlane[1].src = "img/enemy3_n2.png"
lPlane[2] = new Image();
lPlane[2].src = "img/enemy3_down1.png"
lPlane[3] = new Image();
lPlane[3].src = "img/enemy3_down2.png"
lPlane[4] = new Image();
lPlane[4].src = "img/enemy3_down3.png"
lPlane[5] = new Image();
lPlane[5].src = "img/enemy3_down4.png"
lPlane[6] = new Image();
lPlane[6].src = "img/enemy3_down5.png"
lPlane[7] = new Image();
lPlane[7].src = "img/enemy3_down6.png"
// 大飞机信息
var LPLANE = {
imgs: lPlane,
length: lPlane.length,
width: 193,
height: 110,
planeType: 3,
life: 6,
score: 15,
}
// 飞机构造函数,所有飞机
function Plane(parameter) {
this.imgs = parameter.imgs;
this.length = parameter.length;
this.planeType = parameter.planeType;
this.width = parameter.width;
this.height = parameter.height;
this.life = parameter.life;
this.score = parameter.score;
this.index = 0;
this.x = Math.random() * (WIDTH - this.width);
this.y = -this.height;
// 是否发生碰撞
this.isCrashed = false;
this.isDisappear = false;
this.paint = function() {
ctx.drawImage(this.imgs[this.index], this.x, this.y);
}
this.step = function() {
if (this.isCrashed) {
this.index++;
if (this.index == this.length - 1) {
this.isDisappear = true;
}
} else {
this.y++;
}
}
this.crashed = function() {
this.life--;
if (this.life == 0) {
this.isCrashed = true;
score += this.score;
}
}
this.checkCrashed = function(opponent) {
return (opponent.y + opponent.height > this.y) &&
(opponent.x + opponent.width > this.x) &&
(opponent.y < this.y + this.height) &&
(opponent.x < this.x + this.width);
}
}
var planes = [];
function planesPush() {
var probability = Math.floor(Math.random() * 100);
if (probability < 5) {
planes.push(new Plane(SPLANE));
} else if (probability > 98) {
planes.push(new Plane(MPLANE));
} else if (probability == 50) {
for (var i = 0; i < planes.length; i++) {
if (planes[i].planeType == 3) {
break;
}
}
if (i == planes.length) {
planes.push(new Plane(LPLANE));
}
}
}
function paintPlanes() {
for (let i = 0; i < planes.length; i++) {
planes[i].paint();
}
}
function stepPlanes() {
for (let i = 0; i < planes.length; i++) {
planes[i].step();
}
}
function delPlanes() {
for (let i = 0; i < planes.length; i++) {
if (planes[i].y > HEIGHT || planes[i].isDisappear) {
planes.splice(i, 1)
}
}
}
function planesCheckCrashed() {
for (let i = 0; i < planes.length; i++) {
// 判断是否与子弹相撞
for (let j = 0; j < shootOutBullets.length; j++) {
if (planes[i].checkCrashed(shootOutBullets[j])) {
planes[i].crashed();
shootOutBullets[j].crashed();
}
}
if (planes[i].checkCrashed(_myPlane)) {
planes[i].crashed();
_myPlane.crashed();
}
}
}
game.addEventListener("mouseout", function() {
if (state == 2) {
state = PAUSE;
}
});
var pauseImg = new Image();
pauseImg.src = "img/pause.png"
var timer = setInterval(gameControl, 10);
function gameControl() {
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.font = "30px HYShangWeiShouShuW-Regular";
ctx.fillStyle = "#eee";
var textScore = "SCORE: " + score;
var textlife = "LIFE: " + life;
_background.paint();
_background.step();
switch (state) {
case START:
ctx.drawImage(startImg, (WIDTH - startImg.width) / 2, 0);
break;
case LOADING:
ctx.drawImage(startImg, (WIDTH - startImg.width) / 2, 0);
_loadingImgs.paint();
_loadingImgs.step();
break;
case RUNNING:
_myPlane.paint();
_myPlane.step();
_myPlane.shoot();
// 子弹绘制,移动,删除
paintShootOutBullets();
stepShootOutBullets();
delShootOutBullets();
planesPush();
// 敌机绘制,移动,删除
paintPlanes();
stepPlanes();
delPlanes();
planesCheckCrashed();
ctx.fillText(textScore, 10, 10);
ctx.fillText(textlife, 370, 10);
break;
case PAUSE:
_myPlane.paint();
paintShootOutBullets();
paintPlanes();
ctx.fillText(textScore, 10, 10);
ctx.fillText(textlife, 370, 10);
ctx.drawImage(pauseImg, (WIDTH - pauseImg.width) / 2, 0);
break;
case GAMEOVER:
_myPlane.paint();
paintShootOutBullets();
paintPlanes();
ctx.textAlign = "center";
ctx.fillText(textScore, 240, 400);
ctx.fillText("重新开始", 240, 550);
ctx.font = "50px HYShangWeiShouShuW-Regular";
ctx.fillText("游戏结束", 240, 300);
// ctx.fillText(textlife, 200, 450);
// console.log("游戏结束");
clearInterval(timer);
break;
default:
break;
}
}