见缝插针c语言编程,见缝插针游戏的实现
游戏的背景:
前言:这个游戏是2015年出来的,刚开始当时aa(见缝插针)游戏很火,我也是玩了好大半天,深深地求虐感屡试不爽。那个时候我还是一个iOS小兵一枚,当时就感觉这游戏如此简单到炸裂,于是就想着尝试实现它,但是...(此处省略100字)。
时间过得真快,过去了两年,偶然翻看博客,发现有人也有相似的实现和想法,并且提供了很好的思路。于是乎,我又下定决心研究一翻,这才有了今天的实现。
游戏的逻辑:
每一关你都有不同数量的“针”,中心的圆盘上初始状态可能就会有“针”已经插入就绪,不过这是为增加游戏难度而设计的。你的任务就是将你所在关卡中所持有的所有“针”插入到中心转动的圆盘上去(插入点是相对固定的),前提是不能与其他“针”相互接触,否则游戏宣告失败。为了不让你很快通关,后面的关卡理所当然难度会越来越大,比如圆盘转速增加、初始就绪“针”数和持有针数增加、顺逆时针变速转动等。
实现思路:
中心的圆盘是一个CAShapeLayer,点击屏幕就去扩展CAShapeLayer的path,达到针插在圆盘上的效果。对于“针”的动态移动过程, 就可以创建一个过渡的“针”视图来等效代替。那么核心的问题就来了:我在扩展图层的路径时,怎么确定绘制的起始点和终点呢?因为在中心圆盘的旋转过程中,其上的个点也会随之一起做仿射变换。如果你在图层旋转时还是以圆盘静止时硬编码取到的起点和终点来确认绘制“针”的话,那么新绘制的“针”就会和之前“插上”的“针”重合在一起,导致的结果就是:无论你怎么“插针”,圆盘上看到的就只有一根“针”,虽然实际上它是很多“针”重叠在一起而表现出来的结果。
CAShapeLayer属于QuartzCore框架,继承自CALayer。CAShapeLayer是在坐标系内绘制贝塞尔曲线的,通过绘制贝塞尔曲线,设置shape(形状)的path(路径),从而绘制各种各样的图形以及不规则图形。因此,使用CAShapeLayer需要与UIBezierPath一起使用。
UIBezierPath类允许你在自定义的 View 中绘制和渲染由直线和曲线组成的路径。你可以在初始化的时候直接为你的UIBezierPath指定一个几何图形。
通俗点就是UIBezierPath用来指定绘制图形路径,而CAShapeLayer就是根据路径来绘图的。
仿射:无论变换矩阵用什么值,图层中平行的两条线在变换之后仍然保持平行。(平移,缩放,旋转等)
1、那么首要问题就是如何得到当前“针”的绘制起点和终点?
值得庆幸的是中心转轴是圆形的(故称之为圆盘),而且也只能是在圆形的情况下才能设计出aa这样的游戏效果。因为插针的起点和终点的计算依赖于圆形的中心到边界各点的距离相等这一性质,具体可以用如下两张图来表示坐标点的换算过程:
顺时针
逆时针
其中的基准点为在静止时“针”的插入点(对应于绘制“针”的起点),而终点可以通过相同的方法来实现换算,只不过半径r的值需要做出相应的调整。
基准点(x',y'),实际为了计算方便我们取(r,2r)
顺时针旋转诱导公式:
x = x' + r * sinθ
y = y' - r + r * cosθ
逆时针旋转诱导公式:
x = x' - r * sinθ
y = y' - r + r * cosθ
终点计算,只要把对应的r,换成实际的r即可。
根据公式,我们看出,要想求出针的起点和终点,我们必须知道图层旋转的角度。于是,第二个问题就出来了:
2、如何取得在旋转过程中图层的旋转角度?
我们都知道的是要是涉及到动画的话,图层会将动画的过程交给presentationLayer(表现层)来完成。至于动画的初值和终值之间的中间值则由系统不断计算,并通过表现层来展示。
既然我们选用的是图层,我们就需要知道它的transform属性是一个名为CATransform3D的结构体变量,而XXView的transform属性是一个名为CGAffineTransform的结构体变量。前者就自然没有a、b这样的成员变量,而是这样的一个矩阵结构:
struct CATransform3D
{
CGFloat m11, m12, m13, m14;
CGFloat m21, m22, m23, m24;
CGFloat m31, m32, m33, m34;
CGFloat m41, m42, m43, m44;
};
通过矩阵控制坐标变换
struct CATransform3D
{
CGFloat m11(x缩放), m12(y切变), m13(旋转), m14();
CGFloat m21(x切变), m22(y缩放), m23(和m32一起决定x轴的旋转), m24();
CGFloat m31(和m13一起决定y轴的旋转),m32(和m23一起决定x轴的旋转), m33(z缩放), m34(透视效果,要操作的这个对象要有旋转的角度,否则没有效果。正直/负值都有意义);
CGFloat m41(x平移), m42(y平移), m43(z平移), m44(初始为1);
};
其中的m14、m24、m34、m44只是作为矩阵的占位符,通常会将m14、m24、m34设置为0,m44设为1。
常见的变化矩阵:
常见的变换矩阵
举例:图层绕Z轴顺时针旋转推导过程
图层绕Z轴旋转推导
矩阵变换:
矩阵变换
x' = m11 * x + m21 * y + m31 * z + m41
y' = m12 * x + m22 * y + m32 * z + m42
z' = m13 * x + m23 * y + m33 * z + m43
x1 = cosB * x0 - sinB * y0
y1 = sinB * x0 + cosB * y0
cosB sinB 0 0
-sinB cosB 0 0
0 0 1 0
0 0 0 1
aa中我们是围绕z轴旋转的,我们就可以使用反正切变换函数参入实际参数m21、m22的值就可以实时地知道图层的当前旋转角度了:
三角函数:
tanθ = {sinθ\over cosθ}
θ = atan({sinθ\over cosθ})
θ = atan2({sinθ,cosθ})
func transformRotationAngle() -> CGFloat {
var degreeAngle:CGFloat = -CGFloat(atan2f(Float(self.presentation()!.transform.m21), Float(self.presentation()!.transform.m22)))
if (degreeAngle < 0.0) {
degreeAngle = degreeAngle + (CGFloat)(2.0 * Double.pi)
}
return degreeAngle;
}
借助于数学诱导公式,坐标的变换计算公式可以统一为如下形式:
func convertPointWhenRotatingWithBenchmarkPoint(point:CGPoint,radius:CGFloat) -> CGPoint {
let rotationAngle:CGFloat = (self.presentation()?.transformRotationAngle())!
return CGPoint.init(x: point.x + CGFloat(sinf(Float(rotationAngle))) * radius, y: point.y - radius + CGFloat(cosf(Float(rotationAngle))) * radius)
}
在图层的旋转过程中,针的起点和终点都通过以上计算出来了,接着,生成一个贝塞尔曲线,然后追加到整体的贝塞尔曲线中,再赋值给CAShapeLayer(圆盘)的path,这样就达到了针的生成效果。
let strokeBezier = UIBezierPath()
strokeBezier.move(to: strokeStartPoint)
strokeBezier.addLine(to: strokeEndPoint)
strokeBezier.move(to: strokeEndPoint)
strokeBezier.addArc(withCenter: strokeEndPoint, radius: kTopRoundRadius, startAngle: 0, endAngle: CGFloat(Double.pi * 2.0), clockwise: true)
self.arrowStrokePath.append(strokeBezier)
self.centralAxisLayer.path = self.arrowStrokePath.cgPath;
游戏效果:
游戏界面
Github:
https://github.com/SpringAndSummer/Game
参考资料:
https://blog.csdn.net/u013282174/article/details/50388546
https://blog.csdn.net/zmmzxxx/article/details/74276077
见缝插针c语言编程,见缝插针游戏的实现相关推荐
- c语言填数字游戏求解过程解读,c语言编程--数字游戏.doc
c语言编程--数字游戏 计算机实习报告 面向过程编程 用C语言求解实际问题 一.问题描述 游戏类第15个任务--猜数字游戏 计算机从0-9这10个数字中任意选择n个不重复数字(n≤10)组成一个5位数 ...
- java三子棋人机游戏_C语言编程入门游戏《三子棋》
经过C语言初级阶段的系统学习,对基本C语言的知识有了一定的了解和认识,能够通过C语言编程解决一些简单的问题.本次完成一个简单的游戏<三子棋>. 游戏简介:常见的3x3棋盘,有两名游戏玩家, ...
- C语言编程纸牌游戏运行结果,C语言编程,纸牌游戏
C语言编程,纸牌游戏 关注:170 答案:2 mip版 解决时间 2021-01-28 15:29 提问者孤独深渊 2021-01-28 08:16 编号为1-52张牌,正面向上,从第2张开始,以 ...
- c语言编程数独游戏,编程做数独游戏
数独游戏非常好玩,可以训练玩家的逻辑推理能力.数独游戏的规则是: 1.在9×9的大九宫格内,已给定若干数字,其他宫位留白,玩家需要自己按照逻辑推敲出剩下的空格里是什么数字. 2.必须满足的条件:每一行 ...
- go语言编程小游戏--贪吃蛇
前提准备条件:安装gcc环境,可以百度也 可以安装这个链接:https://pan.baidu.com/s/1BbXFcBZywK-k-eIkWqY3Ug 提取码:04wp 复制这段内容后打开百度网盘 ...
- python编写格斗游戏_基于C++语言编程格斗游戏毕业设计正文
摘 要 游戏自古至今都伴随并影响着人们的生活.截至 2013 年,中国游戏用户达 3.45 亿人, 游戏产业链的发展给游戏开发带来了无限的商机, 是未来信息产品的重要深化 方向之一.格斗游戏是出现的比 ...
- 猜数字游戏c语言编程,【游戏编程】猜数字游戏(C语言)
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 //此游戏规则为:系统随机生成一个整数,然后要你去猜它.系统会提示你是大了还是小了.游戏结束后会生成排行榜,有记录时间 #include #include ...
- c语言编程武侠游戏,代码一遍过的程序猿出现 《太吾绘卷》为何凭武侠版捉蛐蛐大火?...
原标题:代码一遍过的程序猿出现 <太吾绘卷>为何凭武侠版捉蛐蛐大火? 马上就要国庆了,虽然小编作为工作狗还没有放假,但表弟已经提前(逃课)放假,昨晚下班回家,表弟便兴冲冲的跑来问我问题:& ...
- 聊聊在博客园写博客的这两年《Unity 3D脚本编程:使用C#语言开发跨平台游戏》正式出版...
版本状态: 2016.9 第一次印刷 (2016.11 输出到台湾) 2017.1 第二次印刷 2017.5 第三次印刷 2017.5 电子书上线:Unity 3D脚本编程--使用C#语言开发跨平台游 ...
最新文章
- 能用条件注释改善的IE兼容问题
- 使用com.sun.imageio.plugins.png.PNGMetadata读取图片的元数据 1
- [linux]服务器apache配置vhost
- android点滴27:R文件无法加载 R cannot be resolved to a v...
- 蒋涛:重新回归的我,将带领 CSDN 全方位升级,为 AI 转型者打造一站式平台
- caffe安装步骤(Anaconda,Windows10环境下)
- sql md5或shal加密
- python中关于requests里的timeout()
- 极坐标可以用计算机吗,极坐标
- 硬件产品开发:外包五要素和外包地图
- C1模拟试卷的一个算法题
- 实现 外网 远程桌面 连接 个人pc(开机自启动,校园网web自动验证,多用户远程桌面)
- Ubuntu下如何下载linux内核源码
- 【HTML】HTML网页设计-----可爱多肉网页设计
- php 浏览商品足迹,iwebshop调取浏览足迹方法
- MTK-如何解锁OEM
- 科大奥锐干涉法测微小量实验的数据_大学物理实验报告答案解析大全(实验数据).doc...
- 不要妄想消费者忠诚于我们的品牌!
- 对于苹果电脑mac系统安装了windows双系统恢复成苹果单系统遇到的一些问题
- 金蝶K3cloud python插件之更新物料列表自定义字段(成本更新)