JavaScript实现简易飞机大战
短信预约 -IT技能 免费直播动态提醒
本文实例为大家分享了JavaScript实现简易飞机大战的具体代码,供大家参考,具体内容如下
话不多说,直接上代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>飞机大战</title>
<style>
body {
text-align: center;
}
canvas {
display: block;
border: 1px solid;
margin: auto;
}
</style>
</head>
<body>
<canvas id="canvas" width="480" height="650"></canvas>
<script>
(function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var start = 0; // 开始阶段
var starting = 1; // 开始的加载阶段
var running = 2; // 游戏阶段
var pause = 3; // 暂停阶段
var gameover = 4; // 结束阶段
var state = start; // 目前状态
var width = canvas.width; // 获取画布的宽度
var height = canvas.height; // 获取画布的高度
var score = 0; // 分数
var life = 3; // 我放飞机生命值
var bg = new Image(); // 创建背景图片
bg.class="lazy" data-src = "img/background.png";
var BG = {
imgs: bg,
width: 480,
height: 852,
};
// 创建生成背景图片的构造函数
function Bg(config) { // 参数为BG对象
this.imgs = config.imgs;
this.width = config.width;
this.height = config.height;
// 定义两张背景图片,用于动画
this.x1 = 0;
this.y1 = 0;
this.x2 = 0;
//第二张背景图的初始高度放在背景高度(固定)的上面
this.y2 = -this.height;
// 背景图片绘制方法
this.paint = function() {
//分别绘制了两张背景图
ctx.drawImage(this.imgs, this.x1, this.y1);
ctx.drawImage(this.imgs, this.x2, this.y2);
};
// 背景图片运动的方法
this.step = function() {
//背景图片位置向下移动一个,然后利用定时器让背景图动起来
this.y1++;
this.y2++;
//判断图片高度的临界点,
if (this.y1 == this.height) {
this.y1 = -this.height;
}
if (this.y2 == this.height) {
this.y2 = -this.height;
}
}
};
// 创建背景图片对象
var sky = new Bg(BG);
// 生成游戏名文字
var logo = new Image();
logo.class="lazy" data-src = "img/start.png";
// 游戏加载过程的4张图片存入一个数组中
var loadings = [];
loadings[0] = new Image();
loadings[0].class="lazy" data-src = "img/game_loading1.png";
loadings[1] = new Image();
loadings[1].class="lazy" data-src = "img/game_loading2.png";
loadings[2] = new Image();
loadings[2].class="lazy" data-src = "img/game_loading3.png";
loadings[3] = new Image();
loadings[3].class="lazy" data-src = "img/game_loading4.png";
var LOADING = {
imges: loadings,
length: loadings.length,
width: 186,
height: 38,
};
// 构造函数
function Loading(config) {
this.imges = config.imges;
this.length = config.length;
this.width = config.width;
this.height = config.height;
this.startIndex = 0; // 用于判断需要显示的图片是哪个
// 绘制方法
this.paint = function() {
ctx.drawImage(this.imges[this.startIndex], 0, height - this.height)
};
this.time = 0; // 加载时图片切换速度
// 图片切换方法
this.step = function() {
this.time++;
if (this.time % 4 === 0) {
this.startIndex++;
}
if (this.startIndex === this.length) {
// 加载阶段结束,进入游戏阶段
state = running;
}
}
};
// 创建加载阶段的对象
var loading = new Loading(LOADING);
// 我放飞机
var heros = [];
heros[0] = new Image();
heros[0].class="lazy" data-src = "img/hero1.png";
heros[1] = new Image();
heros[1].class="lazy" data-src = "img/hero2.png";
heros[2] = new Image();
heros[2].class="lazy" data-src = "img/hero_blowup_n1.png";
heros[3] = new Image();
heros[3].class="lazy" data-src = "img/hero_blowup_n2.png";
heros[4] = new Image();
heros[4].class="lazy" data-src = "img/hero_blowup_n3.png";
heros[5] = new Image();
heros[5].class="lazy" data-src = "img/hero_blowup_n4.png";
var HEROS = {
imgs: heros,
length: heros.length,
width: 99,
height: 124,
frame: 2
};
// 我放飞机的构造函数
function Hero(config) {
this.imgs = config.imgs;
this.length = config.length;
this.width = config.width;
this.height = config.height;
this.frame = config.frame;
this.startIndex = 0; // 用于判断我放飞机当前状态
// 定义我放飞机的位置
this.x = width / 2 - this.width / 2;
this.y = height - this.height;
// 定义飞机撞击的标志,表示飞机没有被撞击
this.down = false;
// 定义飞机是否爆破完成,表示飞机还没有完全爆炸
this.candel = false;
// 绘制方法
this.paint = function() {
ctx.drawImage(this.imgs[this.startIndex], this.x, this.y)
};
// 我放飞机运动方法
this.step = function() {
if (!this.down) { // 飞机正常状态
if (this.startIndex === 0) {
this.startIndex = 1;
} else {
this.startIndex = 0
}
} else { // 爆炸状态
this.startIndex++;
if (this.startIndex === this.length) { // 判断是否炸完了
// 炸完了,命-1
life--;
if (life === 0) { // 判断是否挂了
state = gameover;
this.startIndex = this.length - 1;
} else { // 重新开始新生命
hero = new Hero(HEROS)
}
}
}
};
// 我放飞机碰撞
this.bang = function() {
this.down = true;
};
// 子弹发射
this.time = 0; // 设计速度初始为0
this.shoot = function() {
this.time++;
if (this.time % 2 === 0) { // 每2步移动射击一次
bullets.push(new Bullet(BULLETS))
}
};
};
// 创建我方飞机的对象实例
var hero = new Hero(HEROS);
// 鼠标移动事件
canvas.onmousemove = function(event) {
// console.log("onmousemove");
var event = event || window.event;
if (state == running) { //判断当前游戏状态
//把获取到的页面中的鼠标横坐标的值赋给飞机的横坐标(位置)
hero.x = event.offsetX - hero.width / 2;
//把获取到的页面中的鼠标纵坐标的值赋给飞机的纵坐标(位置)
hero.y = event.offsetY - hero.height / 2;
}
};
// 绘制子弹
var bullet = new Image();
bullet.class="lazy" data-src = "img/bullet1.png";
// 初始化
var BULLETS = {
imgs: bullet,
width: 9,
height: 21,
};
// 创建子弹的构造函数
function Bullet(config) {
this.imgs = config.imgs;
this.width = config.width;
this.height = config.height;
// 子弹坐标
this.x = hero.x + hero.width / 2 - this.width / 2;
this.y = hero.y - this.height;
// 绘制方法
this.paint = function() {
ctx.drawImage(this.imgs, this.x, this.y)
};
// 运动方法
this.step = function() {
this.y -= 10;
};
this.candel = false; // 用于判断子弹是否碰撞
// 子弹碰撞方法
this.bang = function() {
this.candel = true;
}
};
// 所有new的子弹对象放到一个数组
var bullets = [];
// 遍历绘制子弹
function bulletdPaint() {
for (var i = 0; i < bullets.length; i++) {
bullets[i].paint();
}
};
// 遍历调用子弹的运动;
function bulletdStep() {
for (var i = 0; i < bullets.length; i++) {
bullets[i].step();
}
};
// 子弹的删除函数
function bulletDel() {
// 碰撞的时候删除子弹
// 超出画布的高度,即负的子弹的高度
for (var i = 0; i < bullets.length; i++) {
if (bullets[i].candel || bullets[i].y < -bullets[i].height) {
bullets.splice(i, 1)
}
}
};
// 敌方飞机的绘制
var enemy1 = []; //小飞机
enemy1[0] = new Image();
enemy1[0].class="lazy" data-src = "img/enemy1.png";
enemy1[1] = new Image();
enemy1[1].class="lazy" data-src = 'img/enemy1_down1.png';
enemy1[2] = new Image();
enemy1[2].class="lazy" data-src = 'img/enemy1_down2.png';
enemy1[3] = new Image();
enemy1[3].class="lazy" data-src = 'img/enemy1_down3.png';
enemy1[4] = new Image();
enemy1[4].class="lazy" data-src = 'img/enemy1_down4.png';
var enemy2 = []; //中飞机
enemy2[0] = new Image();
enemy2[0].class="lazy" data-src = "img/enemy2.png";
enemy2[1] = new Image();
enemy2[1].class="lazy" data-src = "img/enemy2_down1.png";
enemy2[2] = new Image();
enemy2[2].class="lazy" data-src = "img/enemy2_down2.png";
enemy2[3] = new Image();
enemy2[3].class="lazy" data-src = "img/enemy2_down3.png";
enemy2[4] = new Image();
enemy2[4].class="lazy" data-src = "img/enemy2_down4.png";
var enemy3 = []; //大飞机
enemy3[0] = new Image();
enemy3[0].class="lazy" data-src = "img/enemy3_n1.png";
enemy3[1] = new Image();
enemy3[1].class="lazy" data-src = "img/enemy3_n2.png";
enemy3[2] = new Image();
enemy3[2].class="lazy" data-src = "img/enemy3_down1.png";
enemy3[3] = new Image();
enemy3[3].class="lazy" data-src = "img/enemy3_down2.png";
enemy3[4] = new Image();
enemy3[4].class="lazy" data-src = "img/enemy3_down3.png";
enemy3[5] = new Image();
enemy3[5].class="lazy" data-src = "img/enemy3_down4.png";
enemy3[6] = new Image();
enemy3[6].class="lazy" data-src = "img/enemy3_down5.png";
enemy3[7] = new Image();
enemy3[7].class="lazy" data-src = "img/enemy3_down6.png";
// 初始化数据
var ENEMY1 = {
imgs: enemy1,
length: enemy1.length,
width: 57,
height: 51,
type: 1,
frame: 1,
life: 1,
score: 1,
};
var ENEMY2 = {
imgs: enemy2,
length: enemy2.length,
width: 69,
height: 95,
type: 2,
frame: 1,
life: 5,
score: 5,
};
var ENEMY3 = {
imgs: enemy3,
length: enemy3.length,
width: 165,
height: 261,
type: 3,
frame: 2,
life: 15,
score: 20,
};
// 敌方飞机的构造函数
function Enemy(config) {
this.imgs = config.imgs;
this.length = config.length;
this.width = config.width;
this.height = config.height;
this.type = config.type;
this.frame = config.frame;
this.life = config.life;
this.score = config.score;
// 敌方飞机的坐标
this.x = Math.random() * (width - this.width);
this.y = -this.height;
this.startIndex = 0; // 用于判断的下标
this.down = false; // 用于判断是否碰撞
this.candel = false; // 用于判断是否爆炸完成
//绘制方法
this.paint = function() {
ctx.drawImage(this.imgs[this.startIndex], this.x, this.y);
};
//运动方法
this.step = function() {
if (!this.down) { // 敌方飞机处于正常状态
// 小飞机,中飞机的下标始终都是0
// 大飞机的下标是在0和1之间进行切换
this.startIndex++;
this.startIndex = this.startIndex % this.frame;
// 飞机向下的动画
this.y += 2;
} else { //飞机发生碰撞以后
this.startIndex++;
if (this.startIndex == this.length) {
this.candel = true;
this.startIndex = this.length - 1;
}
}
};
// 判断是否被碰撞
this.checkHit = function(wo) { //判断四个边
return wo.y + wo.height > this.y &&
wo.x + wo.width > this.x &&
wo.y < this.y + this.height &&
wo.x < this.x + this.width;
};
//敌方飞机碰撞后
this.bang = function() {
this.life--;
if (this.life === 0) {
this.down = true;
score += this.score;
}
}
};
// 数组存放敌方飞机
var enemise = [];
// 往敌方飞机数组中添加数据
function enterEnemise() {
var rand = Math.floor(Math.random() * 100)
if (rand < 10) {
// 添加小飞机
enemise.push(new Enemy(ENEMY1));
} else if (rand < 55 && rand > 50) {
// 添加中飞机
enemise.push(new Enemy(ENEMY2));
} else if (rand === 88) {
// 添加大飞机
if (enemise[0].type !== 3 && enemise.length > 0) {
enemise.splice(0, 0, new Enemy(ENEMY3));
}
}
};
// 绘制敌方飞机函数
function enemyPaint() {
for (var i = 0; i < enemise.length; i++) {
enemise[i].paint();
}
};
// 敌方飞机的运动函数
function enemyStep() {
for (var i = 0; i < enemise.length; i++) {
enemise[i].step();
}
};
// 删除敌方飞机函数
function delenemy() {
for (var i = 0; i < enemise.length; i++) {
// console.log(enemise[i].candel)
if (enemise[i].y > height || enemise[i].candel) {
enemise.splice(i, 1)
}
}
};
// 碰撞以后的函数
function hitEnemise() {
for (var i = 0; i < enemise.length; i++) {
// 如果我放飞机撞到了敌方飞机以后
if (enemise[i].checkHit(hero)) {
// 敌方飞机碰撞后,碰撞状态改变
enemise[i].bang();
// 我方飞机碰撞后,碰撞状态改变
hero.bang();
};
// 子弹碰到敌方飞机
for (var j = 0; j < bullets.length; j++) {
if (enemise[i].checkHit(bullets[j])) {
enemise[i].bang();
// 子弹的碰撞后,碰撞状态改变
bullets[j].bang();
}
}
}
};
// 绘制分数和生命值
function scoreText() {
ctx.font = "30px bold"
ctx.fillText("score:" + score, 10, 30);
ctx.fillText("life:" + life, 300, 30);
};
// 游戏暂停的阶段
canvas.onmouseout = function() {
if (state === running) {
state = pause;
}
};
// 调用画布的鼠标移入事件
canvas.onmouseover = function() {
if (state === pause) {
state = running;
}
};
// 暂停图片
var pause = new Image()
pause.class="lazy" data-src = "img/game_pause_nor.png";
// 游戏结束
function gameoverfn() {
ctx.font = "50px bold"
ctx.fillText("GAME OVER !!!", 80, 300);
ctx.fillText("ONCE MORE !!!", 80, 400);
};
// 画布点击事件
canvas.addEventListener("click", function(e) {
p = getEventPosition(e);
// 点击画布时,判断游戏是否开始
if (state === start) {
state = starting;
}
// 重新开始游戏有问题???
if (state === gameover) {
if (p.y >= 350 && p.y < 450) {
console.log('你点击了ONCE MORE !!!');
state = running;
}
}
});
function getEventPosition(e) {
var x, y;
if (e.layerX || ev.layerX === 0) {
x = e.layerX;
y = e.layerY;
} else if (e.offsetX || ev.offsetX === 0) {
x = e.offsetX;
y = e.offsetY;
}
return {
x: x,
y: y
};
};
setInterval(function() {
//背景图片无论在哪个状态都有背景图片以及它的动态效果
sky.paint(); // 绘制背景
sky.step(); // 背景动画
if (state === start) { // 第一阶段
ctx.drawImage(logo, 35, 0)
} else if (state === starting) { // 第二阶段
loading.paint(); // 绘制背景
loading.step(); // 背景动画
} else if (state === running) { // 第三状态
// 绘制我放飞机
hero.paint();
// 我方飞机的运动
hero.step();
// 我方飞机的射击方法
hero.shoot();
// 子弹的绘制
bulletdPaint();
// 子弹的运动
bulletdStep();
// 子弹的删除
bulletDel();
// 创建敌方飞机
enterEnemise();
// 绘制敌方飞机
enemyPaint();
// 绘制敌方飞机的运动
enemyStep();
// 删除敌方飞机
delenemy();
// 判断是否撞击
hitEnemise();
// 绘制分数和生命值
scoreText()
} else if (state === pause) { // 第四状态
sky.paint(); // 绘制背景
sky.step(); // 背景动画
// 绘制我放飞机
hero.paint();
// 子弹的绘制
bulletdPaint();
// 绘制敌方飞机
enemyPaint();
// 绘制分数和生命值
scoreText();
ctx.drawImage(pause, 220, 300)
} else if (state === gameover) { // 第五状态
sky.paint(); // 绘制背景
sky.step(); // 背景动画
hero.paint();
// 子弹的绘制
bulletdPaint();
// 绘制敌方飞机
enemyPaint();
// 绘制分数和生命值
scoreText();
// 游戏结束
gameoverfn();
}
}, 10)
})()
</script>
</body>
</html>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341