UGUI实现拼图游戏

首先看看效果图

拼图完成后,会显示game over

来看看工程结构图

Canvas:画布

kanpask:背包

cell 格子,每个格子上面放一个分割的图片

food就是要拖动的图片

这里cell-food创建一个预设体

准备一个图片。分割成精灵

kanpask:组建

因为这里是5x5的格子,表格布局(Grid Layout Group)x:100 y:100,spacing:x=1 y=1

所以款和高分别是504

food添加组建,来控制是否启用射线

创建createImge.cs脚本挂载在kanpask上

createImge.cs脚本

 1 using UnityEngine;
 2 using System.Collections;
 3 using UnityEngine.UI;
 4
 5 /// <summary>
 6 /// 创建图片,打乱图片排序。然后显示在格子里面
 7 /// </summary>
 8 public class createImge : MonoBehaviour
 9 {
10
11     public Sprite[] sprite; //要显示的图片精灵
12     public GameObject imgPrefab;//生产格子的预设体,这里是父子关系 cell-food
13
14     GameObject[] cells; //保存当前生产的图片精灵,为了拼图后的比较
15
16     public static createImge instance; //单列
17
18     void Awake()
19     {
20         instance = this; //单列脚本
21     }
22
23     // Use this for initialization
24     void Start()
25     {
26         //随机排序图片 ,
27         for (int i = 0; i < sprite.Length; i++)
28         {
29             int index = Random.Range(i, sprite.Length);
30             Sprite temp = sprite[i];
31             sprite[i] = sprite[index];
32             sprite[index] = temp;
33         }
34         cells = new GameObject[sprite.Length];
35         //开始生成对象,并显示在场景
36         for (int i = 0; i < sprite.Length; i++)
37         {
38             //GameObject o = Instantiate(imgPrefab) as GameObject;
39             cells[i] = Instantiate(imgPrefab) as GameObject;
40
41             cells[i].name = "exceed_" + i.ToString();
42
43             cells[i].transform.GetChild(0).GetComponent<Image>().sprite = sprite[i];
44             cells[i].transform.SetParent(transform);
45             //因为是给子对象赋值,所以先找到第一个子对象GetChild(0),然后找到Image组建赋值精灵
46             cells[i].transform.GetChild(0).GetComponent<Image>().sprite = sprite[i];
47             //设置当前对象的父对象
48             cells[i].transform.SetParent(transform);
49             //为了保证生成的对象没有缩放模式,写Vector3(1, 1, 1)的简码。
50             cells[i].transform.localScale = Vector3.one;
51         }
52     }
53
54     // Update is called once per frame
55     void Update()
56     {
57
58     }
59     /// <summary>
60     /// 判断是否已经拼图成功
61     /// </summary>
62     /// <returns></returns>
63     public bool IsFinsid()
64     {
65         Sprite food;
66         foreach (GameObject cell in cells)
67         {
68             //笔记父物体和子物体名子是否相等
69             food = cell.transform.GetChild(0).GetComponent<Image>().sprite;
70             if (cell.name != food.name)
71             {
72                 return false;
73             }
74         }
75         return true;
76     }
77 }

运行游戏看看层次图

红色标记的一个预设体。没用的

接下来是看拖拽代码了

创建createDrag.cs挂载在food上面

createDrag.脚本

  1 using UnityEngine;
  2 using System.Collections;
  3 using UnityEngine.UI;
  4 using UnityEngine.EventSystems;
  5 public class createDrag : MonoBehaviour
  6     , IBeginDragHandler, IDragHandler, IEndDragHandler
  7 {
  8     /*
  9      拖拽原理:是有很多格子(cell),cell里面有拖动的对象,cell可以做背景图片
 10      * 1:程序运行要找到当前物体(即拖动的对象)的位置坐标,也需要临时用了当父物体容器的对象(这样避免遮挡效果),找到被拖动物体的CanvasGroup(CanvasGroup 包含blocksRaycasts属性 如果开启则可以设置是否射线检测到(才能执行相应的事件))
 11      * 2:拖拽开始,记录拖拽前物体的坐标,并设置当前物体为临时容器的子对象,并取消被拖拽物体的射线检测,
 12      * 3:获取拖到目标点上的对象。跟当前拖动前的位置交换即可
 13  */
 14
 15     //自己的RectTransform
 16     RectTransform rf;
 17     //Vector3 oldPosition;//原来的位置,拖拽前的位置
 18     Vector3 newPosition;//拖拽中的位置
 19
 20     //画布的RectTransform,开始拖拽的时候设它为父物体,避免遮挡效果,如果图片不在Canves中则会被挡住
 21     RectTransform knapsackRF;
 22     //原来的格子的RectTransform
 23     RectTransform cellRF;
 24
 25     CanvasGroup cg;
 26
 27     bool isDrag; //是否开始拖拽
 28
 29     GameObject enterGameObject;
 30
 31
 32     //查找到对象
 33     void Awake()
 34     {
 35         rf = GetComponent<RectTransform>();
 36         knapsackRF = GameObject.FindWithTag("kanpask").GetComponent<RectTransform>();
 37         cg = GetComponent<CanvasGroup>(); //CanvasGroup 包含blocksRaycasts属性 如果开启则可以设置是否射线检测到(才能执行相应的事件)
 38     }
 39
 40
 41     /// <summary>
 42     /// 开始拖拽
 43     /// </summary>
 44     /// <param name="eventData"></param>
 45     public void OnBeginDrag(PointerEventData eventData)
 46     {
 47         //oldPosition = rf.position;
 48
 49         //每次开始拖拽前记录它的原始父物体
 50         cellRF = rf.parent.GetComponent<RectTransform>();
 51         //开始拖拽的时候,设置当前的父物体  注意顺序,必须先获取在设置父物体,
 52         rf.SetParent(knapsackRF);
 53         // 开始拖拽后不能被射线检测到
 54         /*
 55          因为事件都是靠射线检测的。当拖动图片到另外一张图片上的时候,
 56          * 从鼠标发出的射线就会执行当前被拖动的物体。射线就停止了(因为射线碰到物体就会停止),这样射线就不会触碰到下面那个图片
 57          * 也就获取不到要放置物体位置的信息了。
 58          */
 59         cg.blocksRaycasts = false;
 60         isDrag = true;
 61     }
 62     /// <summary>
 63     /// 拖拽中
 64     /// </summary>
 65     /// <param name="eventData"></param>
 66     public void OnDrag(PointerEventData eventData)
 67     {
 68         if (isDrag) //必须要执行了OnBeginDrag才执行OnDrag 有时候会遇到不执行OnBeginDrag
 69         {
 70             // 通过屏幕中的鼠标点,获取在父节点中的鼠标点
 71             RectTransformUtility.ScreenPointToWorldPointInRectangle(rf, eventData.position, eventData.enterEventCamera, out newPosition);
 72             rf.position = newPosition; //设置拖动的图片的位置
 73             //print(newPosition);
 74         }
 75     }
 76
 77     /// <summary>
 78     /// 结束拖拽
 79     /// </summary>
 80     /// <param name="eventData"></param>
 81     public void OnEndDrag(PointerEventData eventData)
 82     {
 83         if (isDrag) //
 84         {
 85             enterGameObject = eventData.pointerEnter;//获取当前点上的对象(这样也 是根据射线检测的),也就是拖拽的物体放到了那个物体上面
 86
 87             //如果拖拽到空的地方
 88             if (enterGameObject == null)
 89             {
 90                 MySetParent(rf, cellRF);
 91             }
 92             else //如果非空
 93             {
 94                 //cell--food是父子关系,坐标相同。所以food会把cell覆盖。UGUI是这样的
 95
 96                 switch (enterGameObject.tag)
 97                 {
 98                     case "cell":
 99                         MySetParent(rf, enterGameObject.transform); //如果是格子,即格子上没有图片 是后面的白板
100                         break;
101                     case "food": //即格子上有图片
102                         MySetParent(rf, enterGameObject.transform.parent); //把当前拖动的图片放到指定位置
103                         MySetParent(enterGameObject.transform, cellRF); //把当前的图片放大我拖动图片的位置 ,即我拖动图片要放的位置 。这个位置的图片放到被拖动来之前的位置 ,就是交换位置
104                         break;
105                     default:
106                         MySetParent(rf, cellRF);
107                         break;
108                 }
109             }
110             //结束拖拽后可以被射线检测到
111             cg.blocksRaycasts = true;
112             isDrag = false;
113         }
114         //每次拖拽结束判断是否拼图完成
115         if (createImge.instance.IsFinsid())
116         {
117             print("game over");
118         }
119     }
120     //建立父子关系的方法
121     void MySetParent(Transform son, Transform parent)
122     {
123         son.SetParent(parent); //设置父子关系
124         son.localPosition = Vector3.zero;//设置坐标为0点基于父物体
125         //或者
126         //son.localPosition = Vector3.one;
127     }
128 }
时间: 2024-10-10 17:16:26

UGUI实现拼图游戏的相关文章

一款html拼图游戏详解

本文是爱编程原创翻译,转载请看清文末的转载要求,谢谢合作! 游戏介绍 这篇文章是献给web游戏开发者用简单的开发工具开发一款游戏.此文介绍了用html.css.javascript只需简单和几个步骤开发一款2d游戏.在这里,我要呈现给大家如何创建一款拼图游戏,在这个游戏中你可以拖动小图块来拼成完整的大图. 点击这里查看游戏效果. 游戏规则 游戏规则非常简单,你只要拖动被切碎的图片块来组成完整的大图.需要用正确的方法才能最终拼成完整的图片.在游戏中拖动小图片的次数将被统计下来.所以.应该尽量用最少

Vue.js实现拼图游戏

Vue.js实现拼图游戏 之前写过一篇<基于Vue.js的表格分页组件>的文章,主要介绍了Vue组件的编写方法,有兴趣的可以访问这里进行阅读:http://www.cnblogs.com/luozhihao/p/5516065.html 前言 为了进一步让大家了解Vue.js的神奇魅力,了解Vue.js的一种以数据为驱动的理念,本文主要利用Vue实现了一个数字拼图游戏,其原理并不是很复杂,效果图如下: demo展示地址为:https://luozhihao.github.io/vue-puzz

Entanglement Web App(六边拼图游戏)

插件介绍: 对常常面对电脑工作的朋友们来说,一款能够让你们放松的游戏是必不可少的,今天为大家推荐一款度过休闲时光的小游戏.纠缠是gopherwood工作室为您做的六边拼图的益智游戏,试着使最长的路成为可能.旋转和放置六角形瓷砖蚀刻路径,以延长您的路径,而不运行到墙上. 使用说明: 将Entanglement Web App(六边拼图游戏)添加至chrome,并在应用中启动它. 功能介绍: - 挑战模式;你可以不断挑战自己或者他人的记录.- 樱花小树林:一个完全新的游戏游戏模式的纠缠!你有一个宽敞

JavaScript写一个拼图游戏

拼图游戏的代码400行, 有点多了, 在线DEMO的地址是:打开: 因为使用canvas,所以某些浏览器是不支持的: you know: 为什么要用canvas(⊙o⊙)?  因为图片是一整张jpg或者png, 我们要用把图片导入到canvas画布, 然后再调用上下文context的getImageData方法, 把图片处理成小图, 这些小图就作为拼图的基本单位: 如何判断游戏是否结束, 或者说如何判断用户拼成的大图是正确的? 我们就要在刚刚生成的小图上面添加自定义属性, 后期在小图被移动后再一

拼图游戏(数码还原游戏)算法的研究

将问题一般化,在M*N的方格里有M*N-1个不同元素和一个空元素,只有空元素可以与上下左右相邻的元素交换位置.M*N方格中M*N-1个元素和一个空元素的位置确定一个图形.拼图游戏的问题是:一个图形经过一连串的交换能否得到另一个图形,如何得到.从交换方式的可逆性看出这种关系满足等价三性质,如果图形A通过交换变成图形B我们则称它们是等价的.把M*N-1个元素用1至M*N-1编号,空元素编号0.然后展成一个排列.每个图形对应一个排列.确定了展开方式,图形和排列是一一对应的.这里用到的展开方式是行优先的

类似拼图游戏设计

客户端设计 1.如何绘制? 分上下两层,下层为最终图片,上层尺寸和下层一致,并将上层分割为 m 行 n 列的方格. 2.方格位置如何设定? m 行 n 列的方格,设定左上角坐标为(0,0),那么最右下角坐标为( (m-1) , (n-1) ). 3.如何定义方格对象,及方格拥有什么方法和属性? 方格Pane有4个属性: locationX,locationY,PaneState,visitor. (locationX,locationY)组成方格位置信息: PaneState包含3种状态,VIS

程序设计 之 C#实现《拼图游戏》 (下) 原理篇

前言:在 http://www.cnblogs.com/labixiaohei/p/6698887.html 程序设计 之 C#实现<拼图游戏>(上),上传了各模块代码,而在本文中将详细剖析原理,使读者更容易理解并学习,程序有诸多问题,欢迎指出,共同学习成长! 正文: 拼图是一个非常经典的游戏,基本每个人都知道他的玩法,他的开始,运行,结束.那么,当我们想要做拼图的时候如何入手呢?答案是:从现实出发,去描述需求(尽量描述为文档),当我们拥有了全面的需求,就能够提供可靠的策略,从而在代码中实现,

拼图游戏(数码还原游戏)的实现

一.游戏规则 首先,这里的拼图游戏是滑块拼图,类似于华容道,游戏者通过移动拼图块将拼图还原为初始形状.关于拼图,常见的有3x3,4x4,多的以至于有16x16不等.一般块数越多拼图越复杂. 这里对游戏规则进行较严格的定义: 1. 游戏初始化时,将图形分为nxn个正方形块,随机摆放在原图形位置.一般以原图形右下角的一块为空白块,已进行移动.这里初始化时,也令新图形的右下角为空. 2. 游戏中,拼图的移动只能向空白块移动.从移动方向来说,有两种情况,分别是横移与纵移. 3. 游戏的胜利条件是将打乱的

拼图游戏---需求分析

各位领导/投资人/用户/合作伙伴:我们的产品--趣拼图是为了游戏中的暴力因素以及无聊.,我们有独特的办法制作一个游戏,它能给用户带来更多好处,比如生活知识的普及,智力的开发等,同时我们有更高效率的一传十,十传百的方法,能让更多用户知道我们的产品,并进一步的传播. 在经过众多假设以及实践,我们组决定做一个开发智力的拼图游戏.我发现现在大多数游戏都是按部就班,玩家需要按照游戏制定的规则来活动,那这样,游戏除了娱乐也就没有其他的意义.经过调查,发现现在人,喜欢玩一些格斗[比如拳皇].跑酷[比如神庙逃亡