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 }

 

你可能感兴趣的:(GUI)