在这个超长假期中,无聊。。。,所以动手做一个早就计划要做的小玩意,?水果老虎机
?,嗯,这是一个小程序而不是小游戏...
使用结构还是canvas?
使用模板结构(view)生成水果盘的好处一是用户可自定义产出?n x n
?的定制化老虎机,二是容易通过算法样式生成布局,三是通过?wx.selectQueryAll
?的方法能够很方便的抓到定位数据。但,问题是动画性能过于孱弱,如图构建一个?7x7
?的水果盘,动画性能估计会惨不忍睹,而且纯粹模板结构无论使用?animation
?动画方法还是?css
?的keyframe的动画方法得到的动画效果都非常差(测试过的结论),还有是已知的动画方法可控性很差
使用canvas来生成水果盘好处是动画性能很好(canvas2d),但是定制性和扩展性比较差
so综上考虑,使用模板(view)布局,使用canvas来实现动画。既保证了组件的性能,同时定制型,扩展性也很好
准备计时器方法
动画的生成离不开计时器方法,settimeout/setinterval这两兄弟真的不够看啊,问题还多,做过web开发的一定都知道?window.requestAnimationFrame
?,这货在小程序的计时器方法中不存在,好在?canvas2d
?中可以使用?Canvas.requestAnimationFrame(function callback)
?方法来实现
准备运动算法
在水果老虎机中,激活状态会沿着四方的水果盘做非线性运动(easeInOut比较好用),需要基础的运动算法来计算实际的运动距离。在?animation
?动画方法中,我们可以使用?ease-in/ease-out
?等缓动算法来实现动画效果,但在这里必须要借助?tween.js
?中的缓动算法来实现运动效果(因为需要控制运动节点)。
你会不会想到用css的keyframe动画来做这个运动效果,经过我的测试,css的动画和animation的动画会在每一条边上实现一次(ease)缓动运动(很奇怪的效果)
推荐这篇文章
使用其中一个,节省代码量
const easeInOutQuart = function (t,b,c,d) {
if ((t /= d / 2 ) < 1 ) return c / 2 * t * t * t * t + b;
return -c / 2 * ((t -= 2 ) * t * t * t - 2 ) + b;
}
复制代码
tween算法是以时间为基准(时间比率 = 距离比率)来计算单位时间的实际运动距离
布局
以上面的图为例,我们需要做一个?7 x 7
?的水果盘,实际有效的奖品格子数为?7*4-4
?共24个有效格子
有效格子算法
js
wxml
<view class ="fruits-container" >
<"fruits-table" >
<block wx:for =" {{ary} }" wx:key ="index" >
<view wx:if ={{item.valide} }" class ="valide" >{{item.title} }</view >
<view wx:else class ="in-valide" > </view >
</block >
</view >
<canvas type ="2d" .... />
</view >
复制代码
样式
只节选关键样式,目的是让canvas覆盖在水果盘上,长宽一致
.fruits-container {
position : relative;
width : 400px ;
height : 400px ;
...
}
.fruits-table {
position : absolute;
100% ;
top : 0 ;
left : 0 ;
...
}
复制代码
抓取位置信息
canvas的绘制需要X轴,Y轴的精确信息,可以使用?wx.createSelectorQuery
?方式抓取类名为‘valide’的?view
?(奖品格子)的位置信息
let query = wx.createSelectorQuery().in(this)
query.selectAll(`.fruits-table .valide`).boundingClientRect(ret => {
....
console.log (ret [0 ]) // top,left ,51); font-weight: 700;">right,bottom,width,height
console.1 ]) // top,height
...
...
console.23 ]) // top,height
})
复制代码
得到每一个奖品格子的位置信息后,就可以使用canvas的?fillRect
?方法来绘制激活状态了。
绘制一个激活状态
)
.fields({ node : true ,size : true })
.exec((res ) => {
const canvas = res[0 ].node
const ctx = canvas.getContext('2d' )
let x = top
let y = left
let dx = width
let dy = height
ctx.shadowOffsetX = 2
ctx.shadowOffsetY = -2
ctx.shadowColor = 'red'
ctx.shadowBlur = 50
ctx.lineWidth = 5
ctx.strokeStyle = 'red'
ctx.clearRect(0 ,跑起来
已经绘制了一个激活状态,接下来使它能够简单动起来
执行run方法后可以看到水果盘的激活状态一步一步的往前走(100毫秒),拖拉机终于可以启动了
配上运动算法
经过上面的试验我们终于可以看到基本的运动效果了,接下来配上运动算法和计时器方法
以上为我的小程序水果老虎机的基本开发思路 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!