码迷,mamicode.com
首页 > 其他好文 > 详细

UGUI实现拼图游戏

时间:2015-06-29 22:05:57      阅读:288      评论:0      收藏:0      [点我收藏+]

标签:

首先看看效果图

技术分享

拼图完成后,会显示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 }

 

UGUI实现拼图游戏

标签:

原文地址:http://www.cnblogs.com/nsky/p/4608424.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!