canvas实现雷电系列游戏
本人第一次写博文,如有表达不当或是书写不规范的地方请大家细心指出.
1.首先确定游戏上的元素-飞机,子弹. 我把它们 归为一类 -飞行单位类:
force-势力方
type-单位类型
x,y- 坐标
valid-是否有效,在删除单位时有用
damage-撞击后造成的伤害
hp-单位血量
fireType-如果是飞机 则可以发射的子弹类型
fireInterval-发射子弹的间隔
interval-发射子弹的当前间隔
//飞行单位
var Fly=function(force,type){
var self=this;
self.force=force;
self.type=type;
self.x=0;
self.y=0;
self.valid=true;
self.damage=0;
self.hp=0;
self.fireType=-1;
self.fireInterval=-1;
switch(type.toString()){
case '0':
self.damage=100;
self.hp=1;
self.fireType=101;
self.fireInterval=35;
self.interval=35;
self.range=5;
break;
case '2':
//controller
self.damage=100;
self.hp=20;
self.fireType=100;
self.fireInterval=35;
self.interval=35;
self.range=10;
break;
case '3':
self.damage=100;
self.hp=15;
self.fireType=104;
self.fireInterval=100;
self.interval=100;
self.range=25;
break;
case '4':
self.damage=10;
self.hp=5;
self.fireType=101;
self.fireInterval=40;
self.interval=40;
self.range=20;
break;
case '5':
//boss
self.damage=1000;
self.hp=100;
self.fireType=105;
self.fireInterval=20;
self.interval=20;
self.range=100;
break;
case '100':
self.damage=1;
self.hp=1;
break;
case '101':
self.damage=1;
self.hp=1;
break;
case '104':
self.damage=10;
self.hp=2;
break;
case '105':
self.damage=10;
self.hp=1;
break;
}
}
2.针对飞行单位,有以下方法:
1)初始化坐标
2)绘制单位
3)死亡动画
4)自动移动过程
Fly.prototype={
initPos:function(x,y){
if(this.force==1){
this.x=gameWidth/2;
this.y=gameHeight-30;
}else{
this.x=x||(gameWidth/2);
this.y=y-(this.range||0)||-50;
}
},
draw:function(){
if(!this.valid)return;
switch(this.type.toString()){
case '0'://实心圆
ctx.strokeStyle = "#000000";
ctx.fillStyle = "#000000";
ctx.beginPath();
ctx.arc(this.x, this.y, 5, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
break;
case '2'://正三角
ctx.drawImage(imgList[0], this.x-26, this.y-25);
break;
case '3':
//61 26
ctx.drawImage(imgList[1], this.x-30, this.y-13);
break;
case '4':
ctx.drawImage(imgList[2], this.x-20, this.y-20);
break;
case '5':
ctx.drawImage(imgList[3],this.x-100,this.y-100);
break;
case '100'://竖形子弹
case '101'://竖形子弹
ctx.fillStyle="Red";
ctx.fillRect(this.x-1,this.y-2,2,4);
break;
case '104':
ctx.fillStyle="#126116";
ctx.beginPath();
ctx.moveTo(this.x-5,this.y);
ctx.lineTo(this.x+5,this.y);
ctx.lineTo(this.x,this.y+6);
ctx.lineTo(this.x-5,this.y);
ctx.closePath();
ctx.fill();
break;
case '105':
ctx.drawImage(imgList[4],this.x-7,this.y-7);
break;
default:
break;
}
},
die:function(){
this.valid=false;
//动画
//略过
if(this.type==101)
return;
ctx.fillStyle="#FF0000";
ctx.beginPath();
ctx.arc(this.x,this.y,6,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
var self=this;
var time=0;
var i=setInterval(function(){
var tm=(Math.floor(255*time/10)).toString(16);
ctx.fillStyle='#FF'+tm+tm;
ctx.beginPath();
ctx.arc(self.x,self.y,6+time/8,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
if(time++==80)
clearInterval(i);
},13);
},
autoMove:function(){
switch(this.type.toString()){
case '0':
case '2':
case '3':
case '4':
if(this.force=='1'){
}else{
this.y+=2;
if(this.y>gameHeight+10)
this.valid=false;
}
break;
case '5':
//boss
if(this.y<50){
this.y+=2;
}else{
this.x=gameWidth/2+gameWidth/3*Math.sin((bossMoveTimer++)/30);
}
break;
case '100':
this.y-=10;
if(this.y<-10)
this.valid=false;
break;
case '101':
case '104':
if(this.force=='1'){
this.y-=3;
if(this.y<-10)
this.valid=false;
}else{
this.y+=5;
if(this.y>gameHeight+10)
this.valid=false;
}
break;
case '105':
if(this.force=='1'){
//[*]
}else{
this.y+=4;
this.x+=Math.sin((bulletMoveTimer++)/50)*10;
if(this.y>gameHeight+10)
this.valid=false;
}
break;
default:
break;
}
}
}
3.游戏的主流程是一个循环控制过程.
//循环 函数
function step() {
gameTime+=30;
controllerManager();
enemyManager();
bulletManager();
damageManager();
ReDraw();
}
其中controllerManager()进行控制者操作,如方向的移动,子弹的发射等.
//控制者处理
function controllerManager(){
//方向
if(direction.l){
controller.x-=2;
}
if(direction.r){
controller.x+=2;
}
if(direction.t){
controller.y-=2;
}
if(direction.d){
controller.y+=2;
}
if(direction.l==direction.r&&direction.t==direction.d)
return;
}
enemyManager()进行地方单位的操作,如添加敌方单位,敌方单位子弹发射,敌方单位的位置移动等.我用了一个json结构来表示游戏进程,key-是游戏的时间,value-是加入的地方单位的类型
//敌方单位处理
function enemyManager(){
var tm=Process[Math.floor(gameTime/1000)];
if(tm){
//添加敌方单位
for(var i in tm){
var e=new Fly(2,tm[i]);
e.initPos(gameWidth/(tm.length+1)*(parseInt(i)+1));
enemy.push(e);
}
Process[Math.floor(gameTime/1000)]=null;
}
for(var i in enemy){
if(enemy[i]){
enemy[i].autoMove();
if(!enemy[i].valid){
enemy[i]=null;
}else{
//fire
if(enemy[i].y<10)
return;
if(enemy[i].fireType!=-1&&--enemy[i].interval==0){
enemy[i].interval=enemy[i].fireInterval;
var tm=new Fly(enemy[i].force,enemy[i].fireType);
tm.initPos(enemy[i].x,enemy[i].y+enemy[i].range);
bullet.push(tm);
}
}
}
}
//清理数组
while(enemy.length>0&&enemy[0]==null){
enemy.shift();
}
}
bulletManager()用来控制子弹的移动.
//子弹处理
function bulletManager(){
if(openFire&&--fireInterval==0){
var tm=new Fly(1,100);
tm.x=controller.x;
tm.y=controller.y-7;
bullet.push(tm);
fireInterval=5;
}
for(var i in bullet){
if(!bullet[i])continue;
bullet[i].autoMove();
if(!bullet[i].valid){
bullet[i]=null;
}
}
//清理数组
while(bullet.length>0&&bullet[0]==null){
bullet.shift();
}
}
damageManager()用来进行单位的撞击判断,以及计分的刷新,失败的判断都在里面.
//撞击判断
function damageManager(){
for(var i in bullet){
for(var j in enemy){
if(!bullet[i]||!enemy[j])continue;
if(bullet[i].force==enemy[j].force)continue;
if(Math.abs(bullet[i].x-enemy[j].x)>enemy[j].range||Math.abs(bullet[i].y-enemy[j].y)>enemy[j].range)continue;
enemy[j].hp-=bullet[i].damage;
if(enemy[j].hp<=0)
enemy[j].die();
bullet[i].die();
}
if(!bullet[i])continue;
if(bullet[i].force==controller.force)continue;
if(Math.abs(bullet[i].x-controller.x)>controller.range||Math.abs(bullet[i].y-controller.y)>controller.range)continue;
controller.hp-=bullet[i].damage;
if(controller.hp<=0){
controller.die();
//失败
Fail();
}
bullet[i].die();
refreshScore();
}
for(var j in enemy){
if(!enemy[j])continue;
if(Math.abs(controller.x-enemy[j].x)>enemy[j].range||Math.abs(controller.y-enemy[j].y)>enemy[j].range)continue;
controller.hp-=enemy[j].damage;
if(controller.hp<=0){
controller.die();
//失败
Fail();
}
enemy[j].die();
refreshScore();
}
}
ReDraw()用来对canvas进行重绘.
//重绘
function ReDraw(){
ctx.clearRect(0,0,gameWidth,gameHeight);
//controller
controller.draw();
//enemy
for(var e in enemy){
if(enemy[e])
enemy[e].draw();
}
//bullet
for(var b in bullet){
if(bullet[b])
bullet[b].draw();
}
}
预览:
100/100
浙公网安备 33010602011771号