<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
margin: 0 auto;
width: 480px;
height: 650px;
background-color: #323232;
text-align: center;
}
</style>
</head>
<body>
<div>
<canvas id="canvas" width="480" height="650"></canvas>
</div>
<script>
var canvas = document.getElementById("canvas")
var context = canvas.getContext("2d")
// 0 游戏初始化
// 0.1 定义游戏划分为5个阶段
var START = 0;//游戏初始阶段
var STARTING = 1;//游戏加载阶段
var RUNNING = 2;//游戏运行阶段
var PAUSE = 3;//游戏暂停阶段
var GAMEOVER = 4;//游戏结束阶段
// 0.2 定义一个标示,标示当前游戏处在什么阶段
var state = START;
// 0.3 定义当前画布高度和宽度
var WIDTH = 480;
var HEIGHT = 650;
// 0.4 定义游戏得分和我方飞机生命值
var score = 0;
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+=2;
this.y2+=2;
// 判断两张图片的临界值
// if(this.y1 == HEIGHT){
// this.y1 = -(this.height - HEIGHT + this.height);
// }
// if(this.y2 == HEIGHT){
// this.y2 = -(this.height - HEIGHT + this.height);
// }
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],147,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);
console.log(loading)
// 2.5 为canvas元素绑定点击事件从第一阶段进入第二阶段
canvas.onclick = function(){
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;
// 定义我方飞机的绘制方法
this.paint = function(){
context.drawImage(this.imgs[this.startIndex],this.x,this.y)
}
// 定义我方飞机的运动
this.step = function(){
if(!this.down){
// 未被撞击 startIndex的值在0和1之前进行切换
// if(this.startIndex == 0){
// this.startIndex = 1
// }else{
// this.startIndex = 0
// }
this.startIndex ++;
this.startIndex = this.startIndex % 2;
}else{
// 1. 切换的下标
this.startIndex ++;
// 2. 判断是否执行完
if(this.startIndex == this.length){
life--;
if(life == 0){
state = GAMEOVER;
this.startIndex = this.length - 1;
}else{
hero = new Hero(HEROS);
}
}
}
}
this.time = 0;
// 增加射击的方法
this.shoot = function(){
this.time++;
if(this.time % 3 == 0){
bullets.push(new Bullet(BULLET))
}
}
// 新增bang方法
this.bang = function(){
this.down = true;
}
}
// 3.1.4 创建我方飞机的对象
var hero = new Hero(HEROS);
// 3.1.5 为canvas绑定移动事件
canvas.onmousemove = function(e){
if(state == RUNNING){
// pageX/clientX/offsetX
var x = e.offsetX;
var y = e.offsetY;
// 修改我方飞机坐标值
hero.x = x - hero.width / 2;
hero.y = y - 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 - 10;
// 绘制
this.paint = function(){
context.drawImage(this.imgs,this.x,this.y)
}
// 运动方法
this.step = function(){
this.y -= 10;
}
this.candel = false;
// 新增的方法 - 用于处理子弹撞击的逻辑
this.bang = function(){
this.candel = true;
}
}
// 3.2.4 创建存储子弹的数组
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(){
for(var i = 0 ; i < bullets.length;i++){
// 判断子弹的y值 < - 子弹高度
if(bullets[i].y < -bullets[i].height || bullets[i].candel){
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 : 1,
score : 1
}
var ENEMY2 = {
imgs : enemy2,
length : enemy2.length,
width : 69,
height : 95,
type : 2,
frame : 1,
life : 3,
score : 3
}
var ENEMY3 = {
imgs : enemy3,
length : enemy3.length,
width : 165,
height : 261,
type : 3,
frame : 2,
life : 20,
score : 10
}
// 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之间切换
// if(this.type == 1 || this.type == 2){
// this.startIndex = 0
// }else if(this.type == 3){
// this.startIndex ++;
// this.startIndex %= 2;
// }
this.startIndex ++;
this.startIndex = this.startIndex % this.frame;
// 敌方飞机向下运动
this.y += 2;
}else{
// 被撞击
// 小和中飞机 1 2 3 4 大飞机 2 3 4 5 6 7
this.startIndex ++;
if(this.startIndex == this.length){
this.candel = true;
this.startIndex = this.length - 1;
}
}
}
// 增加用于检查敌机是否被撞击的方法
this.checkHit = function(wo){
// 参数wo 1 我方飞机hero 2 子弹bullet
return wo.y + wo.height > this.y &&
wo.y < this.y + this.height &&
wo.x + wo.width > this.x &&
wo.x < this.x + this.width
}
// 新增的bang方法 - 用于被撞击后的逻辑
this.bang = function(){
this.life --;
if(this.life == 0){
this.down = true;
score += this.score;
}
}
}
// 3.3.4 创建数组 - 用于存储所有敌方飞机
var enemies = []
function enterEnemies(){
var rand = Math.floor(Math.random()*100)
if(rand <= 7){
// 小飞机
enemies.push(new Enemy(ENEMY1))
}else if(rand == 8){
// 中飞机
enemies.push(new Enemy(ENEMY2))
}else if(rand == 9){
// 大飞机 只允许数组中第一个元素为大飞机
if(enemies[0].type != 3 && enemies.length > 0){
enemies.splice(0,0,new Enemy(ENEMY3))
}
}
}
// 3.3.5 创建函数,用于绘制所有的敌方飞机
function enemyPaint(){
for(var i = 0 ; i < enemies.length;i++){
enemies[i].paint()
}
}
// 3.3.6 创建函数,用于控制敌方飞机运动
function enemyStep(){
for(var i = 0 ; i < enemies.length;i++){
enemies[i].step()
}
}
// 3.3.7 创建函数,用于删除敌方飞机
function enemyDel(){
for(var i = 0 ; i < enemies.length;i++){
// 敌方飞机 > 画布的高度
if(enemies[i].y > HEIGHT || enemies[i].candel){
enemies.splice(i,1)
}
}
}
// 3.4 创建函数 - 用于检查所有的撞击情况
function hitEnemies(){
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 painText(){
context.font = "bold 24px 微软雅黑"
context.fillText("SCORE:" + score,10,30)
context.fillText("LIFE:" + life,400,30)
}
// 4 游戏暂停阶段
canvas.onmouseover = function(){
// 从暂停恢复到运行
if(state == PAUSE){
state = RUNNING;
}
}
canvas.onmouseleave = function(){
// 从运行切换到暂停
if(state == RUNNING){
state = PAUSE;
}
}
var pause = new Image()
pause.src = "images/game_pause_nor.png"
// 定义游戏的控制器
setInterval(function(){
// 1 绘制背景图片
sky.paint()
// 2 控制背景运动
sky.step()
switch (state){
case START :
// 3 绘制logo
context.drawImage(logo,40,0)
break;
case STARTING :
loading.paint()
loading.step()
break;
case RUNNING :
hero.paint()
hero.step()
hero.shoot()
bulletsPaint()
bulletsStep()
bulletsDel()
enterEnemies()
enemyPaint()
enemyStep()
enemyDel()
hitEnemies()
painText()
break;
case PAUSE :
hero.paint()
bulletsPaint()
enemyPaint()
painText()
context.drawImage(pause,WIDTH / 2 - 30,HEIGHT / 2 - 23)
break;
case GAMEOVER :
hero.paint()
bulletsPaint()
enemyPaint()
painText()
context.font = "bold 48px 微软雅黑"
context.fillText("GAME OVER",WIDTH / 2 - 120,HEIGHT / 2)
break;
}
},100)
</script>
</body>
</html>
canvas实训之飞机大战
最新推荐文章于 2024-07-23 16:10:02 发布