Unity做2d推箱子

2022-08-04,

最近用u3d做了一个简单的推箱子demo,比较简单 ,因为关卡数据就配置了三关,所以目前就三个关卡看图吧
因为比较简单 直接上代码了 如下所示:

using Move;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 推箱子主要逻辑
/// </summary>
public class MoveBoxManager : MonoBehaviour
{
    public enum ItemState
    {
        block = 0,   //障碍物
        box,   //箱子
        ground,  // 背景
        target,    //目标点
        player,       //玩家
        none       //无
    }
    public class Item
    {
        public ItemState ItemState;
        public int posX;
        public int posY;
    }
    private GameObject _grid;       //预设物父物体
    private GameObject _item;        //预设物
    private GameObject _player;        //玩家
    private Button refreshbt;       //刷新按钮
    private GameObject btnlist;      // 按钮的父物体
    private GameObject succeedPanel;       //成功界面 
    Item[,] gameObjectsArray = new Item[8, 5];    //地图的格子   5行7列
    private int levelCount = 1;
    //障碍区坐标
    List<string> blocklist;
    //箱子
    List<string> boxList;
    //  目标list
    List<string> targetList; 
                                                                     
    List<string> nonelist;
    /// 玩家坐标
    string playerstr = "";
    void  Awake()
    {
        _grid = transform.Find("Grid").gameObject;
        _item = transform.Find("Item").gameObject;
        _player = transform.Find("player").gameObject;
        refreshbt = transform.Find("refreshbt").GetComponent<Button>();
        btnlist = transform.Find("btnlist").gameObject;
        succeedPanel = transform.Find("gamesuccess").gameObject;
        refreshbt.onClick.AddListener(delegate()    //重置按钮
        {
            RePlay();
            Init(levelCount);
        });
        Button up = btnlist.transform.Find("up").GetComponent<Button>();
        up.onClick.AddListener(delegate ()    //上
        {
            CheckRoundBox(0, -1);
        });
        Button down = btnlist.transform.Find("down").GetComponent<Button>();
        down.onClick.AddListener(delegate ()    //下
        {
            CheckRoundBox(0, 1);
        });
        Button left = btnlist.transform.Find("left").GetComponent<Button>();
        left.onClick.AddListener(delegate ()    //左
        {
            CheckRoundBox(-1, 0);
        });
        Button right = btnlist.transform.Find("right").GetComponent<Button>();
        right.onClick.AddListener(delegate ()    //右
        {
            CheckRoundBox(1, 0);
        });
        Init();

    }
    /// <summary>
    /// 检测周边
    /// </summary>
    private void CheckRoundBox(int offsetX, int offsetY)
    {
        char[] chararray = playerstr.ToCharArray();
        int x = Convert.ToInt32(chararray[0].ToString());
        Debug.Log("x     " + x);
        int y = Convert.ToInt32(chararray[1].ToString());
        string up = (x + offsetX) + "" + (y + offsetY);
        if (isWall(up)) return;    //如果是墙的话
        if (isBox(up))     //如果是盒子的话
        {
            Debug.Log("如果是盒子");
            char[] chararray1 = up.ToCharArray();
            int x1 = Convert.ToInt32(chararray1[0].ToString());
            int y1 = Convert.ToInt32(chararray1[1].ToString());
            string up1 = (x1 + offsetX) + "" + (y1 + offsetY);
            if (isWall(up1) || isBox(up1))    //如果下下个位置是墙或者箱子
                return;
            GameObject box = GetBox(up);
            GameObject bg = GetBox(up1);
            _player.transform.position = box.transform.position;
            playerstr = up;
            Vector3 boxopos = bg.transform.localPosition;
            bg.transform.localPosition = box.transform.localPosition;
            box.transform.localPosition = boxopos;
            box.name = up1;     //换位置
            bg.name = up;
            boxList.Remove(up);
            boxList.Add(up1);
            if (isTarget(up1))      //正好推到目标点
            {
                bg.transform.Find("Image").gameObject.SetActive(false);
            }
            if (isTarget(up))    //如果从目标点推出来
            {
                bg.transform.Find("Image").gameObject.SetActive(true);
                bg.transform.Find("Image").GetComponent<Image>().sprite = Resources.Load("MoveStoneGame_target", typeof(Sprite)) as Sprite;
            }
            isSucceed();
            return;
        }
        _player.transform.position = GetBox(up).transform.position;
        playerstr = up;
    }
    /// <summary>
    /// 把每个格子的状态加入 二维数组
    /// </summary>
    public void RandRomBase(int index)
    {
        // gameObjectsArray
        Array.Clear(gameObjectsArray, 0, gameObjectsArray.Length);
        gameObjectsArray = new Item[8, 5];
        int row = gameObjectsArray.GetLength(0);      //行数
        int col = gameObjectsArray.GetLength(1);       //列数
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                string str = i + "" + j;
                ItemState gooseState = FindItemState(str, index);
                Item gooseiItem = new Item();
                gooseiItem.ItemState = gooseState;
                gooseiItem.posX = i;
                gooseiItem.posY = j;
                gameObjectsArray[i, j] = gooseiItem;
            }
        }
    }
    /// <summary>
    /// 找寻是否是障碍物还是箱子
    /// </summary>
    private ItemState FindItemState(string str, int index = 1)
    {
        List<string> _blocklist;
        MoveBoxLevelInfo.blockDic.TryGetValue(index, out _blocklist);    //从字典读取
        blocklist = new List<string>(_blocklist);
        string block = blocklist.Find(t => t == str);
        if (block != null)
        {
            return ItemState.block;
        }
        else
        {
            List<string> _nonelist;
            MoveBoxLevelInfo.NoneDic.TryGetValue(index, out _nonelist);
            nonelist = new List<string>(_nonelist);
            string none = nonelist.Find(t => t == str);
            if (none != null)
                return ItemState.none;
            else
            {
                List<string> _boxlist;
                MoveBoxLevelInfo.boxDic.TryGetValue(index, out _boxlist);
                boxList = new List<string>(_boxlist);
                string box = boxList.Find(t => t == str);
                if (box != null)
                    return ItemState.box;
                else
                {
                    List<string> _targetlist;
                    MoveBoxLevelInfo.targetDic.TryGetValue(index, out _targetlist);
                    targetList = new List<string>(_targetlist);
                    string target = targetList.Find(t => t == str);
                    if (target != null)
                    {
                        return ItemState.target;
                    }
                    else
                    {
                        if (MoveBoxLevelInfo.playerList[index - 1] == str)
                        {
                            playerstr = MoveBoxLevelInfo.playerList[index - 1];
                            return ItemState.player;
                        }
                    }
                }
            }

        }
        return ItemState.ground;
    }
    /// <summary>
    /// 初始化界面
    /// </summary>
    private void Init(int index = 1)
    {
        RandRomBase(index);

        for (int k = 0; k < _grid.transform.childCount; k++)
            GameObject.Destroy(_grid.transform.GetChild(k).gameObject);
        int row = gameObjectsArray.GetLength(0);      //行数
        int col = gameObjectsArray.GetLength(1);       //列数
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                GameObject go = UnityEngine.Object.Instantiate(_item, _grid.transform);
                go.SetActive(true);
                Item _GooseiItem = gameObjectsArray[i, j];
                go.name = i + "" + j;
                go.transform.localPosition = new Vector3(64 + 100 * i, -64 - 100 * j, 0);
                if (_GooseiItem.ItemState == ItemState.block)   //是障碍物的话
                    go.transform.Find("Image").GetComponent<Image>().sprite = Resources.Load("MoveStoneGame_block", typeof(Sprite)) as Sprite;
                else if (_GooseiItem.ItemState == ItemState.box)
                    go.transform.Find("Image").GetComponent<Image>().sprite = Resources.Load("MoveStoneGame_box", typeof(Sprite)) as Sprite;
                else if (_GooseiItem.ItemState == ItemState.target)
                    go.transform.Find("Image").GetComponent<Image>().sprite = Resources.Load("MoveStoneGame_target", typeof(Sprite)) as Sprite;
                else if (_GooseiItem.ItemState == ItemState.none)
                    go.SetActive(false);
                else if (_GooseiItem.ItemState == ItemState.player)
                {
                    go.transform.Find("Image").gameObject.SetActive(false);
                    _player.transform.position = go.transform.position;
                }
                else
                    go.transform.Find("Image").gameObject.SetActive(false);

            }
        }
    }
    /// <summary>
    /// 判断是不是墙
    /// </summary>
    /// <returns></returns>
    bool isWall(string upPos)
    {
        string block = blocklist.Find(t => t == upPos);
        if (block != null)
        {
            return true;
        }
        return false;
    }
    /// <summary>
    /// 判断是不是盒子
    /// </summary>
    /// <returns></returns>
    bool isBox(string pos)
    {
        string box = boxList.Find(t => t == pos);
        if (box != null)
        {
            return true;
        }
        return false;
    }
    /// <summary>
    /// 判断是否达到目标点
    /// </summary>
    /// <param name="pos"></param>
    /// <returns></returns>
    bool isTarget(string pos)
    {
        string target = targetList.Find(t => t == pos);
        if (target != null)
        {
            return true;
        }
        return false;
    }
    /// <summary>
    /// 判断是否成功
    /// </summary>
    void isSucceed()
    {
        if (boxList.All(targetList.Contains) && boxList.Count == targetList.Count)
        {
            Debug.Log("已经成功");
            levelCount++;
            Debug.Log("levelCount  " + levelCount);
            if (levelCount == 4)
            {
                refreshbt.enabled = false;
                succeedPanel.SetActive(true);
                for (int i = 0; i < btnlist.transform.childCount; i++)
                    btnlist.transform.GetChild(i).GetComponent<Button>().enabled = false;
                return;
            }
            RePlay();
            Init(levelCount);
        }
    }
    //  重新玩
    private void RePlay()
    {
        blocklist = null;
        boxList = null;
        targetList = null;
        nonelist = null;
        playerstr = string.Empty;
    }
    /// <summary>
    /// 通过坐标找到盒子
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    GameObject GetBox(string str)
    {
        GameObject gameObject = null;
        for (int i = 0; i < _grid.transform.childCount; i++)
        {
            Transform child = _grid.transform.GetChild(i);
            if (child.name == str)
            {
                gameObject = child.gameObject;
            }
        }
        return gameObject;
    }
}

还有一个脚本是关卡配置数据如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 关卡配置信息
/// </summary>
namespace Move
{
    public class MoveBoxLevelInfo
    {
        //第一关的障碍物的坐标
        public static List<string> blockLevelInfo1 = new List<string> { "00", "01", "02", "03", "04", "10", "14", "20", "24", "30", "34", "40", "44", "50", "54", "60", "70", "71", "72", "73", "64", "74" };

        public static List<string> NoneLevelInfo1 = new List<string> { };

        public static List<string> blockLevelInfo2 = new List<string> { "00", "01", "02", "03", "10", "13", "20", "23", "30", "33", "34", "40", "44", "50", "54", "60", "70", "71", "72", "73", "64", "74" };


        public static List<string> NoneLevelInfo2 = new List<string> { "04", "14", "24" };

        public static List<string> blockLevelInfo3 = new List<string> { "00", "01", "02", "03", "04", "10", "14", "20", "24", "30", "34", "40", "44", "50", "53", "54", "60", "70", "71", "72", "73", "63" };

        public static List<string> NoneLevelInfo3 = new List<string> { "64", "74" };

        public static List<string> boxList1 = new List<string> { "22" };

        public static List<string> targetList1 = new List<string> { "52" };

        public static List<string> boxList2 = new List<string> { "22", "42" };

        public static List<string> targetList2 = new List<string> { "32", "43" };

        public static List<string> boxList3 = new List<string> { "22", "23", "52" };

        public static List<string> targetList3 = new List<string> { "21", "33", "62" };

        //  玩家的坐标点
        public static List<string> playerList = new List<string> { "13", "12", "13" };


        // 关卡的障碍物坐标
        public static Dictionary<int, List<string>> blockDic = new Dictionary<int, List<string>>
        {
            [1] = blockLevelInfo1,
            [2] = blockLevelInfo2,
            [3] = blockLevelInfo3
        };
        //  无
        public static Dictionary<int, List<string>> NoneDic = new Dictionary<int, List<string>>
        {
            [1] = NoneLevelInfo1,
            [2] = NoneLevelInfo2,
            [3] = NoneLevelInfo3
        };
        //箱子
        public static Dictionary<int, List<string>> boxDic = new Dictionary<int, List<string>>
        {
            [1] = boxList1,
            [2] = boxList2,
            [3] = boxList3
        };
        // 目标点
        public static Dictionary<int, List<string>> targetDic = new Dictionary<int, List<string>>
        {
            [1] = targetList1,
            [2] = targetList2,
            [3] = targetList3
        };
    }
}

本文地址:https://blog.csdn.net/weixin_43329960/article/details/107321882

《Unity做2d推箱子.doc》

下载本文的Word格式文档,以方便收藏与打印。