对象:主机、子弹、敌机
动画:画、动
碰撞:主机碰撞敌机、子弹碰撞敌机(像素碰撞--性能问题)
玩法、声音:(选做)
普通碰撞
图片预加载
var imgArr = {
"bg":"img/background.png",
"herofly":"img/herofly.png",
"bullet1":"img/bullet1.png",
"bullet2":"img/bullet2.png",
"enemy1":"img/enemy1.png",
"enemy2":"img/enemy2.png",
"enemy3":"img/enemy3.png",
"prop":"img/prop.png"
};
var imgLength = 0;
for(var i in imgArr){
imgLength++;
}
var loadArr = {};
var num = 0;
for(let i in imgArr){
var img = new Image();
img.src = imgArr[i];
img.onload = function(){
loadArr[i] = this;
num++;
if(num>=imgLength){
main(loadArr);
}
}
}
function main(loadArr){
var canvas = document.getElementById("mycanvas");
var context = canvas.getContext("2d");
canvas.width = loadArr.bg.width;
canvas.height = loadArr.bg.height;
var alive = document.querySelector("#progress div");
var aliveStyle =alive.currentStyle ? alive.currentStyle : window.getComputedStyle(alive,null);
var scoreObj = document.querySelector("#score span");
var score = 0;
//主机对象构造函数
function Hero(x,y,blood,obj){
this.x = x;
this.y = y;
this.blood = blood;
this.obj = obj;
this.w = loadArr.herofly.width/5;
this.h = loadArr.herofly.height;
this.index = 0;
this.num = 0;
this.dis = "";
}
Hero.prototype.draw = function(){
this.num++;
//主机爆炸
if(this.blood<=0){
if(this.num%10 == 0){
this.index++;
}
}
context.drawImage(this.obj,(loadArr.herofly.width/5)*this.index,0,this.w,this.h,this.x,this.y,this.w,this.h);
}
Hero.prototype.move = function(){
switch(this.dis){
case "right":
this.x+=3;
if(this.x>=canvas.width-this.w){
this.x = canvas.width-this.w;
}
break;
case "left":
this.x-=3;
if(this.x<=0){
this.x=0;
}
break;
case "up":
this.y-=3;
if(this.y<=0){
this.y = 0;
}
break;
case "down":
this.y+=3;
if(this.y>=canvas.height - this.h){
this.y = canvas.height-this.h;
}
break;
default:
break;
}
}
//子弹对象构造函数
function Bullet(x,y,power,obj,speed){
this.x = x;
this.y = y;
this.power = power;
this.obj = obj;
this.w = obj.width;
this.h = obj.height;
this.speed = speed;
}
Bullet.prototype.draw = function(){
context.drawImage(this.obj,0,0,this.w,this.h,this.x,this.y,this.w,this.h)
}
Bullet.prototype.move = function(){
this.y -= this.speed;
for(var j=0;j<enemy.length;j++){
//子弹与敌机碰撞
if(this.x<enemy[j].x+enemy[j].w&&this.x+this.w>enemy[j].x&&this.y<enemy[j].y+enemy[j].h&&this.y+this.h>enemy[j].y){
var auEnemy = new Audio();
auEnemy.autoplay = "autoplay";
if(enemy[j].count==5){
enemy[j].blood-=30;
auEnemy.src = "audio/enemy1_down.mp3";
}else if(enemy[j].count == 6){
enemy[j].blood -=25;
auEnemy.src = "audio/enemy2_down.mp3";
}else if(enemy[j].count == 10){
enemy[j].blood -= 10;
auEnemy.src = "audio/enemy3_down.mp3";
}
document.getElementsByTagName("body")[0].appendChild(auEnemy);
setTimeout(function(){
auEnemy.remove();
},1000)
if(enemy[j].count>3){
this.y = -this.h;
}
if(enemy[j].index>=enemy[j].count-2&&enemy[j].count>3){
if(enemy[j].count == 5){
score += 10;
}else if(enemy[j].count == 6){
score += 20;
}else if(enemy[j].count == 10){
score += 30;
}
enemy[j].y = canvas.height;
// console.log(scoreObj.innerHTML);
}
}
}
}
//清除子弹
Bullet.prototype.isClear = function(){
if(this.y<=-this.h){
return true;
}else{
return false;
}
}
//敌机对象构造函数
function Enemy(obj,x,y,w,h,speed){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.obj = obj;
this.speed = speed;
this.blood = 100;
this.index = 0;
this.num = 0;
this.count = 0;
}
Enemy.prototype.draw = function(){
this.num++;
if(this.blood<=50&&this.count>3){
if(this.num%3==0){
this.index++;
}
}
context.drawImage(this.obj,this.index*this.w,0,this.w,this.h,this.x,this.y,this.w,this.h);
}
Enemy.prototype.move = function(){
this.y += this.speed;
//敌机与主机碰撞
if(this.x<newHero.x+newHero.w&&this.x+this.w>newHero.x&&this.y<newHero.y+newHero.h&&this.y+this.h>newHero.y){
if(isHero){
if(_this.count>3){
newHero.blood -= 20;
alive.style.width = parseInt(aliveStyle.width) - 30 +"px";
isHero = false;
}else{
if(_this.count == 0){
bulletObj = loadArr.bullet1;
for(var k=0;k<enemy.length;k++){
enemy[k].y = canvas.height;
if(enemy[k].count == 1){
bulletObj = loadArr.bullet2;
}else if(enemy[k].count == 2){
if(newHero.blood < 100){
newHero.blood +=20;
alive.style.width = parseInt(aliveStyle.width) + 30 +"px";
}
}else if(enemy[k].count == 5){
score += 10;
}else if(enemy[k].count == 6){
score += 20;
}else if(enemy[k].count == 10){
score += 30;
}
}
}else if(_this.count == 1){
bulletObj = loadArr.bullet2;
}else if(_this.count == 2){
if(newHero.blood < 100){
newHero.blood +=20;
alive.style.width = parseInt(aliveStyle.width) + 30 +"px";
}
}
}
}
_this.y = canvas.height;
}
}
Enemy.prototype.isClear = function(){
if(this.y>=canvas.height){
return true;
}else{
return false;
}
}
//主机实例化
var x = 120;
var y = canvas.height-loadArr.herofly.height;
newHero = new Hero(x,y,100,loadArr.herofly);
console.log(newHero);
newHero.draw();
//键盘控制上下左右
document.onkeydown = function(e){
var ev = window.event || e;
switch(ev.keyCode){
case 37:
newHero.dis = "left";
break;
case 38:
newHero.dis = "up";
break;
case 39:
newHero.dis = "right";
break;
case 40:
newHero.dis = "down";
break;
default:
newHero.dis="";
break;
}
}
document.onkeyup = function(){
newHero.dis = "";
}
//子弹实例化
bulletObj = loadArr.bullet1;
var newBullet = new Bullet(newHero.x+(newHero.w/2)-bulletObj.width/2,y-10,2,loadArr.bullet1,2);
newBullet.draw();
//存放子弹的容器
bullet = [];
enemy = [];
var count = 0;
var bgY = 0;
isHero = true;
function act(){
count++;
//清空画布
context.clearRect(0,0,canvas.width,canvas.height);
//背景
drawBg();
//主机
newHero.draw();
newHero.move();
//敌机
if(count%60==0){
var rand = randNum(0,11);
// console.log(rand);
if(rand<=5){
var enemyW = loadArr.enemy1.width/5;
var enemyX = randNum(0,canvas.width-enemyW+1);
var newEnemy = new Enemy(loadArr.enemy1,enemyX,-loadArr.enemy1.height,enemyW,loadArr.enemy1.height,3);
newEnemy.count = 5;
}else if(rand>5 && rand<8){
var enemyW = loadArr.enemy2.width/6;
var enemyX = randNum(0,canvas.width-enemyW+1);
var newEnemy = new Enemy(loadArr.enemy2,enemyX,-loadArr.enemy2.height,enemyW,loadArr.enemy2.height,2);
newEnemy.count = 6;
}else if(rand==8){
var enemyW = loadArr.enemy3.width/10;
var enemyX = randNum(0,canvas.width-enemyW+1);
var newEnemy = new Enemy(loadArr.enemy3,enemyX,-loadArr.enemy3.height,enemyW,loadArr.enemy3.height,1);
newEnemy.count = 10;
}else{
var rands = randNum(0,3);
var enemyW = loadArr.prop.width/3;
var enemyX = randNum(0,canvas.width-enemyW+1);
var newEnemy = new Enemy(loadArr.prop,enemyX,-loadArr.prop.height,enemyW,loadArr.prop.height,2);
newEnemy.count = rands;
newEnemy.index = rands;
}
enemy.push(newEnemy);
}
for(var i=0;i<enemy.length;i++){
enemy[i].draw();
enemy[i].move();
if(enemy[i].isClear()){
//判断是否出界清除
enemy.splice(i,1);
isHero = true;
}
}
//子弹
if(count%20==0){
var newBullet = new Bullet(newHero.x+(newHero.w/2)-bulletObj.width/2,newHero.y-10,2,bulletObj,2);
bullet.push(newBullet);
var audios = new Audio();
audios.src = "audio/bullet.mp3";
audios.autoplay = "autoplay";
document.getElementsByTagName("body")[0].appendChild(audios);
setTimeout(function(){
audios.remove();
},100)
}
for(var i=0;i<bullet.length;i++){
bullet[i].draw();
bullet[i].move();
if(bullet[i].isClear()){
bullet.splice(i,1);
}
}
scoreObj.innerHTML = score;
var res = window.requestAnimationFrame(act);
if(newHero.index>=4){
cancelAnimationFrame(res);
document.getElementById("mask").style.display = "block";
document.querySelector("#mask audio").autoplay = "autoplay";
document.querySelector("#gameStart").autoplay = "";
document.querySelector("#endScore span").innerHTML = score;
}
}
act();
function drawBg(){
//画背景
bgY++;
if(bgY>canvas.height){
bgY=0;
}
context.drawImage(loadArr.bg,0,bgY);
context.drawImage(loadArr.bg,0,bgY-canvas.height);
}
}
随机函数
function randNum(min,max){
return parseInt(Math.random()*(max-min)+min);
}