【微信小游戏开发】小游戏消灭敌机
敌机出现了,英雄飞机已经在路上了,子弹也充足了,是时候消灭敌机了
判断子弹是否命中敌机
我们采用子弹是否在敌机所在的圆内部的方式来判断子弹是否命中目标
我们分别要循环敌机数组和子弹数组,然后一一对比有没有命中目标,给 Bucket
添加一个新方法 enemy_hit()
varBucket={_bucket:{},
move:function(){
for(variinthis._bucket){
for(varjinthis._bucket[i]){
this._bucket[i][j].move();
if(this._bucket[i][j].hit()){
this._bucket[i].splice(j,1);
}
}
}
},
add:function(obj,bucket){
if(!(bucketinthis._bucket)){
this._bucket[bucket]=[];
}
this._bucket[bucket].push(obj);
},
draw:function(ctx){
for(variinthis._bucket){
for(varjinthis._bucket[i]){
this._bucket[i][j].draw();
}
}
},
enemy_hit:function(){
varenemys=this._bucket['enemy'];
varbullets=this._bucket['bullet'];
for(variinenemys){
varenemy=enemys[i];
for(varjinbullets){
varbullet=bullets[j];
varr=enemy.w/2;
varx=(bullet.x-enemy.x);
vary=(bullet.y-enemy.y);
// 因为子弹比敌机要小,所以直接判断子弹是否和敌机相交即可
if(x*x+y*y<=r*r){
// 移除子弹
this._bucket['bullet'].splice(j,1);
// 移除飞机
this._bucket['enemy'].splice(i,1);
}
}
}
}
}
为什么我们要先循环敌机,因为下一章节我们还要添加上敌机撞上我机的情况,避免多次循环
范例
我们把刚刚判断子弹是否命中目标的方法添加到游戏上
game.js
varinherits=function(superCtor){varf=function(){superCtor.call(this);}
f.super_=superCtor;
f.prototype=Object.create(superCtor.prototype,{
constructor:{
value:f,
enumerable:false,
writable:true,
configurable:true
}
});
returnf;
};
varResource={
_res:[],// [][] 资源对象数组, 0 表示资源 1 url 2 类型 3 是否加载完成
_load:function(idx,ops){
varres=this._res[idx];
if(!res[3]){
if(res[2]=="audio")
this._load_audio(res[1],idx,ops)
if(res[2]=="image")
this._load_image(res[1],idx,ops);
}
},
_load_image:function(src,i,ops){
varimg=wx.createImage();
varthat=this;
that._res[i][0]=img;
img.onload=function(){
that._res[i][3]=true;
}
img.src=src;
},
_load_audio:function(src,i,ops){
varaudio=wx.createInnerAudioContext();
if(ops!=null){
for(varkinops){
audio[k]=ops[k];
}
}
varthat=this;
that._res[i][0]=audio;
audio.onCanplay(function(){
that._res[i][3]=true;
});
audio.src=src;
},
loaded:function(callback){
for(vari=0;i<this._res.length;i++){
if(!this._res[i][3]){
varthat=this;
setTimeout(function(){that.loaded(callback);},200);
return;
}
}
callback();
},
add:function(src,type,id,ops){
this._res.push([null,src,type,false,id]);
this._load(this._res.length-1,ops);
},
item:function(src){
for(vari=0;i<this._res.length;i++){
if(this._res[i][1]==src){
returnthis._res[i][0];
}
}
returnnull;
}
}
varBucket={
_bucket:{},
move:function(){
for(variinthis._bucket){
for(varjinthis._bucket[i]){
this._bucket[i][j].move();
if(this._bucket[i][j].hit()){
this._bucket[i].splice(j,1);
}
}
}
},
add:function(obj,bucket){
if(!(bucketinthis._bucket)){
this._bucket[bucket]=[];
}
this._bucket[bucket].push(obj);
},
draw:function(ctx){
for(variinthis._bucket){
for(varjinthis._bucket[i]){
this._bucket[i][j].draw();
}
}
},
enemy_hit:function(){
varenemys=this._bucket['enemy'];
varbullets=this._bucket['bullet'];
for(variinenemys){
varenemy=enemys[i];
for(varjinbullets){
varbullet=bullets[j];
varr=enemy.w/2;
varx=(bullet.x-enemy.x);
vary=(bullet.y-enemy.y);
// 因为子弹比敌机要小,所以直接判断子弹是否和敌机相交即可
if(x*x+y*y<=r*r){
// 移除子弹
this._bucket['bullet'].splice(j,1);
// 移除飞机
this._bucket['enemy'].splice(i,1);
}
}
}
}
}
functionSprite(){
// 位置
this.x=0;
this.y=0;
//宽高
this.w=0;
this.h=0;
// 飞行速度
this.speed=0;
// 图片
this.img=null;
// 类型
this.kind=0;
// 原图位置
this.rx=0;
this.ry=0;
this.rw=0;
this.rh=0;
this.ctx=null;
this.change_kind=function(k){
this.rx=(k-1)*this.rw;
this.ry=0;
}
this.move=function(){
this.y+=this.speed;
};
this.draw=function(){
this.ctx.drawImage(this.img,this.rx,this.ry,
this.rw,this.rh,
this.x-this.w/2,this.y-this.h/2,
this.w,this.h);
}
}
varBullet=inherits(Sprite);
Bullet.prototype.hit=function(){
returnthis.y<=0;
}
varEnemy=inherits(Sprite);
Enemy.prototype.hit=function(){
returnthis.y>=screenHeight;
}
varc=wx.createCanvas();
varctx=c.getContext('2d');
varimg=wx.createImage();
varplane=wx.createImage();
varbgCanvas=null;
varoffset=0;
varw=0;
varh=0;
varscreenWidth=c.width;
varscreenHeight=c.height;
// 上一次飞机的位置
varlasted={x:0,y:0};
// 触摸区域是否在飞机内部
varin_plane=false;
// 创建计时器
vart=0;
functioninit_bg(){
bgCanvas=wx.createCanvas();
bgCanvas.width=screenWidth;
bgCanvas.height=screenHeight+h;
varbgctx=bgCanvas.getContext('2d');
vary=0;
varx=0;
// 底部多绘制一张图片
while(y<screenHeight+h){
x=0;
while(x<screenWidth){
bgctx.drawImage(img,x,y,w,h);
x+=w;
}
y+=h;
}
}
functionreset(){
ctx.save();
ctx.fillStyle="#fff";
ctx.fillRect(0,0,c.width,c.height);
ctx.restore();
}
functiondraw_copy(){
ctx.save();
ctx.textAlign="center"// 居中对齐
ctx.textBaseline="middle"//垂直居中绘制
ctx.fillStyle="#aaa";
ctx.font="16px Arial"// 字体大小 16 像素
ctx.fillText("简单教程,简单编程",c.width/2,(c.height-36))
ctx.fillText(" © 2015-2018 www.twle.cn",c.width/2,(c.height-18));
ctx.restore();
}
functionanimate_it(){
reset(ctx);
ctx.drawImage(bgCanvas,0,offset,screenWidth,screenHeight,0,0,screenWidth,screenHeight);
Bucket.move();
Bucket.enemy_hit();
Bucket.draw(ctx);
ctx.drawImage(plane,0,0,128,128,lasted.x-64,lasted.y-64,128,128);
draw_copy();
timeit();
offset;
if(offset%h==0){
offset=0;
}
requestAnimationFrame(animate_it);
}
wx.onShow(function(){
Resource.item('audio/bgm.mp3').play();
})
wx.onAudioInterruptionBegin(function(){
// 暂停音乐
Resource.item('audio/bgm.mp3').stop();
// 中断动画
//cancelAnimationFrame(animate_it);
})
wx.onAudioInterruptionEnd(function(){
Resource.item('audio/bgm.mp3').play()
// 恢复动画
cancelAnimationFrame(animate_it);
})
wx.onTouchStart(function(e){
varx=e.touches[0].clientX;
vary=e.touches[0].clientY;
if(plane_hit(x,y)){
in_plane=true;
}
});
wx.onTouchEnd(function(e){
if(in_plane){
lasted.x=e.touches[0].clientX;
lasted.y=e.touches[0].clientY;
in_plane=false;
}
});
// 触摸移动事件
wx.onTouchMove(function(e){
if(in_plane){
lasted.x=e.touches[0].clientX;
lasted.y=e.touches[0].clientY;
}
})
functionplane_hit(x,y){
returnx>(lasted.x-64)&&
x<(lasted.x+64)&&
y>(lasted.y-64)&&
y<(lasted.y+64);
}
functionstart(){
w=screenWidth>img.width?img.width:screenWidth;
h=img.height*(w/img.width);
lasted.x=(screenWidth-128)/2;
lasted.y=screenHeight-128;
varbgm=Resource.item('audio/bgm.mp3');
console.log(bgm);
bgm.play();
init_bg();
ctx.drawImage(plane,0,0,128,128,lasted.x,lasted.y,128,128);
draw_copy();
requestAnimationFrame(animate_it);
}
functioncreate_bullet(img){
varbullet=newBullet();
bullet.x=lasted.x;
bullet.y=lasted.y;
bullet.img=img;
bullet.w=30;
bullet.h=30;
bullet.speed=-2;
bullet.img=img;
bullet.kind=1;
bullet.rw=60;
bullet.rh=60;
bullet.ctx=ctx;
Bucket.add(bullet,'bullet');
}
functioncreate_enemy(img){
varenemy=newEnemy();
enemy.w=50;
enemy.h=50;
enemy.x=(enemy.w/2)+Math.random()*(screenWidth-enemy.w/2);
enemy.y=-50;
enemy.img=img;
enemy.speed=2;
enemy.img=img;
enemy.kind=1;
enemy.rw=100;
enemy.rh=100;
enemy.ctx=ctx;
Bucket.add(enemy,'enemy');
}
functiontimeit(){
if(t%60==0){
varenemy=Resource.item('images/enemy.png');
create_enemy(enemy);
}
if(in_plane&&t%20==0){
varbullet=Resource.item('images/bullet.png');
create_bullet(bullet);
}
t++;
}
reset();
Resource.add('images/bg.jpg','image');
Resource.add('audio/bgm.mp3','audio',null,{loop:true});
Resource.add('images/plane.png','image');
Resource.add('images/bullet.png','image');
Resource.add('images/enemy.png','image');
Resource.loaded(function(){
img=Resource.item('images/bg.jpg');
plane=Resource.item('images/plane.png');
start();
});
运行演示如下
以上是 【微信小游戏开发】小游戏消灭敌机 的全部内容, 来源链接: utcz.com/a/129627.html