unity C#拼图游戏Demo

 拼图块脚本

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;


public class ItemPuzzle : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler//IPointerDownHandler, IPointerUpHandler
{

    [Header("正确位置下标")]
    public int CorrectIndex;
    [Header("当前位置下标")]
    [HideInInspector]
    public int CurrIndex;
    /// <summary>
    /// 交换下标
    /// </summary>
    private int ExchangeIndex;

    /// <summary>
    /// 开始拖拽位置(用于判断拖拽方向,防止斜着拖动)
    /// </summary>
    private Vector2 startDragPosition;
    /// <summary>
    /// 拖拽中位置(用于判断拖拽方向,防止斜着拖动)
    /// </summary>
    private Vector2 endDragPosition;
    /// <summary>
    /// 原始交换坐标
    /// </summary>
    private Vector3 m_ExchangePosition;
    private Transform startParent;

    /// <summary>
    /// 交换的
    /// </summary>
    private ItemPuzzle m_ExchangePiece;

    /// <summary>
    /// 检查
    /// </summary>
    private Action OnCheck;

    public void OnBeginDrag(PointerEventData eventData)
    {
        startDragPosition = eventData.position;

        startParent = transform.parent;
        transform.SetParent(transform.root);
        GetComponent<CanvasGroup>().blocksRaycasts = false;
    }

    public void OnDrag(PointerEventData eventData)
    {
        endDragPosition = eventData.position;
        if (!DetectDragDirection()) return;

        m_ExchangePiece = GetExchangePiece(eventData);
        if (m_ExchangePiece == null) return;

        if (eventData.pointerEnter.layer != 6 || m_ExchangePiece.CorrectIndex != 0)
        {
            transform.position = m_ExchangePosition;
            return;
        }

        //Vector2 offset = (Vector2)startPosition - eventData.position;

        //float X = Mathf.Clamp(offset.x, -100, 100);
        //float Y = Mathf.Clamp(offset.y, -100, 100);

        //offset = new Vector2(X, Y);
        //Debug.Log(eventData.pointerEnter.tag);
        //transform.position = (Vector2)startPosition - offset;


        //被交换的交换 给当前的当前
        transform.position = m_ExchangePiece.m_ExchangePosition;
        CurrIndex = m_ExchangePiece.ExchangeIndex;

        //当前的交换 给 交换的当前
        m_ExchangePiece.transform.position = m_ExchangePosition;
        m_ExchangePiece.CurrIndex = ExchangeIndex;

        //当前的当前 给当前的交换
        m_ExchangePosition = transform.position;
        ExchangeIndex = CurrIndex;

        //交换的当前 给 交换的交换
        m_ExchangePiece.m_ExchangePosition = m_ExchangePiece.transform.position;
        m_ExchangePiece.ExchangeIndex = m_ExchangePiece.CurrIndex;

    }

    public void OnEndDrag(PointerEventData eventData)
    {

        transform.SetParent(startParent);
        GetComponent<CanvasGroup>().blocksRaycasts = true;

        //检查拼图块是否到达正确位置
        if (OnCheck != null) OnCheck();
    }

    private ItemPuzzle GetExchangePiece(PointerEventData eventData)
    {
        ItemPuzzle m_ExchangePiece = eventData.pointerCurrentRaycast.gameObject.GetComponent<ItemPuzzle>();

        return m_ExchangePiece;
    }

    #region SetUI 设置当前下标和交换下标
    /// <summary>
    /// 设置当前下标和交换下标
    /// </summary>
    /// <param name="index">下标</param>
    /// <param name="pos">位置</param>
    public void SetUI(int index, Vector3 pos, Action onCheck)
    {
        ExchangeIndex = CurrIndex = index;
        m_ExchangePosition = transform.position = pos;
        OnCheck = onCheck;

        Debug.Log("下标=" + index);
        Debug.Log("位置=" + pos);
    }
    #endregion

    #region DetectDragDirection 计算拖拽的方向并将其转换为角度。通过判断角度的范围,可以确定拖拽的主要方向(上、下、左、右)
    /// <summary>
    /// 计算拖拽的方向并将其转换为角度。通过判断角度的范围,可以确定拖拽的主要方向(上、下、左、右)
    /// </summary>
    /// <returns></returns>
    private bool DetectDragDirection()
    {
        Vector2 direction = endDragPosition - startDragPosition;
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;

        if (angle < 0) angle += 360; // Convert negative angles to positive

        //Debug.Log($"Drag Angle: {angle}");

        //if (angle >= 45 && angle < 135)
        //{
        //    Debug.Log("Dragged Upward");
        //}
        //else if (angle >= 135 && angle < 225)
        //{
        //    Debug.Log("Dragged Leftward");
        //}
        //else if (angle >= 225 && angle < 315)
        //{
        //    Debug.Log("Dragged Downward");
        //}
        //else
        //{
        //    Debug.Log("Dragged Rightward");
        //}

        if (angle >= 70 && angle < 110)
        {
            //Debug.Log("Dragged Upward");
            return true;
        }
        else if (angle >= 160 && angle < 200)
        {
            //Debug.Log("Dragged Leftward");
            return true;
        }
        else if (angle >= 250 && angle < 290)
        {
            //Debug.Log("Dragged Downward");
            return true;
        }
        else if (angle >= 340 || angle < 20)
        {
            //Debug.Log("Dragged Rightward");
            return true;
        }
        else
        {
            //Debug.Log("不能");
            return false;
        }
    }
    #endregion
}
 

生成拼图随机位置脚本

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;

public class PuzzlePiece : MonoBehaviour
{
    [Header("拼图块")]
    [SerializeField]
    private ItemPuzzle[] m_ItemPuzzles;

    [Header("拼图块位置")]
    [SerializeField]
    private Vector3[] m_Position;

    private void Start()
    {
        LoadRandomPos();
    }
    /// <summary>
    /// 加载随机位置
    /// </summary>
    private void LoadRandomPos()
    {
        if (m_ItemPuzzles == null || m_ItemPuzzles.Length == 0 || m_Position == null || m_Position.Length == 0) return;

        List<int> m_IndexList = GenerateUniqueRandomNumbers(9, 0, 8);
        for (int i = 0; i < m_IndexList.Count; ++i)
        {
            int index = m_IndexList[i];
            ItemPuzzle item = m_ItemPuzzles[i];
            Vector3 pos = m_Position[index];
            if (item != null)
            {
                item.SetUI(index, pos, OnCheckCallBack);
            }
        }

    }

    /// <summary>
    /// 检查回调
    /// </summary>
    private void OnCheckCallBack()
    {
        if (m_ItemPuzzles == null || m_ItemPuzzles.Length == 0) return;
        bool isSuccess = true;
        for (int i = 0; i < m_ItemPuzzles.Length; ++i)
        {
            ItemPuzzle item = m_ItemPuzzles[i];
            if (item != null)
            {

                if (item.CorrectIndex != item.CurrIndex)
                {
                    isSuccess = false;
                    break;
                }
            }
        }

        
        if (isSuccess)
        {
            //成功
            Debug.Log("拼图成功");
        }
        else
        {
            //失败
            Debug.Log("拼图失败");
        }
    }


    /// <summary>
    /// 生成不重复的随机数
    /// </summary>
    /// <param name="count">数组长度</param>
    /// <param name="minValue">最小(包括最小)</param>
    /// <param name="maxValue">最大(包括最大)</param>
    /// <returns></returns>
    /// <exception cref="ArgumentException"></exception>
    public List<int> GenerateUniqueRandomNumbers(int count, int minValue, int maxValue)
    {
        if (count > (maxValue - minValue + 1))
        {
            throw new ArgumentException("The count is too large for the given range.");
        }

        HashSet<int> uniqueNumbers = new HashSet<int>();
        System.Random random = new System.Random();

        while (uniqueNumbers.Count < count)
        {
            int number = random.Next(minValue, maxValue + 1);
            uniqueNumbers.Add(number);
        }

        return new List<int>(uniqueNumbers);
    }
}
 

成功样式

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值