基于unity3d和leap motion的拼图游戏
近期用unity3d引擎做了一个拼图游戏,会分几次写完,以此作为总结。
本文基本查找了网上能查到的全部资料作为參考。也算是大家节省了时间。
眼下仅仅完毕了拼图部分,leap motion手势控制部分会在兴许完毕,只是说实话不太看好LM。
项目资源来自 cube454517408 http://blog.csdn.net/cube454517408/article/details/7907247,只是玩法不同,玩法与小夭
tid=2852">http://game.ceeger.com/forum/read.php?
tid=2852同样。我也重写了前者的程序。部分实现思路不同,两个游戏的project在本文完毕后都会打包上传。
http://download.csdn.net/detail/smilingeyes/8234627
首先是整个游戏须要的模块。
一个拼图游戏大致须要例如以下几个控制模块:碎片显示,碎片随机打乱。随机排序后碎片顺序的合法性检查。移动控制,拼图是否完毕的检查。
游戏实现的思路为。建立N*N个plane。通过控制每一个plane的材质球贴图偏移形成碎片,最后一个plane使用透明贴图。使用数组纪录每一个碎片的偏移位置,和碎片的排列顺序。
移动碎片时。plane位置不发生变化。变化的是此plane贴图的偏移(详见第一部分碎片显示)。
一、碎片显示。
此部分能够有几种选择,第一个就是将每部分碎片单独做成图片,比方这个
http://tieba.baidu.com/p/2053275362 优点是处理比較方便,能够使用GUI处理,缺点是每一个图片都须要前期处理,并且因为前期分片的份数固定,游戏难度不能任意调整,除非每一个图都准备非常多不同难度的切割后的小图。
第二是使用NGUI中的Atlas,对图集中的sprite信息进行重定义。详细參考小夭的程序。当中用到了UISprite类中的outer结构体,outer记录了sprite在图集中的位置信息。可是在NGUI3.6版本号中outer已经不是UISprite的成员变量,是否还能用文中的方法进行改动没有尝试。假设有人尝试请留言告知,在此谢过。
第三是在材质球中设置纹理偏移和缩放,详细做法參考上面cube454517408的帖子。本人也是用的此种方法。
第二和第三种实现方法的优点是能够任意调整图片分成的份数,因此能够非常方便的调整游戏难度。
- <span style="font-size:18px;"> Vector2 offset; \\记录每一块碎片的偏移
- offset.x = origin.x + piecesLength * j;
- offset.y = origin.y - piecesLength * i;
- temp.transform.localPosition = new Vector3 (offset.x*10f,offset.y*10f);
- texOffset[k].x = j*transform.localScale.x/row; \\计算纹理偏移
- texOffset[k].y = (row-1-i)*transform.localScale.x/row;
- temp.renderer.material.mainTextureOffset = texOffset[k]; \\设置纹理偏移
- temp.renderer.material.mainTextureScale = new Vector2(transform.localScale.x/row,transform.localScale.x/row); \\设置纹理缩放</span>
由于图源为正方形。所以仅仅考虑了将其分为N*N块的分法,因此偏移和缩放的计算较为简单。
- void Display()
- {
- for (int i = 0; i < pieces.Length; i++) {
- pieces[i].renderer.material.mainTextureOffset = texOffset[squence[i]];
- pieces[i].renderer.enabled = isReander[squence[i]];
- }
- }
void Update ()的最后调用Display(),isRender数组保存了该碎片贴图是否显示,texOffset数组保存了每一个碎片贴图的偏移位置。
碎片显示部分就这么多内容,以下是碎片打乱算法。
二、碎片打乱算法
这里有两种不同的思路。第一种是小夭採用的,将正确排列的碎片随机移动若干次。以达到打乱碎片顺序的目的。该方法的优点是,用这样的方法生成的随机序列一定能够还原,缺点是实现起来较为复杂。详细实现见小夭的文章。
另外一种思路是採用洗牌算法,使用一个数组保存第N个碎片的纹理偏移,从第一个碎片開始与随机一个碎片交换内容,直到数组结束。算法实现起来比較简单,可是并不一定保证能够正确还原。
- void Shuffle()
- {
- Random.seed = System.Environment.TickCount;
- for (int i = 0; i < squence.Length - 1; i++) {
- int temp = squence[i];
- int randomIndex = Random.Range(0, squence.Length-1);
- squence[i] = squence[randomIndex];
- squence[randomIndex] = temp;
- }
- }
三、逆序和检验
通过洗牌算法得到的随机序列,并不一定能够还原成初始的顺序。这是由于在洗牌时改变了数组的逆序和。參加百度百科(不可还原的拼图)……http://baike.baidu.com/link?
url=2ajCBRlh6Ox1I1SPK8gEayd-aAaCITNNQjVSA09qDHDLXZM9Ndrp-thdWdjg-Xt_sRk3PCABt-3LUPDKfTZDy_
lemene对此进行了证明。喜欢数学证明的同学请见 http://www.cppblog.com/lemene/archive/2007/10/04/33405.html
shaomn的解说比較easy明确。http://blog.sina.com.cn/s/blog_4ed8b87701011c6x.html
对于数组squence[],定义其逆序和为sum += (i - j) * (squence [i] - squence [j]) > 0 ? 0 : 1;对于初始序列其逆序和为0,左右移动碎片时sum不变,上下移动时sum +2、-2或不变,可是不管如何移动。逆序和奇偶性是不变的。因此在洗牌算法之后,检验数组逆序和是否为偶数就可以。
- bool Check()
- {
- int sum = 0;
- for (int i = 0; i < squence.Length; i++)
- for (int j = 0; j < i; j++)
- sum += (i - j) * (squence [i] - squence [j]) > 0 ? 0 : 1;
- return sum % 2 == 1;
- }
四、移动控制
移动控制有两种思路,第一种是鼠标点击想要移动的碎片,检測碎片周围是否有空位置,假设有交换位置。
另外一种是按方向键。检測空位置周围是否有能够向按键方向移动的碎片。假设有交换位置。全然能够同一时候实现。本文仅仅实现了另外一种。由于要结合leap motion。另外一种操作方式和手势控制比較接近。
- if (Input.GetKeyDown ("left")) {
- MoveLeft();
- }
- if (Input.GetKeyDown ("right")) {
- MoveRight();
- }
- if (Input.GetKeyDown ("down")) {
- MoveDown();
- }
- if (Input.GetKeyDown ("up")) {
- MoveUp();
- }
其它移动函数与之类似。不一样的是推断条件。首先找到空白碎片(也就是开局时最后一个碎片)当前在的碎片队列中的顺序。将之与要移动的碎片交换在队列中的位置。
- void MoveLeft()
- {
- int last,temp;
- last = FindLastPiece();
- if(last%row < row-1)
- {
- temp = squence[last];
- squence[last] = squence[last+1];
- squence[last+1] = temp;
- }
- }
- int FindLastPiece()
- {
- int i=0;
- while(squence[i]!=squence.Length-1)
- {
- i++;
- }
- return i;
- }
使用leap motion进行手势控制在实现时採用了比較简单的逻辑,仅仅适用于本游戏。假设同一时候须要进行其它手势的推断则须要设计其它的约束条件。此处逻辑为推断手掌移动速度,超过某个方向的最大速度则推断为使碎片向该方向移动。leap motion 与unity结合开发的设置不再介绍。
为了降低误判,设置了一个控制是否启用手势控制的变量update,在检測到手势的0.5s内暂停手势控制。
- Leap.Hand hand = LeapControl.Hand;
- if (hand != null && update) {
- if (hand.PalmVelocity.x > minVelocity)
- {
- MoveRight();
- update = false;
- Invoke("SetUpdate",0.5f);
- }
- if (hand.PalmVelocity.x < -minVelocity)
- {
- MoveLeft();
- update = false;
- Invoke("SetUpdate",0.5f);
- }
- if (hand.PalmVelocity.y > minVelocity)
- {
- MoveUp();
- update = false;
- Invoke("SetUpdate",0.5f);
- }
- if (hand.PalmVelocity.y < -minVelocity)
- {
- MoveDown();
- update = false;
- Invoke("SetUpdate",0.5f);
- }
- }
五、游戏结束检測
在每次移动过后,检測是否完毕。
- bool Finish()
- {
- int i=0;
- while (i < squence.Length && i == squence[i])
- {
- i++;
- }
- if (i == squence.Length) {
- Debug.Log("finish!");
- return true;
- } else
- return false;
- }
基于unity3d和leap motion的拼图游戏的更多相关文章
- Unity3D中使用Leap Motion进行手势控制
Leap Motion作为一款手势识别设备,相比于Kniect,长处在于准确度. 在我的毕业设计<场景漫游器>的开发中.Leap Motion的手势控制作为重要的一个环节.以此,谈谈开发中 ...
- 基于unity3d游戏的android版本逆向初探
https://bbs.pediy.com/thread-212532.htm [文章标题]: 基于unity3d游戏的android版本逆向初探 [文章作者]: dreaman [作者邮箱]: [e ...
- 介绍用C#和VS2015开发基于Unity架构的2D、3D游戏的技术
[Unity]13.3 Realtime GI示例 摘要: 分类:Unity.C#.VS2015 创建日期:2016-04-19 一.简介 使用简单示例而不是使用实际示例的好处是能让你快速理解光照贴图 ...
- 利用Vue.js实现拼图游戏
之前写过一篇<基于Vue.js的表格分页组件>的文章,主要介绍了Vue组件的编写方法,有兴趣的可以访问这里进行阅读:http://www.cnblogs.com/luozhihao/p/5 ...
- 基于Unity3D 的Vuforia SDK开发基础教程
最新博客地址已转到: http://blog.csdn.net/zzlyw?viewmode=contents ------------------------------------------ ...
- JavaScript写一个拼图游戏
拼图游戏的代码400行, 有点多了, 在线DEMO的地址是:打开: 因为使用canvas,所以某些浏览器是不支持的: you know: 为什么要用canvas(⊙o⊙)? 因为图片是一整张jpg或 ...
- Leap Motion发布新平台,直击下一代移动端VR/AR手部追踪
2013年,动作捕捉技术公司Leap Motion发布了面向PC的体感控制器,不过销量并不乐观.随着2014年虚拟现实技术的再一次兴起,它发布一款用于Oculus Rift的附加设备,从而正式登上VR ...
- atitit.html5 拼图游戏的解决之道.
atitit.html5 拼图游戏的解决之道. 1. 拼图游戏的操作(点击法and 拖动法) 1 1. 支持键盘上.下.左.右键移动: 1 2. 支持点击空白模块中的上下左右箭头移动: 1 3. 支持 ...
- Vue.js实现拼图游戏
Vue.js实现拼图游戏 之前写过一篇<基于Vue.js的表格分页组件>的文章,主要介绍了Vue组件的编写方法,有兴趣的可以访问这里进行阅读:http://www.cnblogs.com/ ...
随机推荐
- 【Eclipse】调试java程序的九个技巧
本文转自[半夜乱弹琴],原文地址:http://www.cnblogs.com/lingiu/p/3802391.html 九个技巧: 逻辑结构 条件debug 异常断点 单步过滤 跳到帧 Inspe ...
- ios8.1上运行程序,程序界面只显示一部分
在ios 9.1上运行程序没问题 但是在8.1上运行发现模拟器上只显示了程序的一小部分界面,没有显示完全. 结果发现由以下代码设置问题引起的 - (BOOL)application:(UIApplic ...
- JAVA 中URL链接中文参数乱码的若干处理方法
方法一: http://xxx.do?ptname='我是中国人' String strPtname = request.getParameter("ptname"); strPt ...
- Android 应用内HttpClient 与 WebView 共享 Cookie
DefaultHttpClient httpclient=....; String toUrl="https://cap.cityu.edu.hk/studentlan/details.as ...
- vsftpd安装
原文连接:史上最详细的vsftpd配置文件讲解: http://www.9170.org/post-322.html 参考博文:centos启用ftp功能:http://os.51cto.com/ar ...
- QML在XP等显卡明显不好的情况下 可以参考
http://doc.qt.io/qt-5/windows-requirements.html
- ASP.NET MVC 5 学习教程:修改视图和布局页
原文 ASP.NET MVC 5 学习教程:修改视图和布局页 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 ...
- php函数参数
函数的参数 通过参数列表可以传递信息到函数,即以逗号作为分隔符的表达式列表.参数是从左向右求值的. PHP 支持按值传递参数(默认),通过引用传递参数以及默认参数.也支持可变长度参数列表,更多信息参见 ...
- 转:CSS圆角详解
CSS3是样式表(style sheet)语言的最新版本,它的一大优点就是支持圆角. 网页设计大师Nicholas Zakas的最新文章,清晰易懂地解释了CSS3圆角的各个方面,非常值得学习.以下就是 ...
- cocos2dx进阶学习之CCApplication
继承关系 CCApplication-> CCApplicationProtocol 类主要成员变量 static CCApplication * sm_pSharedApplication; ...