最近使用了轻量级的 Canvas 类库 ZRender开发了一些自定义图件,所以想试试用zrender开发小游戏怎么样,自己也没什么经验,所以写着玩吧,可能有些逻辑部分写的不是很好。。这个小游戏很简单,内容为用篮子接水果,接到苹果10分,橘子5分,菠萝15分,草莓30分,通过键盘的左右按键控制篮子左右移动,最后得分为累计接到的水果得分。

一:

首先我们需要一些水果的小图标,那么在图标网站上面去下载一些图标。这里下载了苹果、菠萝、橘子、草莓的图标。

当然如果要用篮子接水果的话,我们还需要下载一个篮子的图标。这里下载的图标都是png格式的,一般是用到它的透明背景特点

二:

添加如下标签布局,设置myimg部分display:none 目的是在window.onload的时候,能够确保这些图标都加载完毕,同时放置一个div用于zrender初始化。

<div><div id="myimg" style="display:none"><img src="data:images/apple.png"/><img src="data:images/orange.png"/><img src="data:images/pineapple.png"/><img src="data:images/strawberry.png"/><img src="data:images/basket.png"/></div><div class="example-container" style="width:500px;height:600px;border:1px solid black;margin:0 auto"></div>
</div>

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-50var 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);});},

七:最终效果

整体代码:

<!--created by chencen -->
<!--on 2018/1/11-->
<!--blog cc-fys--><!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>catch fruit</title><script type="text/javascript" src="zrender.js"></script>
</head>
<div><div id="myimg" style="display:none"><img src="data:images/apple.png"/><img src="data:images/orange.png"/><img src="data:images/pineapple.png"/><img src="data:images/strawberry.png"/><img src="data:images/basket.png"/></div><div class="example-container" style="width:500px;height:600px;border:1px solid black;margin:0 auto"></div>
</div>
<body>
<script>window.onload=function() //初始化{//为了保证图片加载完成var container=document.getElementsByClassName('example-container')[0];new CatchFruit(container);};//分数规则var rule={apple:10,orange:5,pineapple:15,strawberry:30};function CatchFruit(elememt){this.element=elememt;this.zr = zrender.init(this.element);this.w= this.zr.getWidth();this.h = this.zr.getHeight();this.keydown={};this.fruitStyle={style: {width:35,height:35,x:0,y:0}};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);this.init();}CatchFruit.prototype={constructor: CatchFruit,//初始化init: function () {var self=this;//画背景self.drawBG();//绑定事件self.bindEvent();//更新状态self.updateState();},//画背景drawBG:function() {var zrBGGroup=this.zrBGGroup;var bottomGroup=this.bottomGroup;var w=this.w;var h=this.h;var bg = new zrender.Rect({shape: {width: w,height: h},style: {fill: new zrender.RadialGradient(0.5, -0.1, 1, [{offset: 0,color: '#37B0FF'},{offset: 1,color: '#efe3ff'}])}});zrBGGroup.add(bg);zrBGGroup.add(new zrender.Rect({shape: {width: w,height: 40},style: {fill:'#33292f'}}));zrBGGroup.add(new zrender.Rect({shape: {width: w,height: 40},style: {fill:'#33292f'}}));zrBGGroup.add(new zrender.Text({style: {text:'得分:',fontSize: '18',textFill: '#fff'},position: [20, 10]}));this.score=new zrender.Text({style: {text:'0',fontSize: '18',textFill: '#fff'},position: [70, 10]});zrBGGroup.add(this.score);//篮子this.basket=new zrender.Image({style: {image:'images/basket.png',width:100,height:40},position:[w/2-50,0]});bottomGroup.add(this.basket);},//更新效果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-50var 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);},//丢水果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);});},//加分效果scoreEffect:function(winScore){var w=this.w;var h=this.h;var effectGroup=this.effectGroup;var addCore=new zrender.Text({style: {text:'+ '+winScore,fontSize: '25',textFill: '#ff5140',textAlign: 'center'},position: [w/2, h/2]});effectGroup.add(addCore);addCore.animateTo({style: {opacity:0},position: [10, 10]}, 1000, 0, 'linear', function () {effectGroup.remove(addCore);});},//绑定事件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);},dispose:function(){var myinter=this.myinter;clearInterval(myinter);this.zrBGGroup.removeAll();this.zrGroup.removeAll();this.bottomGroup.removeAll();this.effectGroup.removeAll();var zr = this.zr;zrender.dispose(zr);}};</script></body>
</html>

demo:https://ccessl.github.io/zrender-use-demo/

Canvas 类库ZRender开发的接水果的小游戏相关推荐

  1. 轻量级的Canvas类库zrender使用笔记 :简单自定义图件开发

    ECharts,一个纯 Javascript 的图表库,底层依赖轻量级的 Canvas 类库 ZRender,提供直观,生动,可交互,可高度个性化定制的数据可视化图表.当然我们自己可能有些需求,通过修 ...

  2. Android使用SurfaceView开发《捉小猪》小游戏 (一)

    先上效果图: 哈哈, 说下实现思路: 我们可以把每一个树桩, 小猪, 车厢都看成是一个Drawable, 这个Drawable里面保存了x, y坐标, 我们的SurfaceView在draw的时候, ...

  3. 云开发版合成大西瓜小游戏微信小程序源码 微信游戏小程序附带流量主功能

    这是一款云开发版的合成大西瓜小游戏微信小程序源码,微信游戏小程序源码.该小游戏玩法简单,只需要拖动同样的水果落下合成新品众的水果,最终合成大西瓜,玩法酷似俄罗斯方块,相当于换一种形式的俄罗斯方块,简单 ...

  4. html5猜大王游戏,水果大王小游戏

    水果大王小游戏是一款全新祖玛消除类型的h5网页小游戏.不知道玩家们是否还记得合成大西瓜这款风靡一时的魔性页游,如今融入了全新的元素,让其摇身一变,与更为经典的祖玛玩法结合到了一起.水果大王小游戏不像是 ...

  5. Javascript开发的金山打字简易小游戏

    记得以前读书的时候,由于课前都预习过了,所以听课一般都是为了给老师面子很"耐心"的坐在教室里,发着呆走着神.突然,那天上课讲了几天前预习的课题,采用JS可以识别键盘输入,嘿嘿,好玩 ...

  6. 水果掉落小游戏(原生js+css动画)

    摘要 水果下落小游戏,采用原生js的dom操作和css的animation,做的比较粗糙,目的是练习原生js的常用操作.游戏功能与界面均为他人设计,本demo具体代码实现由本人独立实现. 样式 dem ...

  7. Java窗体小游戏开发飞机大作战Java小游戏开发源码

    Java窗体小游戏开发飞机大作战Java小游戏开发源码

  8. 如何用 JavaScript+Canvas 开发一款超级烧脑小游戏?

    作者 | huangjianke 责编 | 伍杏玲 出品 | CSDN(ID:CSDNnews) [CSDN 编者按]据微信最新数据,微信小游戏累计注册用户量已突破10亿.那么初学者如何开发一款好玩又 ...

  9. 从技术角度谈如何开发一款微信联网小游戏

    微信自从有了 "跳一跳" 后微信小游戏就开始迅速火爆起来,为跟上这股潮流,相信很多开发者都想探一探微信小游戏是如何开发的.下面从技术的角度说说一下微信小游戏如何开发的. 附:本文适 ...

最新文章

  1. api 创建zookeeper客户端_zookeeper分布式锁原理及实现
  2. 专家观点 | 李德仁:基于云计算的智慧城市运营脑
  3. C#调用C++DLL类的方法
  4. 20172301 《程序设计与数据结构》第七周学习总结
  5. php随机产生4乘4矩阵,PHP 用二维矩阵生成一个给定层数的杨辉(PASCAL)三角形
  6. 轻松与外来客户进行REST通信
  7. 编写react组件_如何编写第一个React.js组件
  8. BZOJ4034 树上操作
  9. innobackupex做MySQL增量备份及恢复
  10. 鸿蒙操作系统是pc还是手机,华为鸿蒙操作系统是什么?鸿蒙适用机型首曝光
  11. Java NIO框架Netty教程(二)
  12. PanguVR获得400万种子轮融资,提供高效的VR家装解决方案
  13. ONES(光盘刻录软件)单文件版V2.1.358 | ones刻录软件下载 | ones刻录软件怎么使用
  14. 于歆杰pdf 电路原理_buck电路原理(于歆杰 电路原理pdf)
  15. 装完linux无法进入windows,安装Ubuntu后无法启动Windows,如何解决?
  16. python画多个圆_我如何用pythonturtle画一个中间有一个圆的圆圈?
  17. ENVI5.3 安装教程,新手入门(超详细)附安装包和常见问题
  18. 【Linux基础】Ubuntu 20.04系统安装(完整版)
  19. 最简单方法!!用python生成动态条形图(解决报错问题!)
  20. 计算机和音乐结合的作品,用计算机创作多媒体作品──音乐和声音张燕.doc

热门文章

  1. 复试2014年算法题
  2. 比较购物网站中比较代码如何实现
  3. python图片压缩限定大小_Python练习小工具——照片压缩及自定义尺寸更改
  4. WPF基础五:UI④ 条目控件ContextMenu
  5. php word,下载与安装 · PHPword新版开发指南 · 看云
  6. Windows 1709版本中OneDrive导致绝大多数程序崩溃的解决方案
  7. [Applied Plotting, Charting Data Representation in Python] Assignment 2-Plotting Weather Patterns
  8. Brooks曾经在UMLChina网站留过言-回忆和送别(1)
  9. 电梯媒体卷起来,行业利润打下去
  10. 计算机网络为什么需要抽象出五层模型?