【微信小游戏开发】小游戏敌机出现

英雄飞机也有了,子弹也有了,怎么可以少了飞机呢,对吧

同样,我们也不使用官方的图片,而是使用下面这张雪碧图

【微信小游戏开发】小游戏敌机出现

  1. 图片地址为: https://www.twle.cn/static/i/minigame/enemy.png

  2. 图片大小为 400x100

  3. 每个子弹大小为 100x100

下载这张图片,并保存到 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,100,100,c.width/2-25,0,50,50);

draw_copy();

}

reset();

bullet.src='images/enemy.png'

虽然敌机大小为 100x100 ,但我们把它绘制小一点,不然一屏幕都放不下几个敌机

运行效果如下

【微信小游戏开发】小游戏敌机出现

对敌机进行封装

因为剧情 (接下里的教程) 需要,我们对敌机做一些封装

functionEnemy()

{

// 位置

this.x=0;

this.y=0;

//宽高

this.w=50;

this.h=50;

// 飞行速度

this.speed=2;

// 敌机图片

this.img=null;

// 敌机类型

this.kind=1;

// 原图位置

this.rx=0;

this.ry=0;

this.rw=100;

this.rh=100;

this.change_kind=function(k)

{

this.rx=(k-1)*100;

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);

}

}

注意

  1. 我们绘制敌机的时候,xy 所代表的,就是敌机中间的位置
  2. 敌机的飞行方向是从下往上

是不是发现和子弹差不多,对的,等下我们会说

让敌机飞起来

把敌机放到动画里,敌机就会飞起来了

有一个点需要注意,敌机不可能凭空出现对吧,所以敌机初始化的 Y 坐标轴为 -h

然后我们就可以把敌机放到动画里,让敌机飞起来

varc=wx.createCanvas();

varctx=c.getContext('2d');

varenemy=null;

functionEnemy()

{

//宽高

this.w=50;

this.h=50;

// 位置

this.x=0;

this.y=-this.h;

// 飞行速度

this.speed=2;

// 敌机图片

this.img=null;

// 敌机类型

this.kind=1;

// 原图位置

this.rx=0;

this.ry=0;

this.rw=100;

this.rh=100;

this.change_kind=function(k)

{

this.rx=(k-1)*100;

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);

enemy.move();

enemy.draw(ctx);

draw_copy();

requestAnimationFrame(animate_it);

}

enemy=newEnemy();

enemy.x=c.width/2;

enemy.y=-enemy.h;

enemy.img=wx.createImage();

enemy.img.onload=function(){

reset(ctx);

enemy.draw(ctx);

draw_copy();

requestAnimationFrame(animate_it);

}

reset();

enemy.img.src='images/enemy.png'

运行演示如下

更多敌机

我们每 800ms 产生一个敌机

这时候要使用一个数组来存储全部的敌机,还要检查敌机是否超出边界,如果超出了边界就删除敌机

注意,一般来说,敌机的产生速度要远远小于子弹的,不然子弹都忙不过来不是

还有一点,敌机的位置是随机的,所以我们要使用随机数创建一个敌机位置

game.js

varc=wx.createCanvas();

varctx=c.getContext('2d');

varscreenHeight=c.height;

varscreenWidth=c.width;

functionEnemy(){

//宽高

this.w=50;

this.h=50;

// 位置

this.x=0;

this.y=-this.h;

// 飞行速度

this.speed=2;

// 敌机图片

this.img=null;

// 敌机类型

this.kind=1;

// 原图位置

this.rx=0;

this.ry=0;

this.rw=100;

this.rh=100;

this.change_kind=function(k){

this.rx=(k-1)*100;

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);

}

}

varEnemys={

_data:[],

move:function(){

for(variinthis._data){

this._data[i].move();

if(this._data[i].y>=screenHeight){

this._data.splice(i,1);

}

}

},

add:function(enemy){

this._data.push(enemy);

},

draw:function(ctx){

for(variinthis._data){

this._data[i].draw(ctx);

}

}

}

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);

Enemys.move();

Enemys.draw(ctx);

draw_copy();

requestAnimationFrame(animate_it);

}

functioncreate_enemy(img){

varenemy=newEnemy();

enemy.x=(enemy.w/2)+Math.random()*(screenWidth-enemy.w/2);

enemy.y=-enemy.h;

enemy.img=img;

Enemys.add(enemy);

}

varenemy_img=wx.createImage();

enemy_img.onload=function(){

reset(ctx);

create_enemy(enemy_img);

Enemys.draw(ctx);

draw_copy();

setInterval(function(){create_enemy(enemy_img);},800);

requestAnimationFrame(animate_it);

}

reset();

enemy_img.src='images/enemy.png'

运行演示如下

把敌机也绘制到游戏上

好了,加下来就是组装我们的敌机和之前已经做好的游戏了

除了组长之外,还有一个很重要的工作,就是合并

我们发现敌机和子弹所使用的信息都差不多,连保存数组也差不多,那么我们就可以把它们的主要代码合并

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();

}

}

}

}

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.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').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,'buttet');

}

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/129672.html

回到顶部