
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>飞机大战</title>
<style>
div{
text-align: center;
margin: 10px auto;
}
#canfly{
background-color: #999999;
cursor: pointer;
}
body{
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div>
<h3>飞机大战</h3>
<canvas id="canfly" width="480" height="650"></canvas>
</div>
</body>
<script>
(function(){
var canvas = document.getElementById("canfly");
var context = canvas.getContext("2d");
//游戏基础数据
var gameData = {
state : 0,//状态
//游戏状态常量
START : 0,
STARTING : 1,
RUNNING : 2,
PAUSE : 3,
GAMEOVER : 4,
HEROLIFE : 3,
score : 0,
WIDTH : 480,
HEIGHT : 650,
}
//加载背景图片
var bgImg = new Image();
bgImg.src = "images/background.png";
var SKY = {
imgs : bgImg,
width : 480,
height : 650,
}
//startLogo
var startLogo = new Image();
startLogo.src = "images/start.png";
//加载飞机入场动画
var loadings = [];
loadings[0] = new Image();
loadings[0].src = "images/game_loading1.png";
loadings[1] = new Image();
loadings[1].src = "images/game_loading2.png";
loadings[2] = new Image();
loadings[2].src = "images/game_loading3.png";
loadings[3] = new Image();
loadings[3].src = "images/game_loading4.png";
//初始化入场动画图片数据
var LOADING = {
imgs : loadings,
width : 186,
height : 38,
sum : loadings.length//图片个数
}
//加载英雄机
var heros = [];
heros[0] = new Image();
heros[0].src = "images/hero1.png";
heros[1] = new Image();
heros[1].src = "images/hero2.png";
heros[2] = new Image();
heros[2].src = "images/hero_blowup_n1.png";
heros[3] = new Image();
heros[3].src = "images/hero_blowup_n2.png";
heros[4] = new Image();
heros[4].src = "images/hero_blowup_n3.png";
heros[5] = new Image();
heros[5].src = "images/hero_blowup_n4.png";
//初始化英雄机
var HERO = {
imgs : heros,
width : 99,
height : 124,
sum : heros.length,
length : 2
}
//子弹
var bullet = [];
bullet[0] = new Image();
bullet[0].src = "images/bullet1.png";
//初始化子弹
var BULLET = {
imgs : bullet,
width : 8,
height : 21,
sum : bullet.length
}
//加载暂停图片
var paused = new Image();
paused.src = "images/game_pause_nor.png";
//加载敌机图片
var enemies1 = [];//小型飞机
enemies1[0] = new Image();
enemies1[0].src = "images/enemy1.png";
enemies1[1] = new Image();
enemies1[1].src = "images/enemy1_down1.png";
enemies1[2] = new Image();
enemies1[2].src = "images/enemy1_down2.png";
enemies1[3] = new Image();
enemies1[3].src = "images/enemy1_down3.png";
enemies1[4] = new Image();
enemies1[4].src = "images/enemy1_down4.png";
var ENEMY1 = {
imgs : enemies1,
width : 57,
height : 51,
type : 0,//敌机类型
sum : enemies1.length,//爆炸图片个数
length : 1,//正常图片个数
reviseH : 12,//碰撞高度修正
reviseW : 6,//碰撞宽度修正
life : 1,//生命
score : 1//分数
}
var enemies2 = [];//中型飞机
enemies2[0] = new Image();
enemies2[0].src = "images/enemy2.png";
enemies2[1] = new Image();
enemies2[1].src = "images/enemy2_down1.png";
enemies2[2] = new Image();
enemies2[2].src = "images/enemy2_down2.png";
enemies2[3] = new Image();
enemies2[3].src = "images/enemy2_down3.png";
enemies2[4] = new Image();
enemies2[4].src = "images/enemy2_down4.png";
var ENEMY2 = {
imgs : enemies2,
width : 69,
height : 95,
type : 1,//敌机类型
sum : enemies2.length,//爆炸图片个数
length : 1,//正常图片个数
reviseH : 8,//碰撞高度修正
reviseW : 2,//碰撞宽度修正
life : 3,//生命
score : 5//分数
}
var enemies3 = [];//大型飞机
enemies3[0] = new Image();
enemies3[0].src = "images/enemy3_n1.png";
enemies3[1] = new Image();
enemies3[1].src = "images/enemy3_n2.png";
enemies3[2] = new Image();
enemies3[2].src = "images/enemy3_hit.png";
enemies3[3] = new Image();
enemies3[3].src = "images/enemy3_down1.png";
enemies3[4] = new Image();
enemies3[4].src = "images/enemy3_down2.png";
enemies3[5] = new Image();
enemies3[5].src = "images/enemy3_down3.png";
enemies3[6] = new Image();
enemies3[6].src = "images/enemy3_down4.png";
enemies3[7] = new Image();
enemies3[7].src = "images/enemy3_down5.png";
enemies3[8] = new Image();
enemies3[8].src = "images/enemy3_down6.png";
var ENEMY3 = {
imgs : enemies3,
width : 168,
height : 258,
type : 2,//敌机类型
sum : enemies3.length,//爆炸图片个数
length : 2,//正常图片个数
reviseH : 8,//碰撞高度修正
reviseW : 2,//碰撞宽度修正
life : 10,//生命
score : 20//分数
}
//------------------------------//
//创建通用构造器
function Compant(config){
this.imgs = config.imgs;//加载图片
this.width = config.width;
this.height = config.height;
this.sum = config.sum;
this.length = config.length;
//敌机属性
this.type = config.type;//类型
this.life = config.life;//生命值
this.score = config.score;//分数
this.time = 0;//相对速度
this.index = 0;//索引值
this.down = false;//是否执行爆破动画标识
this.canDelete = false;//是否删除标识
//绘制坐标
this.x = 0;
this.y = 0;
//绘制方法
this.paint = function(){
context.drawImage(this.imags[this.index],this.x,this.y);
}
this.step = function(){};//移动方法
this.bang = function(){};//执行撞击后逻辑方法
}
//创建背景图片构造器
function Bgsky(config){
//通用构造器初始化
Compant.call(this,config);///
//绘制高度变量
this.y1 = -this.height;
this.y2 = 0;
//定义绘制方法
this.paint = function(){
context.drawImage(this.imgs,0,this.y1);//第一张图片
context.drawImage(this.imgs,0,this.y2);//第二张图片
}
//背景的运动方法
this.step = function(){
this.time++;
if(this.time % 3 == 0){
this.y1++;//运动到下一帧
this.y2++;
//图片移动至画布后,将y坐标重置为-height,实现图片的连续滚动
this.y1 > this.height && (this.y1 = -this.height);
this.y2 > this.height && (this.y2 = -this.height);
this.time = 1;//垂直移动时间
}
}
}
var sky = new Bgsky(SKY);
//入场动画构造器
function Loading(config){
//调用构造器
Compant.call(this,config);
//定义绘制方法
this.paint = function(){
context.drawImage(this.imgs[this.index],0,gameData.HEIGHT - this.height);
}
//定义入场动画
this.step = function(){
this.time++;
if(this.time % 20 == 0){
this.index++;
if(this.index == this.sum){
gameData.state = gameData.RUNNING;
this.time = 0;
}
}
}
}
var loading = new Loading(LOADING);
//英雄机构造函数
function Hero(config){
Compant.call(this,config);
this.btTime = 0;
this.x = (gameData.WIDTH - this.width)/2;
this.y = gameData.HEIGHT - this.height - 10;
//定义绘制方法
this.paint = function(){
context.drawImage(this.imgs[this.index],this.x,this.y);
}
//定义飞机动画
this.step = function(){
this.time++;
if(this.down){
if(this.time % 15 == 0){
this.index++;
if(this.index >= this.sum){
if(gameData.HEROLIFE > 0){
hero = new Hero(HERO);
this.down = false;
}else{
gameData.state = gameData.GAMEOVER;
}
this.index = this.length;
}
}
}else{
if(this.time % 15 == 0){
this.index++;
this.index %= this.length;
this.time = 0;
}
}
}
//射击方法
this.shoot = function(){
this.btTime++;
if(this.btTime % 25 == 0){
bullets[bullets.length] = new Bullet(BULLET);
this.btTime = 0;
}
}
//撞机方法
this.bang = function(){
if(!this.down){
gameData.HEROLIFE--;
this.down = true;
this.index = this.length;
}
}
}
var hero = new Hero(HERO);
var bullets = [];
//定义子弹构造器
function Bullet(config){
Compant.call(this,config);
//子弹坐标
this.x = hero.x + hero.width/2 - this.width/2;
this.y = hero.y - this.height;
//绘制子弹
this.paint = function(){
context.drawImage(this.imgs[this.index],this.x,this.y);
}
//定义子弹移动
this.step = function(){
this.y -= 1;//子弹移动速度
}
//子弹删除
this.bang = function(){
this.canDelete = true;
}
}
//绘制子弹
function paintBullets(){
for(var i = 0,length = bullets.length;i < length;i++){
bullets[i].paint();//绘制当前子弹
if(gameData.state == gameData.RUNNING){
bullets[i].step();
}
}
}
//清除超出屏幕的子弹
function clearBullet(){
for(var i = bullets.length - 1;i >= 0;i--){
if(bullets[i].y <= bullets[i].height || (bullets[i].canDelete)){
bullets.splice(i,1);//删除
}
}
}
//绘制游戏得分
function paintText(){
context.font = "bold 24px 微软雅黑";
context.fillText("得分:" + gameData.score,10,30);
context.fillText("生命:" + gameData.HEROLIFE,390,30);
}
//绘制暂停图标
function paintPaused(){
context.drawImage(paused,gameData.WIDTH/2 - 30,gameData.HEIGHT/2 - 22.5);
}
//敌机构造器
function Enemy(config){
//调用通用构造器初始化
Compant.call(this,config);
//设置撞击修正
this.reviseH = config.reviseH;
this.reviseW = config.reviseW;
//敌机坐标
this.x = Math.floor(Math.random()*(gameData.WIDTH - this.width));
this.y = -this.height;
//定义绘制方法
this.paint = function(){
context.drawImage(this.imgs[this.index],this.x,this.y);
}
//移动方法
this.step = function(){
if(this.down){//坠机
this.time++;//播放爆炸动画
if(this.time % 15 == 0){
this.index++;
}
if(this.index >= this.sum){//判断动画是否播放完毕
gameData.score += this.score;
this.canDelete = true;
}
}else{//未坠机
//敌机移动
this.time++;
switch(this.type){
case 0://小型飞机
this.y++;
break;
case 1://中型飞机
this.time % 2 == this.y++;
break;
case 2://大型飞机
this.time % 3 == this.y++;
break;
}
//大型飞机动画
this.bigTime++;
if(this.type == 2 && (this.bigTime % 10 == 0)){
this.index = this.index == 0 ? 1 : 0;
this.bigTime = 0;//重置
}
}
}
//判断敌机是否被撞击
this.hit = function(bh){
return (bh.x + bh.width > this.x - this.reviseW) && (bh.y < this.y + this.height - this.reviseH)
&& (bh.x < this.x + this.width + this.reviseW) && (bh.y + bh.height > this.y + this.reviseH);
}
//敌机被撞
this.bang = function(){
if(!this.down && !this.canDelete){
this.life--;
if(this.life <= 0){
this.down = true;
this.index = this.length;//开始执行爆炸动画
}
}
}
}
//创建敌机方法
var enemies = [];//存储敌机
var enemyTime = 0;//敌机出现速度
function createEnemies(){
//生成随机数用于判断飞机类型
var num = Math.floor(Math.random()*100);
if(num < 70){//小型飞机
enemies[enemies.length] = new Enemy(ENEMY1);
}else if(num < 90){//中型飞机
enemies[enemies.length] = new Enemy(ENEMY2);
}else{//大型飞机
if(enemies.length > 0 && enemies[0].type != 2){
enemies.unshift(new Enemy(ENEMY3));//将大型飞机添加到数组开头
}
}
}
//绘制飞机以及删除超出屏幕的飞机
function paintEnemiesAndCheckHIt(){
for(var i = 0;i<enemies.length;i++){
var enemy = enemies[i];
//判断敌机和英雄机是否被击落或飞出屏幕外
if((enemy.y > gameData.HEIGHT) || enemy.canDelete){
enemies.splice(i,1);
continue;
}
//绘制飞机
enemy.paint();
//判断游戏是否正在运行
if(gameData.state == gameData.RUNNING){
enemy.step();
}
//判断是否和英雄机碰撞
if(enemy.hit(hero)){
enemy.bang();
hero.bang();
}
//判断是否被子弹击中
for(var j = 0;j < bullets.length;j++){
var bullet = bullets[j];
if(enemy.hit(bullet)){
enemy.bang();
bullet.bang();
}
}
}
}
//------------------------------//
//画布点击事件
canvas.onclick = function(){
if(gameData.state == gameData.START){
gameData.state = gameData.STARTING;
}
}
//画布绑定鼠标移动事件 - 控制飞机移动
canvas.onmousemove = function(event){
//获取鼠标当前坐标
var x = event.offsetX;
var y = event.offsetY;
//设置飞机坐标
hero.x = x - hero.width/2;
hero.y = y - hero.height/2;
if(gameData.state == gameData.PAUSE){
gameData.state = gameData.RUNNING;
}
}
//鼠标移出游戏界面暂停事件
canvas.onmouseout = function(){
if(gameData.state == gameData.RUNNING){
gameData.state = gameData.PAUSE;
}
}
function gameOver(){
context.font = "bold 45px 微软雅黑";
context.fillText("Game Over",gameData.WIDTH/2 - 150,gameData.HEIGHT/2);
}
//-----------------------------//
//初始化飞机大战方法
function init(){
//执行游戏
gameExec();
}
//游戏执行函数
function gameExec(){
//背景
sky.paint();
sky.step();
enemyTime++;//敌机创建的速度
switch(gameData.state){
case gameData.START:
context.drawImage(startLogo,30,0);
break;
case gameData.STARTING://进场动画加载
loading.paint();
loading.step();
break;
case gameData.RUNNING:
//加载飞机
hero.paint();
hero.step();
//绘制子弹
hero.shoot();
paintBullets();
//创建飞机
if(enemyTime % 100 == 0){
createEnemies();
}
//绘制所有地方飞机和碰撞检测
paintEnemiesAndCheckHIt();
//清除子弹
clearBullet();
break;
case gameData.PAUSE:
//绘制飞机
hero.paint();
//绘制子弹
paintBullets();
//绘制暂停图片
paintPaused();
break;
case gameData.GAMEOVER:
gameOver();
break;
}
//绘制得分
paintText();
//定时执行
setTimeout(function(){
gameExec();
},8);
}
//执行初始化方法
init();
})()
</script>
</html>