【微信小游戏开发】小游戏飞行的子弹
上一章节中我们做了一个资源加载器,所以可以很轻松的加载多个资源了...
本章节我们来实现 打飞机 小游戏中的子弹效果
同样,我们也不使用官方的图片,而是使用下面这张雪碧图
- 图片地址为: https://www.twle.cn/static/i/minigame/bullet.png
- 图片大小为
180x60
- 每个子弹大小为
60x60
下载这张图片,并保存到 images
目录
废话不多说,我们先绘制第一颗飞机
我们从底部正中间发射子弹
game.js
varc=wx.createCanvas();varctx=c.getContext('2d');
varbullet=wx.createImage();
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-108))
ctx.fillText(" © 2015-2018 www.twle.cn",c.width/2,(c.height-128));
ctx.restore();
}
bullet.onload=function(){
reset(ctx);
ctx.drawImage(bullet,0,0,60,60,c.width/2-30,c.height-30,30,30);
draw_copy();
}
reset();
bullet.src='images/bullet.png'
虽然子弹大小为 60x60
,但我们把它绘制小一点,不然一屏幕都放不下几颗子弹
运行效果如下
对子弹进行封装
因为剧情 (接下里的教程) 需要我们对子弹做一些封装
functionBullet(){
// 位置
this.x=0;
this.y=0;
//宽高
this.w=30;
this.h=30;
// 飞行速度
this.speed=-2;
// 子弹图片
this.img=null;
// 子弹类型
this.kind=1;
// 原图位置
this.rx=0;
this.ry=0;
this.rw=60;
this.rh=60;
this.change_kind=function(k)
{
this.rx=(k-1)*60;
this.ry=0;
}
this.move=function(){
this.y+=this.speed;
};
this.draw=function(ctx){
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);
}
}
注意
- 我们绘制子弹的时候,
x
和y
所代表的,就是子弹中间的位置- 子弹的飞行方向是从下往上
让子弹飞起来
然后我们就可以把子弹放到动画里,让子弹飞起来
varc=wx.createCanvas();varctx=c.getContext('2d');
varbullet=null;
functionBullet(){
// 位置
this.x=0;
this.y=0;
//宽高
this.w=30;
this.h=30;
// 飞行速度
this.speed=2;
// 子弹图片
this.img=null;
// 子弹类型
this.kind=1;
// 原图位置
this.rx=0;
this.ry=0;
this.rw=60;
this.rh=60;
this.change_kind=function(k){
this.rx=(k-1)*60;
this.ry=0;
}
this.move=function(){
this.y-=this.speed;
};
this.draw=function(ctx){
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);
}
}
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-108))
ctx.fillText(" © 2015-2018 www.twle.cn",c.width/2,(c.height-128));
ctx.restore();
}
functionanimate_it(){
reset(ctx);
bullet.move();
bullet.draw(ctx);
draw_copy();
requestAnimationFrame(animate_it);
}
bullet=newBullet();
bullet.x=c.width/2;
bullet.y=c.height-15;
bullet.img=wx.createImage();
bullet.img.onload=function(){
reset(ctx);
bullet.draw(ctx);
draw_copy();
requestAnimationFrame(animate_it);
}
reset();
bullet.img.src='images/bullet.png'
运行演示如下
更多子弹
我们每 500ms
发射一颗子弹
这时候要使用一个数组来存储全部的子弹,还要检查子弹是否超出边界,如果超出了边界就删除子弹
game.js
varc=wx.createCanvas();varctx=c.getContext('2d');
varBullets={
_data:[],
move:function(){
for(variinthis._data){
this._data[i].move();
if(this._data[i].y<=0){
this._data.splice(i,1);
}
}
},
add:function(bullet){
this._data.push(bullet);
},
draw:function(ctx){
for(variinthis._data){
this._data[i].draw(ctx);
}
}
}
functionBullet(){
// 位置
this.x=0;
this.y=0;
//宽高
this.w=30;
this.h=30;
// 飞行速度
this.speed=2;
// 子弹图片
this.img=null;
// 子弹类型
this.kind=1;
// 原图位置
this.rx=0;
this.ry=0;
this.rw=60;
this.rh=60;
this.change_kind=function(k){
this.rx=(k-1)*60;
this.ry=0;
}
this.move=function(){
this.y-=this.speed;
};
this.draw=function(ctx){
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);
}
}
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-108))
ctx.fillText(" © 2015-2018 www.twle.cn",c.width/2,(c.height-128));
ctx.restore();
}
functionanimate_it(){
reset(ctx);
Bullets.move();
Bullets.draw(ctx);
draw_copy();
requestAnimationFrame(animate_it);
}
functioncreate_bullet(img)
{
varbullet=newBullet();
bullet.x=c.width/2;
bullet.y=c.height-15;
bullet.img=img;
Bullets.add(bullet);
}
varbullet_img=wx.createImage();
bullet_img.onload=function(){
reset(ctx);
create_bullet(bullet_img);
Bullets.draw(ctx);
draw_copy();
setInterval(function(){create_bullet(bullet_img);},500);
requestAnimationFrame(animate_it);
}
reset();
bullet_img.src='images/bullet.png'
运行演示如下
让飞机发射子弹
是时候组装起来让飞机发射子弹了
这时候每个子弹的产生过程是这样的
如果按下了手指,那么创建子弹,如果用户抬起手指,则取消创建子弹
game.js
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;
}
}
varBullets={
_data:[],
move:function(){
for(variinthis._data){
this._data[i].move();
if(this._data[i].y<=0){
this._data.splice(i,1);
}
}
},
add:function(bullet){
this._data.push(bullet);
},
draw:function(ctx){
for(variinthis._data){
this._data[i].draw(ctx);
}
}
}
functionBullet(){
// 位置
this.x=0;
this.y=0;
//宽高
this.w=30;
this.h=30;
// 飞行速度
this.speed=2;
// 子弹图片
this.img=null;
// 子弹类型
this.kind=1;
// 原图位置
this.rx=0;
this.ry=0;
this.rw=60;
this.rh=60;
this.change_kind=function(k){
this.rx=(k-1)*60;
this.ry=0;
}
this.move=function(){
this.y-=this.speed;
};
this.draw=function(ctx){
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);
}
}
varc=wx.createCanvas();
varctx=c.getContext('2d');
varimg=wx.createImage();
varplane=wx.createImage();
varbgm=wx.createInnerAudioContext();
bgm.loop=true;
varbgCanvas=null;
varoffset=0;
varw=0;
varh=0;
varscreenWidth=c.width;
varscreenHeight=c.height;
// 上一次飞机的位置
varlasted={x:0,y:0};
// 触摸区域是否在飞机内部
varin_plane=false;
// 创建点计时器
vart=null;
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);
Bullets.move();
Bullets.draw(ctx);
ctx.drawImage(plane,0,0,128,128,lasted.x-64,lasted.y-64,128,128);
draw_copy();
offset++;
if(offset%h==0){
offset=0;
}
requestAnimationFrame(animate_it);
}
wx.onShow(function(){
bgm.play()
})
wx.onAudioInterruptionBegin(function(){
// 暂停音乐
bgm.stop();
// 中断动画
//cancelAnimationFrame(animate_it);
})
wx.onAudioInterruptionEnd(function(){
bgm.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;
}
if(in_plane){
varimg=Resource.item('images/bullet.png')
create_bullet(img);
t=setInterval(function(){create_bullet(img);},200);
}
});
wx.onTouchEnd(function(e){
if(in_plane){
lasted.x=e.touches[0].clientX;
lasted.y=e.touches[0].clientY;
in_plane=false;
clearInterval(t);
t=null;
}
});
// 触摸移动事件
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;
bgm.play()
init_bg();
ctx.drawImage(plane,0,0,128,128,lasted.x,lasted.y,128,128);
draw_copy();
requestAnimationFrame(animate_it);
}
reset();
functioncreate_bullet(img){
varbullet=newBullet();
bullet.x=lasted.x;
bullet.y=lasted.y;
bullet.img=img;
Bullets.add(bullet);
}
Resource.add('images/bg.jpg','image');
Resource.add('audio/bgm.mp3','audio');
Resource.add('images/plane.png','image');
Resource.add('images/bullet.png','image');
Resource.loaded(function(){
bgm=Resource.item('audio/bgm.mp3');
img=Resource.item('images/bg.jpg');
plane=Resource.item('images/plane.png');
start();
});
运行演示如下
注意
要注意几点,一定要在绘制灰机之前绘制子弹,不然你可能会看到飞机头上飘过的刚发出的子弹
代码已经越来越长了....还好只有最后几步了
以上是 【微信小游戏开发】小游戏飞行的子弹 的全部内容, 来源链接: utcz.com/a/129710.html