实现方式

1、引入UGUI自带的事件系统  UnityEngine.EventSystems

2、为我们的类添加接口  IBeginDragHandler, IDragHandler, IEndDragHandler

 using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems; public class DragOnPic : MonoBehaviour,IBeginDragHandler, IDragHandler, IEndDragHandler { public void OnBeginDrag (PointerEventData eventData)
{
throw new System.NotImplementedException ();
} void IDragHandler.OnDrag (PointerEventData eventData)
{
throw new System.NotImplementedException ();
} public void OnEndDrag (PointerEventData eventData)
{
throw new System.NotImplementedException ();
} }

拼图游戏实例

1、准备一张拼图要用到的图片素材,并拖入Unity中

2、图片的TextureType选为Sprite(2D and UI), 点击Apply

3、将SpriteMode改为Multiple,点击SpriteEditor,在弹出的窗口中点Slice,Type为Grid,我这张图片分辨率是500x500的,拆分为16份,所以我的PixelSize是125x125,最终结果如下图:

4、添加一个Panel作为背景,为Panel添加GridLayoutGroup组件,具体设置如下,添加脚本ImageCreater用于生成图片

5、为Panel添加一个Image作为我们拼图的格子的背景,名字改为Cell,在这个Cell上再添加一个Image作为图片的载体,并将它的Tag设置为Cell,为Image添加拖拽脚本DragOnPic,将Cell拖成预制体备用

6、新建一个GameManager类用于实现随机生成图片的功能

 public class GameManager  {

     /// <summary>
/// Randoms the array.
/// </summary>
static public void RandomArray(Sprite[] sprites)
{
for (int i = ; i < sprites.Length; i++) {
//随机抽取数字中的一个位置,并将这张图片与第i张图片交换.
int index = Random.Range(i, sprites.Length);
Sprite temp = sprites[i];
sprites[i] = sprites[index];
sprites[index] = temp;
}
}
}

7、在ImageCreater中写入生产图片的方法

 using UnityEngine;
using System.Collections;
using UnityEngine.UI; public class ImageCreater : MonoBehaviour { public static ImageCreater _instance; //存储裁剪好图片的数组.
public Sprite[] sprites; //格子的预设体.
public GameObject cellPrefab; void Start () {
_instance = this;
CreateImages();
} private void CreateImages()
{
//将图片数组随机排列.
GameManager.RandomArray(sprites); //生产图片.
for (int i = ; i < sprites.Length; i++) {
//通过预设体生成图片.
GameObject cell = (GameObject)Instantiate(cellPrefab); //设置cell的名字方便检测是否完成拼图.
cell.name = i.ToString(); //获取cell的子物体.
Transform image = cell.transform.GetChild(); //设置显示的图片.
image.GetComponent<Image>().sprite = sprites[i]; //设置子物体的名称,方便检测是否完成拼图.
int tempIndex = sprites[i].name.LastIndexOf('_');
image.name = sprites[i].name.Substring(tempIndex + ); //将Cell设置为Panel的子物体.
cell.transform.SetParent(this.transform); //初始化大小.
cell.transform.localScale = Vector3.one;
}
} }

8、到这里,拼图游戏已经基本成形,下面只需要实现每张图片的拖拽功能就OK了,下面是DragOnPic的代码

 using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems; public class DragOnPic : MonoBehaviour,IBeginDragHandler, IDragHandler, IEndDragHandler { //记录下自己的父物体.
Transform myParent; //Panel,使拖拽是显示在最上方.
Transform tempParent; CanvasGroup cg;
RectTransform rt; //记录鼠标位置.
Vector3 newPosition; void Awake()
{
//添加CanvasGroup组件用于在拖拽是忽略自己,从而检测到被交换的图片.
cg = this.gameObject.AddComponent<CanvasGroup>(); rt = this.GetComponent<RectTransform>(); tempParent = GameObject.Find("Canvas").transform;
} /// <summary>
/// Raises the begin drag event.
/// </summary>
public void OnBeginDrag (PointerEventData eventData)
{
//拖拽开始时记下自己的父物体.
myParent = transform.parent; //拖拽开始时禁用检测.
cg.blocksRaycasts = false; this.transform.SetParent(tempParent);
} /// <summary>
/// Raises the drag event.
/// </summary>
void IDragHandler.OnDrag (PointerEventData eventData)
{
//推拽是图片跟随鼠标移动.
RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, Input.mousePosition, eventData.enterEventCamera, out newPosition);
transform.position = newPosition;
} /// <summary>
/// Raises the end drag event.
/// </summary>
public void OnEndDrag (PointerEventData eventData)
{
//获取鼠标下面的物体.
GameObject target = eventData.pointerEnter; //如果能检测到物体.
if(target)
{
GameManager.SetParent(this.transform, target.transform, myParent);
}
else {
this.transform.SetParent (myParent);
this.transform.localPosition = Vector3.zero;
} //拖拽结束时启用检测.
cg.blocksRaycasts = true; //检测是否完成拼图.
if(GameManager.CheckWin())
{
Debug.Log("Win!!!");
} } }

在GameManager中加入设置父物体的方法及检测是否完成拼图的方法:

 1    /// <summary>
/// Sets the parent.
/// </summary>
static public void SetParent(Transform mine, Transform target, Transform oldParent)
{
//如果检测到图片,则交换父物体并重置位置.
switch (target.tag)
{
case "Cell":
mine.SetParent(target.parent);
target.SetParent(oldParent);
mine.localPosition = Vector3.zero;
target.localPosition = Vector3.zero;
break;
default:
mine.SetParent (oldParent);
mine.localPosition = Vector3.zero;
break;
}
} /// <summary>
/// Checks is win.
/// </summary>
static public bool CheckWin()
{
for (int i = ; i < ImageCreater._instance.transform.childCount; i++) {
if(ImageCreater._instance.transform.GetChild(i).name != ImageCreater._instance.transform.GetChild (i).transform.GetChild().name)
{
return false;
}
}
return true;
}

到这里,拼图的基本功能就算是全部完成了

网页版预览

PC版下载

使用UGUI实现拖拽功能(拼图小游戏)的更多相关文章

  1. 使用NGUI实现拖拽功能(拼图小游戏)

    上一次用UGUI实现了拼图小游戏,这次,我们来用NGUI来实现 实现原理 NGUI中提供了拖拽的基类UIDragDropItem,所以我们要做的就是在要拖拽的图片上加一个继承于该类的脚本,并实现其中的 ...

  2. canvas drag 实现拖拽拼图小游戏

    博主一直心心念念想做一个小游戏-  前端时间终于做了一个小游戏,直到现在才来总结,哈哈- 以后要勤奋点更新博客! 实现原理 1.如何切图? 用之前的方法就是使用photoshop将图片切成相应大小的图 ...

  3. React Editor 应用编辑器(1) - 拖拽功能剖析

    这是可视化编辑器 Gaea-Editor 的第一篇连载分析文章,希望我能在有限的篇幅讲清楚制作这个网页编辑器的动机,以及可能带来的美好使用前景(画大饼).它会具有如下几个特征: 运行在网页 文档流布局 ...

  4. JQuery UI的拖拽功能

    JQuery UI是JQuery官方支持的WebUI 代码库,包含底层交互.动画.特效等API,并且封装了一些Web小部件(Widget).同时,JQuery UI继承了jquery的插件支持,有大量 ...

  5. Js元素拖拽功能实现

    Js元素拖拽功能实现 需要解决的问题 最近项目遇到了一个问题,就是用户某个操作需要弹出一个自定义的内容输入框,但是有个缺点,当浏览太大的时候没办法点击确认和取消按钮,应为这个弹出框是采用绝对定位的,取 ...

  6. (Demo分享)利用JavaScript(JS)实现一个九宫格拖拽功能

    利用JavaScript(JS)实现一个九宫格拖拽功能   Demo实现了对任意方格进行拖拽,可以交换位置,其中Demo-1利用了勾股定理判断距离! Demo-1整体思路: 1.首先div实现自由移动 ...

  7. html5中的拖拽功能

    拖拽元素支持的事件 ondrag 应用于拖拽元素,整个拖拽过程都会调用 ondragstart 应用于拖拽元素,当拖拽开始时调用 ondragleave 应用于拖拽元素,当鼠标离开拖拽元素是调用 on ...

  8. 使用 vue3 的自定义指令给 element-plus 的 el-dialog 增加拖拽功能

    element-plus 提供的 el-dialog 对话框功能非常强大,只是美中不足不能通过拖拽的方式改变位置,有点小遗憾,那么怎么办呢?我们可以通过 vue 的自定义指令来实现一个可以拖拽的对话框 ...

  9. RCP:拖拽功能的实现 Drag and Drop

    SWT中的拖拽是使用的org.eclipse.swt.dnd. 有三个需要密切注意的类: 1.DragSource 2.DropTarget 3.Transfer DragSource封装了需要被拖拽 ...

随机推荐

  1. 深入.NET平台和C#编程

    第一章  深入.NET框架 1.Microsoft.NET框架概述: 1).NET介绍 2)为什么需要.NET框架 通过如下两个问题说明为什么需要.NET框架 01,C#程序可以再不同平台(PDA,P ...

  2. 标准I/O 缓存

    标准I/O提供了三种类型的缓存: (1)全缓存.在这种情况下,当填满标准I/O 缓存后才进行实际 I/O 操作.对于驻在磁盘上的文件通常是由标准I/O库实施全缓存的.在一个流上执行第一次I/O操作时, ...

  3. CoreJavaE10V1P3.6 第3章 Java的基本编程结构-3.6 字符串 String

    String类(java.lang.String)就是Unicode字符序列,例如:"Java\u2122" 3.6.1 Substring 提取子串 String greetin ...

  4. Python网络编程学习_Day11

    一.协程 1.理论知识 协程,又称伪线程,是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈. ...

  5. php计算几分钟前、几小时前、几天前的几个函数分享

    /* * 精确时间间隔函数 * $time 发布时间 如 1356973323 * $str 输出格式 如 Y-m-d H:i:s * 半年的秒数为15552000,1年为31104000,此处用半年 ...

  6. java操作mongodb——插入数据

    在mongodb中,表(Table)被称之为集合(Collection),记录(Record)被称为文档(Document) 首先连接到数据库 MongoClient mongoClient = ne ...

  7. 【1】ShopNC 模仿笔记(一)

    不断学习,人生将会成功. 1. 序 一直想模仿一个整套的商城, 今天在shopNC 里面看到了想要的一切, 所以把一些组件, 命名规范等记录下来, 提高以后的开发效率. 官方网站 PC : shopN ...

  8. how to make a git repo un-git?

    If you have a git repo and now you want to make it a plain filesystem tree .. (removing the git trac ...

  9. Java版冒泡排序和选择排序

    一.理解说明 1.理解和记忆 冒泡排序:依次定位数组元素,每次只和相邻的且符合条件的元素交换位置. 选择排序:依次在数组的每个位置,通过逐个对比选择出最大或最小的元素. 2.知识点说明 (1)数组是引 ...

  10. lvs 会话保持(转发)

    lvs & keepalived的tcp 长连接的问题解决办法 虽然应用keepalived搞定了后端服务负载均衡和高可用性问题,但是在具体应用的时候,还是要注意很多问题.很多应用都用tcp或 ...