本文主要介绍用微信小程序canvas开发水果老虎机的思路。本文通过idea代码一步步介绍给大家,有一定的参考价值,有需要的朋友可以参考一下。
在这个漫长的假期里,很无聊。于是我开始做一个小玩意,水果吃角子老虎机,早就打算做了。嗯,这是一个小程序,而不是一个小游戏。
使用结构还是canvas?
使用模板结构(view)生成果盘的好处是用户可以用nn定制定制的老虎机,布局可以很容易的用算法风格生成,定位数据可以很容易的用wx.selectQueryAll的方法抓取,但问题是动画表现太弱。比如一个7x7的水果盘,如图构造,动画表现估计很恐怖。而且使用纯模板结构得到的动画效果无论动画方法还是css关键帧动画方法都很差(测试结论),已知的动画方法可控性差。
用canvas生成果盘的好处是动画表现很好(canvas2d),但是定制性和扩展性差。
所以总结一下,用模板(视图)和画布的布局来实现动画。既保证了组件的性能,又具有良好的可定制性和可扩展性。
准备计时器方法
没有timer方法就无法生成动画。settimeout/setinterval两兄弟真的看不够。问题还是很多的。做过web开发的人一定知道window.requestAnimationFrame,这是小程序的timer方法中不存在的。还好canvas2d可以用canvas。RequestAnimationFrame(函数回调)方法来实现它。
准备运动算法
在水果吃角子老虎机中,激活状态会沿着四边果盘非线性移动(easeInOut比较好用),需要一个基本的运动算法来计算实际的运动距离。在动画方法中,我们可以使用ease-in/ease-out等慢动作算法来实现动画效果,但这里我们要使用tween.js中的慢动作算法来实现运动效果(因为我们需要控制运动节点)。
你会想到用css的关键帧动画来做这个动作效果吗?经过我的测试,css的动画和动画会在每一边实现(缓解)慢动作(非常奇怪的效果)。
推荐这篇文章
使用其中一个来节省代码量。
/*
* Tween.js
* t:当前时间;
* b:开始值(初始值);
* c:价值的变化;
* d:持续时间(duration)。
*/
//1/4次方的慢动作
const easeInOutQuart=function (t,b,c,d) {
if ((t /=d/2) 1)返回c/2 * t * t * t * t b;
return-c/2 *(t-=2)* t * t * t-2)b;
}
Tween算法是根据时间(时间比=距离比)来计算单位时间内实际移动的距离。
布局
以上图为例,我们需要制作一个77的水果盘,实际有效奖格数为7*4-4,共有24个有效格。
高效格型算法
射流研究…
//0-6第一行的所有网格都有效。
//21-27最后一行的所有网格都有效。
//中间部分I% 7==0,I% 7==(7-1)有效。
//算法源代码有点枯燥。按照上面的思路,可以遍历28格,识别出奖格valide=true。
//可以延伸一下,想想6x6 5x5。想法是一样的。
wxml
视图class=水果-容器
view class=fruits-table
block wx:for= { { ary } } wx:key= index
view wx:if= { { item . valide } } class= valide { { item . title } }/view
视图wx:else class= in-valid /视图
/阻止
/查看
画布类型=2d ./
/查看
模式
只选择关键的样式,这样canvas就可以覆盖同样长宽的果盘。水果容器{
位置:相对;
宽度:400px
高度:400px
.
}。水果桌{
位置:绝对;
宽度:100%;
身高:100%;
top:0;
左:0;
.
}
抓取位置信息
画布的绘制需要X轴和Y轴的准确信息。您可以使用wx.createSelectorQuery捕获类名为“valide”的视图的位置信息。
let query=wx.createSelectorQuery()。在(这个)
query . select all(` . fruits-table . valide `)。boundingClientRect(ret={
.
console.log(ret[0]) //顶部、左侧、右侧、底部、宽度、高度
console.log(ret[1]) //顶部、左侧、右侧、底部、宽度、高度
.
.
console.log(ret[23]) //顶部、左侧、右侧、底部、宽度、高度
})
得到每一个奖品格子的位置信息后,就可以使用帆布的fillRect方法来绘制激活状态了。
绘制一个激活状态
let query=wx.createSelectorQuery().在(这个)
查询。全选(`。水果桌。有效`).boundingClientRect(ret={
.
设{上,左,右,下,宽,高}=ret[0]
const canvasQuery=wx。createselectquery()
canvasquery。选择( #水果-画布)。字段({ node: true,size: true })。exec((res)={
const canvas=res[0].结节
const ctx=canvas.getContext(2d )
让x=顶部
让y=左
设dx=宽度
让dy=高度
ctx.shadowOffsetX=2
ctx.shadowOffsetY=-2
ctx.shadowColor=red
ctx.shadowBlur=50
ctx.lineWidth=5
ctx.strokeStyle=red
ctx.clearRect(0,0,canvas.width,canvas.height)
ctx.strokeRect(x,y,dx,dy)
})
})
跑起来
已经绘制了一个激活状态,接下来使它能够简单动起来
//抽象激活方法
函数矩形(点,画布){
设{x,y,dx,dy}=获取位置(点)
ctx.shadowOffsetX=2
ctx.shadowOffsetY=-2
.
.
ctx.clearRect(0,0,canvas.width,canvas.height) //擦除整个水果盘
ctx.strokeRect(x,y,dx,dy) //绘制激活区域
}
函数运行(){
setTimeout(()={
if (ret.length) {
let point=ret.shift()
矩形(点,画布)
运行()
}
}, 100)
}
执行奔跑方法后可以看到水果盘的激活状态一步一步的往前走(100毫秒),拖拉机终于可以启动了
配上运动算法
经过上面的试验我们终于可以看到基本的运动效果了,接下来配上运动算法和计时器方法
//夸脱四次方的缓动
const easeInOutQuart=function (t,b,c,d) {
if ((t /=d/2) 1)返回c/2 * t * t * t * t b;
return-c/2 *(t-=2)* t * t * t-2)b;
}
让start=0 //开始时间
let begin=0 //开始奖品位置
let end=23 //终点位置,这里跑一圈
let during=5000 //运动总时间
//1000/60 17,
//17毫秒即表示屏幕60帧刷新率每秒 requestAnimationFrame计数频率(一般情况)
常量步进器=()={
//左侧为位移距离
//老虎机的运动位移是节点位移,不是精确位移
//所以这里用parseInt处理,只取整数部分
//数据变化为0,1,2,3,4,5.23
//间隔时间/距离由easeInOutQuart算法计算
var left=easeInOutQuart(start,begin,end,during);
设idx=parseInt(左)
开始=开始17
if (idx=end) {
let point=this.ret[idx] //取节点位置信息
this.rect(point) //绘制
}
//时间递增
if (start=during) {
这个。CTX。requestanimationframe(steper);//计时器
}否则{
//动画结束,这里可以插入回调.
//回调().
}
};
steper();//启动
总结
以上所述是小编给大家介绍的微信小程序帆布开发水果老虎机的思路详解,希望对大家有所帮助!