见缝插针游戏的实现

这个游戏是2015出来的。当初aa很流行,我玩了很久,深深的乞虐。那时候我还是一个iOS战士。当时觉得游戏简单到爆,就想着试着实现一下,但是...(此处省略100字)。

时间过得真快!这两年偶然看了博客,发现有人有类似的感悟和想法,提供了好的思路。结果我下定决心再研究一遍,才有了今天的实现。

你在每一关都有不同数量的“针”,在中心盘上可能会有初始状态的“针”插入,但这是为了增加游戏的难度。你的任务是将你关卡中的所有“针”插入中心旋转圆盘(插入点相对固定),前提是不能接触到其他“针”,否则游戏失败。为了不让你快速过关,自然下面的关卡难度会越来越严重,比如盘速的提高,初始准备好的“针”数和持针数的增加,顺时针和逆时针变速旋转。

中心盘是一个现金播放器。点击屏幕,扩大CAShapeLayer的路径,并实现将针插入磁盘的效果。对于“针”的动态移动过程,可以创建一个过渡“针”视图来等效替换它。那么核心问题来了:当我展开图层的路径时,如何确定绘制的起点和终点?因为在中心圆盘旋转的过程中,它上面的点也会一起做仿射变换。如果你确定在图层旋转或者光盘静止的时候画“针”,那么新画的“针”就会和之前插入的“针”重叠,造成的结果就是不管你怎么扎针,光盘上只有一个“针”,虽然实际上是很多“针”重叠的结果。

好在中轴线是圆的(所以叫圆盘),aa之类的游戏效果只能在圆的情况下设计。因为销的起点和终点的计算依赖于圆心到边界上各点的距离相等的性质,所以坐标点的转换过程可以用下面两个图形来表示:

基准点是针静止时的插入点(对应于拔针的起点),终点也可以用同样的方法换算,只是半径r的值需要相应调整。

Datum (x ',y '),实际上为了计算方便,我们取(r,2r)。

要计算终点,只需将对应的R改为实际的R。

根据公式,我们可以看到,为了找到针的起点和终点,我们必须知道层的旋转角度。然后,第二个问题出来了:

我们都知道,如果涉及到动画,层会把动画过程交给presentationLayer。至于动画的初值和终值之间的中间值,由系统不断计算,通过表示层显示。

既然选择了一个层,就需要知道它的transform属性是一个名为cattransform的结构变量,XXView的transform属性是一个名为CGAffineTransform的结构变量。前者自然没有A、B等成员变量,而是一个这样的矩阵结构:

其中m14、m24、m34、m44只是作为矩阵的占位符。通常m14,m24,m34设置为0,m44设置为1。

常见变更矩阵:

示例:层绕Z轴顺时针旋转的推导过程

矩阵变换:

在aa中,我们绕Z轴旋转,所以我们可以通过反正切变换函数将实际参数m21和m22的值相加来实时知道图层的当前旋转角度:

三角函数:

tanθ = {sinθ\over cosθ}

θ = atan({sinθ\over cosθ})

θ = atan2({sinθ,cosθ})

借助数学归纳公式,坐标转换计算公式可以统一为以下形式:

在层的旋转过程中,针的起点和终点通过上述计算。然后生成一条Bezier曲线,再添加到整体Bezier曲线上,赋给CAShapeLayer (disk)的路径,从而达到生成针的效果。

游戏效果: