<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
canvas{
display: block;
margin: 100px auto;
}
</style>
</head>
<body>
<canvas id="canvas" width="480px" height="650px"></canvas>
<script type="text/javascript">
// 前提
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
// 0.游戏初始化
// 0.1 将游戏分为几个阶段
var START = 0; //第一个阶段 游戏开始阶段
var STARTING = 1; //第二个阶段 游戏运行前的动画阶段
var RUNNING = 2; //第三个阶段 游戏运行阶段
var PAUSE = 3; //第四个阶段 游戏暂停阶段
var GAMEOVER = 4; //第五个阶段 游戏结束阶段
// 0.2 定义自己的状态,跟上面比较,判断游戏处于哪一个阶段
var state = START;
// 0.3 定义当前画布的宽和高
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
// 0.4 定义游戏的得分
var score = 0;
// 0.5 定义我方飞机的生命值
var life = 3;
// 1.游戏开始阶段
// 1.1 加载背景图片
// 1.1.1 创建背景图片的对象
var bg = new Image();
bg.src = "images/background.png";
// 1.1.2 初始化背景图片的数据
var BG = {
imgs : bg,
width : 480,
height : 852
}
// 1.1.3 创建背景图片的 构造器 函数(构造出一个对象)
function Bg(config){
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(){
context.drawImage(this.imgs,this.x1,this.y1);
context.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;
}
}
}
// 1.1.4 创建背景图片的对象
var sky = new Bg(BG)
// 1.2 绘制logo
var logo = new Image();
logo.src = "images/start.png"
// 2.游戏运行前动画阶段
// 2.1 加载动画所需要的图片
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";
// 2.2 初始化图片的数据
var LOADINGS = {
imgs : loadings,
length : loadings.length,
width : 186,
height : 38
}
// 2.3定义开始前动画的构造器
function Loading(config){
this.imgs = config.imgs;
this.length = config.length;
this.width = config.width;
this.height = config.height;
// 定义索引,判断显示对应的图片
this.startIndex = 0;
// 定义绘制方法
this.paint = function(){
context.drawImage(this.imgs[this.startIndex],0,HEIGHT-this.height);
}
// 定义运动的方法
this.time = 0;
this.step = function(){
this.time ++;
if(this.time % 3 == 0){
this.startIndex ++;
}
if(this.startIndex == this.length){ //如果索引等于长度的时候,就要进入下一个状态
state = RUNNING; //游戏进入第三个阶段
}
}
}
// 2.4创建游戏运行前动画的对象
var loading = new Loading(LOADINGS);
// 2.5 第一个阶段的时候,点击画布,切换到第二个阶段
canvas.onclick = function(){
// 判断,如果为第一阶段的时候点击,才OK
if(state == START){
state = STARTING;
}
}
// 3. 游戏运行阶段
// 3.1 绘制我方飞机
// 3.1.1 加载我方飞机所需要用到的图片
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";
// 3.1.2 初始化我方飞机的数据
var HEROS = {
imgs : heros,
length : heros.length,
width : 99,
height : 124,
frame : 2 //我方飞机有两种状态,增加标识
}
// 3.1.3 我方飞机的构造器
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; //false表示没有撞击
// 定义状态看是否爆破完成
this.candel = false;
// 定义绘制的方法
this.paint = function(){
context.drawImage(this.imgs[this.startIndex],this.x,this.y);
}
// 定义运动的方法
this.step = function(){
// 两个状态
// 1.正常运动状态
// 2.碰撞以后的状态
if(!this.down){ //正常运动的状态
// 没有撞击的时候,角标在0和1之间进行切换即可
if(this.startIndex == 0){
this.startIndex = 1;
}else{
this.startIndex = 0;
}
}else{ //撞击以后的状态
// 角标就要不停的增加,模拟出动画
this.startIndex ++;
// 判断是否撞击完成
if(this.startIndex == this.length){
life --;
if(life == 0){
state = GAMEOVER;
// 如果死了,要让动画留到最后一张的爆破图片
this.startIndex = this.length - 1;
}else{
// 撞击以后,所有属性全都重置,最简单就是直接new
hero = new Hero(HEROS);
}
}
}
}
// 飞机的碰撞方法
this.bang = function(){
this.down = true;
}
// 增加射击的方法
this.time = 0;
this.shoot = function(){
this.time ++;
if(this.time % 3 == 0){
bullets.push(new Bullet(BULLET))
}
}
}
// 3.1.4 创建我方飞机的对象
var hero = new Hero(HEROS);
// 3.1.5 增加移动事件
canvas.onmousemove = function(event){
// console.log(event.offsetX)
var event = event || window.event;
if(state == RUNNING){
hero.x = event.offsetX - hero.width / 2;
hero.y = event.offsetY - hero.height /2;
}
}
// 3.2 绘制子弹
// 3.2.1 创建子弹的图片
var bullet = new Image();
bullet.src = "images/bullet1.png";
// 3.2.2 初始化子弹的数据
var BULLET = {
imgs : bullet,
width : 9,
height : 21
}
// 3.2.3 创建子弹的构造
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(){
context.drawImage(this.imgs,this.x,this.y);
};
// 运动方法
this.step = function(){
this.y -= 10;
}
// 增加碰撞属性
this.candel = false; //false表示没有碰撞
// 增加碰撞方法
this.bang = function(){
this.candel = true;
}
}
// 3.2.4 所有new 的子弹对象全都放到一个数组中去
var bullets = [];
// 3.2.5 遍历 - 绘制子弹
function bulletsPaint(){
for(var i = 0;i < bullets.length;i++){
bullets[i].paint()
}
}
// 3.2.6 遍历 - 绘制子弹的运动
function bulletsStep(){
for(var i = 0;i < bullets.length;i++){
bullets[i].step()
}
}
// 3.2.7 子弹的删除
function bulletsDel(){
// 子弹删除:
// 1.碰撞
// 2.超出画布 y < -子弹的高度 ?
for(var i = 0;i < bullets.length;i++){
if(bullets[i].candel || bullets[i].y < -bullets[i].height){
bullets.splice(i,1); //第一个参数是选定位置,第二个参数删除几个
}
}
}
// 3.3 绘制敌方飞机
// 3.3.1 加载敌方飞机的图片
var enemy1 = []; //小飞机
enemy1[0] = new Image();
enemy1[0].src = "images/enemy1.png"
enemy1[1] = new Image();
enemy1[1].src = "images/enemy1_down1.png"
enemy1[2] = new Image();
enemy1[2].src = "images/enemy1_down2.png"
enemy1[3] = new Image();
enemy1[3].src = "images/enemy1_down3.png"
enemy1[4] = new Image();
enemy1[4].src = "images/enemy1_down4.png"
var enemy2 = []; //中飞机
enemy2[0] = new Image();
enemy2[0].src = "images/enemy2.png"
enemy2[1] = new Image();
enemy2[1].src = "images/enemy2_down1.png"
enemy2[2] = new Image();
enemy2[2].src = "images/enemy2_down2.png"
enemy2[3] = new Image();
enemy2[3].src = "images/enemy2_down3.png"
enemy2[4] = new Image();
enemy2[4].src = "images/enemy2_down4.png"
var enemy3 = []; //大飞机
enemy3[0] = new Image();
enemy3[0].src = "images/enemy3_n1.png"
enemy3[1] = new Image();
enemy3[1].src = "images/enemy3_n2.png"
enemy3[2] = new Image();
enemy3[2].src = "images/enemy3_down1.png"
enemy3[3] = new Image();
enemy3[3].src = "images/enemy3_down2.png"
enemy3[4] = new Image();
enemy3[4].src = "images/enemy3_down3.png"
enemy3[5] = new Image();
enemy3[5].src = "images/enemy3_down4.png"
enemy3[6] = new Image();
enemy3[6].src = "images/enemy3_down5.png"
enemy3[7] = new Image();
enemy3[7].src = "images/enemy3_down6.png"
// 3.3.2 初始化敌方飞机的数据
var ENEMY1 = {
imgs : enemy1,
length : enemy1.length,
width: 57,
height : 51,
type : 1,
frame : 1,
life : 2,
score : 2
}
var ENEMY2 = {
imgs : enemy2,
length : enemy2.length,
width: 69,
height : 95,
type : 2,
frame : 1,
life : 4,
score : 8
}
var ENEMY3 = {
imgs : enemy3,
length : enemy3.length,
width: 165,
height : 261,
type : 3,
frame : 2,
life : 14,
score : 20
}
// 3.3.3 敌方飞机的构造
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(){
context.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;
}
}
}
// 3.3.4 创建数组,用于存放敌方飞机
var enemies = [];
// 3.3.5 往数组中去添加飞机
function enterEnemise(){
var rand = Math.floor(Math.random() * 100);
if(rand < 10){ //添加小飞机
enemies.push(new Enemy(ENEMY1))
}else if(rand < 55 && rand > 50){
enemies.push(new Enemy(ENEMY2))
}else if(rand == 88){
// 大飞机有且只能有一个
// 把大飞机放在数组的第一位
if(enemies[0].type != 3 && enemies.length > 0){
enemies.splice(0,0,new Enemy(ENEMY3))
}
}
}
// 3.3.6 创建函数 绘制敌方飞机
function paintEnemise(){
for(var i = 0;i< enemies.length;i++){
enemies[i].paint();
}
}
// 3.3.7 创建函数 绘制敌方飞机运动
function stepEnemise(){
for(var i = 0;i< enemies.length;i++){
enemies[i].step();
}
}
// 3.3.8 创建函数,用于删除飞机
function delEnemise(){
for(var i = 0;i< enemies.length;i++){
if(enemies[i].y > HEIGHT || enemies[i].candel){
enemies.splice(i,1)
}
}
}
// 3.4 绘制碰撞以后的函数
function hitEnemise(){
for(var i = 0;i< enemies.length;i++){
// 如果我方飞机撞到了敌方飞机以后
if(enemies[i].checkHit(hero)){
// 处理敌方飞机碰撞以后的逻辑
enemies[i].bang();
// 处理我方飞机碰撞以后的逻辑
hero.bang()
}
// 子弹如果碰到敌方飞机以后
for(var j = 0;j<bullets.length;j++){
if(enemies[i].checkHit(bullets[j])){
enemies[i].bang();
// 子弹的碰撞逻辑
bullets[j].bang()
}
}
}
}
// 3.5 绘制得分和我方飞机的生命值
function paintText(){
context.font = "bold 30px 微软雅黑"
context.fillText("SCORE:" + score,10,30);
context.fillText("LIFE:" + life,380,30 )
}
// 4.游戏暂停阶段
canvas.onmouseover = function(){
if(state == PAUSE){
state = RUNNING
}
}
canvas.onmouseout = function(){
if(state == RUNNING){
state = PAUSE
}
}
var pause = new Image();
pause.src="images/game_pause_nor.png";
// 5.GAMEOVER文本
function paintOver(){
context.font = "bold 40px 微软雅黑"
context.fillText("GAME OVER!!!",100,300)
}
setInterval(function(){
// 因为背景图片时刻都在运动
sky.paint();
sky.step();
if(state == START){
context.drawImage(logo,30,0)
}else if(state == STARTING){
loading.paint();
loading.step();
}else if(state == RUNNING){
// 我方飞机的绘制
hero.paint();
// 我方飞机的运动
hero.step();
// 我方飞机的射击方法
hero.shoot();
// 绘制子弹
bulletsPaint();
// 绘制子弹的运动
bulletsStep();
// 删除子弹
bulletsDel()
// 创建敌方飞机
enterEnemise()
// 绘制敌方飞机
paintEnemise()
// 绘制敌方飞机的运动
stepEnemise()
// 敌方飞机的删除
delEnemise()
// 是否撞击
hitEnemise()
// 绘制文字
paintText()
}else if(state == PAUSE){
hero.paint();
bulletsPaint();
paintEnemise()
paintText()
context.drawImage(pause,200,300)
}else if(state == GAMEOVER){
hero.paint();
bulletsPaint();
paintEnemise()
paintText()
paintOver()
}
},50)
</script>
</body>
</html>
飞机大战源码
猜你喜欢
转载自blog.csdn.net/weixin_42940821/article/details/82257057
今日推荐
周排行