最近使用了轻量级的 Canvas 类库 ZRender开发了一些自定义图件,所以想试试用zrender开发小游戏怎么样,自己也没什么经验,所以写着玩吧,可能有些逻辑部分写的不是很好。。这个小游戏很简单,内容为用篮子接水果,接到苹果10分,橘子5分,菠萝15分,草莓30分,通过键盘的左右按键控制篮子左右移动,最后得分为累计接到的水果得分。
一:
首先我们需要一些水果的小图标,那么在图标网站上面去下载一些图标。这里下载了苹果、菠萝、橘子、草莓的图标。
当然如果要用篮子接水果的话,我们还需要下载一个篮子的图标。这里下载的图标都是png格式的,一般是用到它的透明背景特点
二:
添加如下标签布局,设置myimg部分display:none 目的是在window.onload的时候,能够确保这些图标都加载完毕,同时放置一个div用于zrender初始化。
zrender初始化
var container=document.getElementsByClassName('example-container')[0];
var zr = zrender.init(container);
三:
这里向zrender中添加了四个group,zrBGGroup用于添加背景元素,zrGroup用于放置水果,bottomGroup用于放置篮子,effectGroup用于放置加分的效果。设置group的position,方便后面元素定位。
this.zrBGGroup=new zrender.Group();
this.zrBGGroup.position=[0,0];
this.zr.add(this.zrBGGroup);
this.zrGroup=new zrender.Group();
this.zrGroup.position=[0,40];
this.zr.add(this.zrGroup);
this.bottomGroup=new zrender.Group();
this.bottomGroup.position=[0,this.h-40];
this.zr.add(this.bottomGroup);
this.effectGroup=new zrender.Group();
this.effectGroup.position=[0,0];
this.zr.add(this.effectGroup
四:
把背景部分都添加进去,这里背景用到了一个RadialGradient蓝紫渐变色。同时添加了得分是个zrender.Text对象,篮子是个zrender.Image对象。因为要监听键盘的按键,这里监听keydown一个事件如果keyCode等于39,说明按下了这个键->,将篮子向右移动。如果keyCode等于37,按下了<-这个键,将篮子向左移动。注意要限定移动的范围。
//绑定事件
bindEvent:function(){
var self=this;
var w=this.w;
window.addEventListener("keydown", function (e) {
var basket=self.basket;
var x=basket.position[0];
if(e.keyCode==39) //按下了这个键->
{
if((x+20)<=w-50)
{
basket.attr({
position:[x+20,0]
});
}
}
else if(e.keyCode==37) //按下了<-这个键
{
if((x-20)>=-50)
{
basket.attr({
position:[x-20,0]
});
}
}
}, false);
},
五:
水果要掉下来状态也需要更新,我们这里用setInterval,每0.1秒更新一次状态。同时要检测是否有水果掉到了篮子里面。因为掉水果和检测水果是在同一个Interval逻辑,不一定每次都会落水果。所以这里在0~100里面的随机数里面,只有随机到0~8时才会掉落水果。这里有一个技巧,因为草莓的分值比较高,所以掉落草莓的概率设置的最小,只有随机到0的时候掉落草莓。每次遍zrGroup的子元素,检测水果是否在篮子的范围,在这个范围则移除改元素,同时加上对应的分值。
//更新效果
updateState:function(){
var self=this;
var w=this.w;
var score=this.score;
this.myinter=setInterval(function(){
var zrGroup=self.zrGroup;
var basket=self.basket;
var random=Math.floor(Math.random()*100); //控制数量
var speed=120-random;
//pos 的范围是-50 ~w-50
var pos=Math.random()*w-50;
switch(random)
{
case 0: //丢草莓
self.throwFruit('strawberry',pos,speed);
break;
case 1:
case 2: //丢苹果
self.throwFruit('apple',pos,speed);
break;
case 3:
case 4: //丢菠萝
self.throwFruit('pineapple',pos,speed);
break;
case 5:
case 6:
case 7:
case 8://丢橘子
self.throwFruit('orange',pos,speed);
break;
}
//检测及更新显示
var basketX=basket.position[0];
zrGroup.eachChild(function(item){
var x=item.position[0];
var y=item.position[1];
//大致的判断范围
if(y>w-35&& x>basketX-15&&x<(basketX+100-15))
{
var type=item.fType;
var winScore=rule[type];
//加分
var scoreNOW=Number(score.style.text)+winScore;
self.scoreEffect(winScore);
score.attr({
style: {
text:scoreNOW
}
});
zrGroup.remove(item);
}
});
},100);
}
六:
最后讲一下水果是如何掉落的吧,用到了zrender的animateTo,设置其position和持续时间。这里传递了三个参数,第一个type表示是那种类型的水果。第二个pos表示水果的x轴坐标,第三个speed水果表示美秒钟移动的像素值。同时这里选用了几种类型的缓动效果,如下图所示。
//丢水果
throwFruit:function(type,pos,speed){
var easeType=['linear','quadraticIn','quadraticOut','cubicIn','cubicOut','linear'];
var easing=easeType[Math.floor(Math.random()*5)];
var zrGroup=this.zrGroup;
var h=this.h;
var dur=(h-40)/speed*1000;
var baseStyle=this.fruitStyle;
baseStyle.style.image='images/'+type+'.png';
baseStyle.position=[pos,0];
var onefruit=new zrender.Image(baseStyle);
onefruit.fType=type;
zrGroup.add(onefruit);
onefruit.animateTo({
position: [pos,h-40],
rotation: Math.PI *2
}, dur, 0, easing,function(){
//结束之后要移除该元素
zrGroup.remove(onefruit);
});
},
七:最终效果
整体代码:
catch fruit
demo:https://ccessl.github.io/zrender-use-demo/