<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>飞机大战</title>
<style>
div
{
margin: 0 auto;
text-align: center;
}
</style>
</head>
<body>
<div>
<canvas id="myCanvas" width="480" height="650"></canvas>
</div>
<script>
//获取画布的对象和工具
var cav = document.getElementById("myCanvas");
var cxt = cav.getContext("2d");
//初始化数据
//定义游戏的状态
var START = 0; //加载
var STARTING = 1; //加载中
var RUNNING = 2; //游戏开始
var PAUSE = 3; //暂停
var GAMEOVER = 4; //结束
//开始加载状态
var start = START;
//设置宽高
var WIDTH = 480;
var HEIGHT = 650;
//设置得分
var score = 0;
//设置玩家生命值
var life = 3;
//设置背景
var bg = new Image();//创建背景对象
bg.src = "img/background.png";
//定义背景对象数据
var Bg = {
imgs: bg,
width: 480,
height: 850
}
//定义函数绘制背景
//创建两张图片形成切换效果
function BG(temp)
{
this.imgs = temp.imgs;
this.width = temp.width;
this.height = temp.height;
//第一张图片位置
this.x1 = 0;
this.y1 = 0;
//第二张图片位置
this.x2 = 0;
this.y2 = -this.height;
//定义paint函数绘制背景图片
this.paint = function()
{
cxt.drawImage(this.imgs,this.x1,this.y1);
cxt.drawImage(this.imgs,this.x2,this.y2);
}
//定义step函数移动背景图片
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);
//绘制外层logo
var logo = new Image();
logo.src = "img/start.png";
//游戏加载状态
var loadings = [];//定义加载状态图片数组
loadings[0] = new Image();
loadings[0].src = "img/game_loading1.png";
loadings[1] = new Image();
loadings[1].src = "img/game_loading2.png";
loadings[2] = new Image();
loadings[2].src = "img/game_loading3.png";
loadings[3] = new Image();
loadings[3].src = "img/game_loading4.png";
//定义对象存储图片数据
var Loading = {
img: loadings,
length: loadings.length,
width: 186,
height: 38
}
//定义函数绘制加载状态的动画
//当loading的索引长度达到最大时游戏开始
function Load(temp)
{
this.img = temp.img;
this.length = temp.length;
this.width = temp.width;
this.height = temp.height;
this.index = 0; //定义数组索引
//x,y为图片的位置
this.x = 110;
this.y = 400;
//定义绘制图片的函数paint
this.paint = function()
{
cxt.drawImage(this.img[this.index],this.x,this.y);
}
//定义图片移动函数
this.cnt = 0;
this.step = function()
{
//当程序运行3次时图片换一个
this.cnt++;
if (this.cnt%3==0)
this.index++;
if (this.index == this.length)
start = RUNNING;//游戏开始标志
}
}
//创建载入图片对象
var loadImg = new Load(Loading);
//给canvas绑定鼠标点击事件
//点击画布时进入START状态
cav.onclick = function()
{
if (start==START)
start = STARTING;
}
//定义玩家对象状态数组
var myPlane = [];
//玩家飞机正常的状态
//用两张图片使飞机呈现动态效果
myPlane[0] = new Image;
myPlane[0].src = "img/hero1.png";
myPlane[1] = new Image;
myPlane[1].src = "img/hero2.png";
//飞机生命值为0时的状态
myPlane[2] = new Image;
myPlane[2].src = "img/hero_blowup_n1.png";
myPlane[3] = new Image;
myPlane[3].src = "img/hero_blowup_n2.png";
myPlane[4] = new Image;
myPlane[4].src = "img/hero_blowup_n3.png";
myPlane[5] = new Image;
myPlane[5].src = "img/hero_blowup_n4.png";
//定义玩家飞机的数据对象
var plane = {
img: myPlane,
length: myPlane.length,
width: 99,
height: 124,
collider: 2 //玩家是否碰撞的状态
}
//创建玩家飞机函数
function PLANE(my)
{
this.img = my.img;
this.length = my.length;
this.width = my.width;
this.height = my.height;
this.collider = my.collider;
this.index = 0; //数组索引
//飞机(图片)位置
this.x = (WIDTH - this.width) / 2;
this.y = HEIGHT - 150;
this.dash = false; //飞机未碰撞
//撞击函数
this.bang = function()
{
this.dash = true;//飞机碰撞了
}
//paint绘制飞机
this.paint = function()
{
cxt.drawImage(this.img[this.index],this.x,this.y);
}
//玩家飞机运动函数
this.step = function()
{
//飞机未碰撞时在两张图片中来
//回切换,形成动态效果
if (this.dash==false)
{
this.index++;
this.index = this.index % 2;
}
else
{
//飞机碰撞后加载碰撞后的图片
this.index++;
if (this.index==this.length)
{
//碰撞一次生命值减一
life--;
//s生命值为0时结束游戏
if (life <= 0)
{
start = GAMEOVER;
this.index = this.length - 1;
}
//生命值不为0重建玩家飞机对象
else
{
player = new PLANE(plane);
}
}
}
}
//定义自动射击的时间间隔
this.cnt = 0;
//玩家飞机射击控制函数
this.shoot = function()
{
this.cnt++;
if (this.cnt % 3==0)
{
//射出的子弹存在数组里
bullett.push(new bulls(bull));
}
}
}
//设置玩家对象
var player = new PLANE(plane);
//设置飞机在画布上跟随鼠标移动
cav.onmousemove = function(evevt)
{
var event = event || window.event;
if (start==RUNNING)
{
//获取鼠标的位置
var x = event.offsetX;
var y = event.offsetY;
//使玩家飞机中心跟随鼠标
player.x = x - player.width / 2;
player.y = y - player.height / 2;
}
}
//绘制子弹
var bu = new Image();
bu.src = "img/bullet1.png";
//初始化子弹数据
var bull = {
img: bu,
width: 9,
height: 21
}
//绘制子弹函数
function bulls(zd)
{
this.img = zd.img;
this.width = zd.width;
this.height = zd.height;
//子弹坐标
this.x = player.x + player.width / 2 - this.width / 2;
this.y = player.y - this.height - 10;
//碰撞标志位
this.candel = false;
//绘制子弹
this.paint = function()
{
cxt.drawImage(this.img,this.x,this.y);
}
//子弹移动函数
this.step = function()
{
this.y -= 10;
}
//碰撞状态改变函数
this.bang = function()
{
this.candel = true;
}
}
//创建储存子弹对象的数组
var bullett = [];
//创建绘制所有子弹的函数
function bullet_paint()
{
for (var i=0;i<bullett.length;i++)
{
bullett[i].paint();
}
}
//创建子弹运动的函数
function bullet_step()
{
for (var i=0;i<bullett.length;i++)
{
bullett[i].step();
}
}
//清楚无用的子弹(碰撞和出界的)
function bullet_vanish()
{
for (var i=0;i<bullett.length;i++)
{
//子弹的碰撞动画播放完,以及出界的清除掉
if (bullett[i].candel==true || bullett[i].y<-bullett[i].height)
{
//splice删除i位置的若干元素
bullett.splice(i,1);
}
}
}
//创建敌机
var enermys = [];//低机图片数组
enermys[0] = new Image();
enermys[0].src = "img/enemy1.png";
enermys[1] = new Image();
enermys[1].src = "img/enemy1_down1.png";
enermys[2] = new Image();
enermys[2].src = "img/enemy1_down2.png";
enermys[3] = new Image();
enermys[3].src = "img/enemy1_down3.png";
enermys[4] = new Image();
enermys[4].src = "img/enemy1_down4.png";
//敌机初始化数据
var enermy = {
img: enermys,
length: enermys.length,
width: 57,
height: 51,
life: 1,
score: 1
}
function Enermy(dj)
{
this.img = dj.img;
this.length = dj.length;
this.width = dj.width;
this.height = dj.height;
this.life = dj.life;
this.score = dj.score;
//用随机数产生敌机出现的坐标
this.x = Math.random() * (WIDTH - this.width);
this.y = -this.height;
this.dash = false;//撞击标志位
this.cancel = false;//确定动画是否播放完
this.index = 0;//敌机索引
//绘制敌机
this.paint = function()
{
cxt.drawImage(this.img[this.index],this.x,this.y);
}
//敌机运动函数
this.step = function()
{
if (!this.dash)
{
//没碰撞时敌机状态不变一直是第一张图片
this.index = 0;
this.y += 10;
if (this.y+this.height>HEIGHT)
{
//当敌机到达画布底部还没被击败,则游戏结束
start = GAMEOVER;
}
}
else
{
//加载碰撞后的动画
this.index++;
if (this.index == this.length)
{
this.cancel = true;//表示动画播放完
this.index = this.length - 1;
}
}
}
//敌机撞击函数
this.bang = function()
{
//碰撞后生命值减少
this.life--;
if (this.life<=0)
{
this.dash = true;
score += this.score;
}
}
//判断碰撞函数
this.check_hit = function(obj)
{
return this.x<obj.x+obj.width && this.x+this.width>obj.x && this.y<obj.y+obj.height && this.y+this.height>obj.y
}
}
//定义数组存储敌机
var enermies = [];
function enermy_create()
{
//使用随机数控制敌机产生数量
var ran = Math.floor(Math.random()*100);
if (ran<=7)
{
enermies.push(new Enermy(enermy));
}
}
//绘制敌机
function enermy_paint()
{
for (var i=0;i<enermies.length;i++)
{
enermies[i].paint();
}
}
//敌机运动
function enermy_step()
{
for (var i=0;i<enermies.length;i++)
{
enermies[i].step();
}
}
//敌机毁灭并清除掉
function enermy_dash()
{
for (var i=0;i<enermies.length;i++)
{
if (enermies[i].cancel || enermies[i].y>HEIGHT)
enermies.splice(i,1);
}
}
//碰撞处理函数
function checkHit()
{
for (var i=0;i<enermies.length;i++)
{
//情况一:玩家飞机与敌机碰撞
if (enermies[i].check_hit(player))
{
enermies[i].bang();
player.bang();
}
//情况二:子弹与敌机相撞
for (var j=0;j<bullett.length;j++)
{
if (enermies[i].check_hit(bullett[j]))
{
enermies[i].bang();
bullett[j].bang();
}
}
}
}
//定义暂停图片
var pause = new Image();
pause.src = "img/game_pause_nor.png";
//鼠标离开画布时暂停
cav.onmouseout = function()
{
if (start ==RUNNING)
start = PAUSE;
}
//鼠标回到画布时继续
cav.onmouseover = function()
{
if (start == PAUSE)
start = RUNNING;
}
//在画布的左上角打印得分
//在画布右上角打印玩家生命值
function pain_information()
{
cxt.font = 'bold 24px 微软雅黑';
cxt.fillText("SCORE:"+score,20,30);
cxt.fillText("LIFE:"+life,380,30);
}
//游戏结束时打印gameover
function paint_end_game()
{
cxt.font = "bold 36px 微软雅黑";
cxt.fillText("GAMEOVER",150,300);
}
//定时器循环调用
function main()
{
sky.paint();//绘制背景图
sky.step();//背景图滚动
//当游戏是开始状态时
if (start == START)
{
cxt.drawImage(logo,40,0);//添加飞机大战字样的图片
}
//当游戏是载入状态时
else if (start == STARTING)
{
loadImg.paint();//绘制加载图片
loadImg.step();//加载图片运动
}
else if (start == RUNNING)
{
//玩家飞机状态
player.paint();//绘制玩家飞机
player.step();//玩家飞机运动
player.shoot();//玩家飞机射击
//射击子弹状态
bullet_paint();//绘制子弹
bullet_step();//子弹运动
bullet_vanish();//子弹消失
//敌人状态
enermy_create();//敌机产生
enermy_paint();//敌机绘制
enermy_step();//敌机运动
enermy_dash();//敌机毁灭
checkHit();//判断敌机碰撞
//打印玩家得分与生命值
pain_information();
}
//暂停游戏时也要保存当前游戏的状态画面
else if (start == PAUSE)
{
player.paint();
bullet_paint();
enermy_paint();
cxt.drawImage(pause,200,300);
pain_information();
}
//游戏结束状态
else if (start == GAMEOVER)
{
pain_information();
paint_end_game();
}
}
setInterval(main,60);
</script>
</body>
</html>