完整实现地宫地图

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gohuge/article/details/80272848

地宫说明

我们看到的游戏地宫有如暗黑的地下城风格,泰瑞利亚的地道风格,苍之纪元和冒险岛的走格子风格。
东方故事的深渊探险风格,这里了结合苍之纪元+深渊探险实现一套地宫副本的基础结构;
与其走格子不同的是,地宫是触屏点击行走,当然ARPG的寻路实现走格子便不屑一谈了。

我们简单的拆解一下地宫的基础程序结构,大概有:
1、地图编辑器:可自动随机生成地宫,可编辑地表和景观,可编辑事件对象,可设置地图呈现效果;
2、地宫场景:第三人称单位控制,视角控制,网格寻路实现,物件碰撞和交互处理;
3、地宫事件(持续开发):事件呈现和触发(碰撞或近位点击触发),事件编辑和放置。

地图制作

地图声明为三层 即地表层,景观 层,和事件层,分三层在于,后续地表的起伏表现,景观层编辑优化,运行中事件管理,等... ...
我们可以通过地牢算法,生成地牢随机网格,在通过网格路径优化,优化至项目中可行的地图网格布局;
不过只有算法是不行的,利用算法生成的二维坐标网格,我们可以在网格中布局地表样式(可以随机或选择性布局 ,景观雷同)。
完成生成后,策划可以通过编辑器改善地图,和添加事件,下面为编辑器的部分思路代码:
//*****************************************************************************
//Created By [email protected] on 2018/5/8.
//
//@Description 地图制作工具
//*****************************************************************************
using UnityEngine;
using UnityEditor;
using Boo.Lang;
namespace Assets.Game.Editor.Scene
{
    public class TravelMapTools : EditorWindow
    {
        // 地表,景观,事件 资源
        public static TravelMapRes surfaceRes, barrierRes, eventsRes;

        [MenuItem("Tools/地宫地图", false, 111)]
        static void window()
        {
            TravelMapTools win = (TravelMapTools)EditorWindow.GetWindow(typeof(TravelMapTools), false, "TravelMap", false);
            surfaceRes = new TravelMapRes("Assets/GameRes/Model/Map/TravelSurface/",".FBX");
            barrierRes = new TravelMapRes("Assets/GameRes/Model/Map/TravelBarrier/",".FBX");
            eventsRes = new TravelMapRes("Assets/GameRes/Model/Map/TravelEvents/",".prefab");

            win.Show();
        }

        private int row = 32, col = 32;
        // 景观几率
        private int scape = 10;
        private bool Wall;
        // 对象集合
        private bool[,] mapArray;
        // 生成次数
        private int times;
        // 地表,高空,事件
        private GameObject map;
        private GameObject surface, barrier, events;
        private GameObject block;
        private BoxCollider bc;
        private Vector2 sp1, sp2, sp3;

        void OnGUI()
        {
            int x = 10;
            GUI.Label(new Rect(x, 30, 150, 220), "输入地图名称");
            GUI.TextField(new Rect(x, 60, 150, 20), "MapName");

            // 选择地表资源
            GUI.Label(new Rect(x, 100, 150, 220), "选择地表资源");
            sp1 = GUI.BeginScrollView(new Rect(x, 130, 150, 200), sp1, new Rect(0, 0, 150, 400));
            for (int i = 0; i < surfaceRes.resNames.Count; i++)
            {
                surfaceRes.selected[i] = GUI.Toggle(new Rect(5, i * 25, 150, 20), surfaceRes.selected[i], surfaceRes.resNames[i]);
            }
            GUI.EndScrollView();

            // 选择高空资源
            GUI.Label(new Rect(x + 180, 100, 150, 220), "选择高空资源");
            sp2 = GUI.BeginScrollView(new Rect(x + 180, 130, 150, 200), sp2, new Rect(0, 0, 150, 400));
            for (int i = 0; i < barrierRes.resNames.Count; i++)
            {
                barrierRes.selected[i] = GUI.Toggle(new Rect(5, i * 25, 150, 20), barrierRes.selected[i], barrierRes.resNames[i]);
            }
            GUI.EndScrollView();

            // 生成地图
            if (GUI.Button(new Rect(x, 350, 130, 25), "生成地图"))
            {
                Creat();
            }
            // 优化地图
            if (GUI.Button(new Rect(x, 390, 130, 25), "优化地图"))
            {
                Next();
            }

            // 添加物件
            GUI.Label(new Rect(x + 20, 430, 200, 25), "点击添加物件");
            // 上方添加物件
            if (GUI.Button(new Rect(x + 40, 450, 50, 25), "上"))
            {
                CopyBlock(0);
            }
            // 左方添加物件
            if (GUI.Button(new Rect(x + 10, 480, 50, 25), "左"))
            {
                CopyBlock(2);
            }
            // 右方添加物件
            if (GUI.Button(new Rect(x + 70, 480, 50, 25), "右"))
            {
                CopyBlock(3);
            }

            // 选择高空资源
            if (GUI.Button(new Rect(x , 520, 130, 25), "添加事件"))
            {
                CopyBlock(-1);
            }
            sp3 = GUI.BeginScrollView(new Rect(x, 560, 150, 150), sp2, new Rect(0, 0, 150, 300));
            for (int i = 0; i < eventsRes.resNames.Count; i++)
            {
                eventsRes.selected[i] = GUI.Toggle(new Rect(5, i * 25, 150, 20), eventsRes.selected[i], eventsRes.resNames[i]);
            }
            GUI.EndScrollView();
        }

        public void Creat()
        {
            // 创建地图
            block = GameObject.Find("Block");
            bc = block.GetComponent<BoxCollider>();


            // 资源选择
            surfaceRes.ReSelected();
            barrierRes.ReSelected();

            if (map)
            {
                Undo.DestroyObjectImmediate(map);
            }
            map = NewMap();
            map.transform.localPosition = Vector3.zero;
            mapArray = InitMapArray();
            CreateMap(mapArray);
        }

        public void ResSelected(string path, List<GameObject> list, List<string> resList, bool[] selected)
        {
            list.Clear();
            for (int i = 0; i < selected.Length; i++)
            {
                if (selected[i])
                {
                    GameObject obj = AssetDatabase.LoadAssetAtPath(path + resList[i], typeof(GameObject)) as GameObject;
                    list.Add(obj);
                }

            }
        }

        public void Next()
        {
            if (times < 7)
            {
                times++;
                Undo.DestroyObjectImmediate(map);
                map = NewMap();
                mapArray = SmoothMapArray(mapArray);
                CreateMap(mapArray);
            }
        }

        GameObject NewMap()
        {
            GameObject obj = new GameObject("mapName");
            obj.AddComponent<BlockMap>();
            obj.AddComponent<Terrain>();
            obj.AddComponent<TerrainCollider>();

            BlockMap bm = obj.GetComponent<BlockMap>();
            bm.row = row;
            bm.col = col;

            surface = new GameObject("surface");
            surface.transform.SetParent(obj.transform);
            barrier = new GameObject("barrier");
            barrier.transform.SetParent(obj.transform);
            events = new GameObject("events");
            events.transform.SetParent(obj.transform);
            return obj;
        }

        // 随机地块
        GameObject RandomBlock(GameObject layer, List<GameObject> list, int x, int lay, int z)
        {
            string name = GetBlockName(x, lay, z);
            GameObject blockobj = GameObject.Find(name);
            // 预防重复添加
            if (blockobj != null) return blockobj;

            blockobj = Instantiate(block,
                new Vector3(x * bc.size.x, (lay == 1 ? 0 : (lay - 1) * bc.size.y), z * bc.size.z),
                Quaternion.identity, layer.transform) as GameObject;

            blockobj.name = name;
            Block b = blockobj.GetComponent<Block>();
            b.rowIndex = x;
            b.colIndex = z;
            b.layerIndex = lay;
            int index = Random.Range(0, list.Count);
            GameObject res = Instantiate(list[index], blockobj.transform);
            res.transform.localPosition = Vector3.zero;
            return blockobj;
        }

        public void CopyBlock(int way)
        {
            GameObject obj = (GameObject)Selection.activeObject;
            if (!obj.transform.parent.gameObject.name.StartsWith("Block"))
                return;
            obj = obj.transform.parent.gameObject;
            Block b = obj.GetComponent<Block>();
            switch (way)
            {
                case 0: //上
                    RandomBlock(barrier, barrierRes.objs, b.rowIndex, b.layerIndex + 1, b.colIndex);
                    break;
                case 2: //左
                    RandomBlock(surface, surfaceRes.objs, b.rowIndex - 1, b.layerIndex, b.colIndex);
                    break;
                case 3: //右
                    RandomBlock(surface, surfaceRes.objs, b.rowIndex + 1, b.layerIndex, b.colIndex);
                    break;
                case -1: //事件格子
                    eventsRes.ReSelected();
                    RandomBlock(events, eventsRes.objs, b.rowIndex, b.layerIndex + 1, b.colIndex);
                    break;
            }
        }

        string GetBlockName(int x, int y, int z)
        {
            return  "Block_" + x + "_" + y + "_" + z;
        }

        bool[,] InitMapArray()
        {
            bool[,] array = new bool[row, col];
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    array[i, j] = Random.Range(0, 100) < 60;
                    if (i == 0 || i == row - 1 || j == 0 || j == col - 1)
                    {
                        array[i, j] = false;
                    }
                }
            }
            return array;
        }

        bool[,] SmoothMapArray(bool[,] array)
        {
            bool[,] newArray = new bool[row, col];
            int count1, count2;

            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    count1 = CheckNeighborWalls(array, i, j, 1);
                    count2 = CheckNeighborWalls(array, i, j, 2);

                    if (count1 >= 5 || count2 <= 2)
                    {
                        newArray[i, j] = false;
                    }
                    else
                    {
                        newArray[i, j] = true;
                    }

                    if (i == 0 || i == row - 1 || j == 0 || j == col - 1)
                    {
                        newArray[i, j] = false;
                    }
                }
            }
            return newArray;
        }

        int CheckNeighborWalls(bool[,] array, int i, int j, int t)
        {
            int count = 0;
            for (int i2 = i - t; i2 < i + t + 1; i2++)
            {
                for (int j2 = j - t; j2 < j + t + 1; j2++)
                {
                    if (i2 > 0 && i2 < row && j2 >= 0 && j2 < col)
                    {
                        if (!array[i2, j2])
                        {
                            count++;
                        }
                    }
                }
            }
            if (!array[i, j])
                count--;
            return count;
        }

        void CreateMap(bool[,] array)
        {
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    if (Wall)
                    {
                        if (!array[i, j])
                        {
                            GameObject go = RandomBlock(surface, surfaceRes.objs, i, 1, j);
                        }
                        else
                        {
                            GameObject go = RandomBlock(barrier, barrierRes.objs, i, 2, j);
                        }
                    }
                    else
                    {
                        if (array[i, j])
                        {
                            GameObject go = RandomBlock(surface, surfaceRes.objs, i, 1, j);

                            if (Random.Range(1, 100) < scape)
                            {
                                go = RandomBlock(barrier, barrierRes.objs, i, 2, j);
                            }
                        }
                    }
                }
            }
        }

    }

}
//*****************************************************************************
//Created By [email protected] on 2018/5/8.
//
//@Description 地图制作工具
//*****************************************************************************
using Boo.Lang;
using System.IO;
using UnityEngine;
using UnityEditor;

namespace Assets.Game.Editor.Scene
{
    // 资源管理类
    public class TravelMapRes
    {
        // 资源路径
        public string path;
        // 资源名称
        public List<string> resNames = new List<string>();
        // 选中位置
        public bool[] selected;
        // 选中资源
        public List<GameObject> objs = new List<GameObject>();
        // 许可资源类型
        public string resPrex = null;

        public TravelMapRes(string p)
        {
            this.path = p;
            InitResList(this.path);
        }

        public TravelMapRes(string p,string prex)
        {
            this.path = p;
            resPrex = prex;
            InitResList(this.path);
        }

        public void InitResList(string path)
        {
            resNames.Clear();
            if (Directory.Exists(path))
            {
                DirectoryInfo direction = new DirectoryInfo(path);
                FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
                for (int i = 0; i < files.Length; i++)
                {
                    if (files[i].Name.EndsWith(".meta")) continue;
                    if (resPrex != null && !files[i].Name.EndsWith(resPrex))
                    {
                        continue;
                    }
                    resNames.Add(files[i].Name);
                }
                this.selected = new bool[resNames.Count];
            }
            else {
                this.selected = new bool[0];
            }
        }

        public void ReSelected()
        {
            objs.Clear();
            for (int i = 0; i < selected.Length; i++)
            {
                if (selected[i])
                {
                    GameObject obj = AssetDatabase.LoadAssetAtPath(path + resNames[i], typeof(GameObject)) as GameObject;
                    objs.Add(obj);
                }

            }
        }

        public GameObject RandomSelectedObj()
        {
            ReSelected();
            return objs[Random.Range(0, objs.Count)];
        }
    }
}
角色控制

地图中角色控制和相机差不多和ARPG一样了,视角可上下,左右移动,相机跟随角色和调整视角。
//*****************************************************************************
//Created By Gouhj on 2018/5/3.
//
//@Description 移动控制器
//*****************************************************************************
using UnityEngine;
using UnityEngine.AI;

public class PlayerMove : MonoBehaviour
{
    
    [Header("是否点击移动")]
    public bool isClickMove = false;
    [Header("是否采用网格导航")]
    public bool IsNavAgent;
    [Header("移动速度")]
    public float m_speed = 5f;
    [Header("跑动动作")]
    public string RUN = "is_run";
    [Header("待机动作")]
    public string IDLE = "is_idle";

    float ogrY = 0;
    // 动作 0 待机,1 跑动
    int currentState = 0;

    // 寻路者  
    NavMeshAgent agent;
    // 玩家
    GameObject player;
    // 目标位置 
    Vector3 targetPos;

    void Start()
    {
        agent = this.GetComponent<NavMeshAgent>();
        targetPos = this.transform.position;
        ogrY = targetPos.y;
    }

    void LateUpdate()
    {
        if (isClickMove)
        {
            MoveControlByMouse();
        }
        else
        {
            MoveControlByTranslate();
        }
    }

    //Translate移动控制函数
    void MoveControlByTranslate()
    {
        if (Input.GetKey(KeyCode.W) | Input.GetKey(KeyCode.UpArrow)) //前
        {
            this.transform.Translate(Vector3.forward * m_speed * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.S) | Input.GetKey(KeyCode.DownArrow)) //后
        {
            this.transform.Translate(Vector3.forward * -m_speed * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.A) | Input.GetKey(KeyCode.LeftArrow)) //左
        {
            this.transform.Translate(Vector3.right * -m_speed * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.D) | Input.GetKey(KeyCode.RightArrow)) //右
        {
            this.transform.Translate(Vector3.right * m_speed * Time.deltaTime);
        }
    }

    // 鼠标点击移动
    void MoveControlByMouse()
    {
        if (Input.GetMouseButton(0))
        {
            //获得鼠标屏幕位置  
            Vector3 mousePos = Input.mousePosition;
            //将屏幕位置转为射线  
            Ray ray = Camera.main.ScreenPointToRay(mousePos);
            //用来记录射线碰撞记录  
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                // 点中地板砖
                //if (!hit.collider.name.Equals("Terrain"))
                //{
                //    return;
                //}
                targetPos = new Vector3(hit.point.x, ogrY, hit.point.z);
                if (!player) {
                    player = this.transform.GetChild(0).gameObject;
                }
                // 差值 
                transform.rotation = Quaternion.LookRotation(targetPos - transform.position);
                if (IsNavAgent)
                {
                    agent.SetDestination(targetPos);
                }
                
            }
        }
        if (IsNavAgent)
        {
            if (agent.remainingDistance == 0)
            {
                AnimatorChange(0);
            }
            else
            {
                AnimatorChange(1);
            }
        }
        else {
            if (Mathf.Abs(transform.position.x - targetPos.x) > 0.1 || Mathf.Abs(transform.position.z - targetPos.z) > 0.1)
            {
                AnimatorChange(1);
                transform.position = Vector3.MoveTowards(transform.position, targetPos, m_speed * Time.deltaTime);
            }
            else
            {
                AnimatorChange(0);
            }
        }

    }

    // 动作切换
    void AnimatorChange(int state)
    {
        if (!player) return;
        if (currentState == state) return;
        currentState = state;
        switch (state)
        {
            case 0:
                Animator ani = player.GetComponent<Animator>();
                ani.SetTrigger(IDLE);
                break;
            case 1:
                ani = player.GetComponent<Animator>();
                ani.SetTrigger(RUN);
                break;
            default:
                break;
        }
    }
}
//*****************************************************************************
//Created By [email protected] on 2018/5/3.
//
//@Description 第三人称相机
//*****************************************************************************
using UnityEngine;

namespace Game
{

    public class PlayerCamera : MonoBehaviour
    {

        private Transform player;
        private Vector3 offsetPosition;
        private float distance;
        private float scrollSpeed = 10; //鼠标滚轮速度
        private bool isRotating; //开启摄像机旋转
        private float rotateSpeed = 2; //摄像机旋转速度

        // Use this for initialization
        void Start()
        {
            player = GameObject.Find("player").transform;
            //摄像机朝向player
            transform.LookAt(player.position);
            transform.SetParent(transform);
            //获取摄像机与player的位置偏移
            offsetPosition = transform.position - player.position;
        }

        // Update is called once per frame
        void Update()
        {
            //摄像机跟随player与player保持相对位置偏移 
            transform.position = offsetPosition + player.position;
            //摄像机的旋转
            RotateView();
            //摄像机的摄影控制
            ScrollView();
        }

        void ScrollView()
        {
            //返回位置偏移的向量长度
            distance = offsetPosition.magnitude;
            distance -= Input.GetAxis("Mouse ScrollWheel") * scrollSpeed;

            //限制变化长度的范围在最小为4最大为22之间
            distance = Mathf.Clamp(distance, 4, 22);

            //新的偏移值为偏移值的单位向量*变换长度
            offsetPosition = offsetPosition.normalized * distance;
        }

        void RotateView()
        {
            //按下鼠标右键开启旋转摄像机
            if (Input.GetMouseButtonDown(1))
            {
                isRotating = true;
            }

            //抬起鼠标右键关闭旋转摄像机
            if (Input.GetMouseButtonUp(1))
            {
                isRotating = false;
            }

            if (isRotating)
            {

                //获取摄像机初始位置
                Vector3 pos = transform.position;
                //获取摄像机初始角度
                Quaternion rot = transform.rotation;

                //摄像机围绕player的位置延player的Y轴旋转,旋转的速度为鼠标水平滑动的速度
                transform.RotateAround(player.position, player.up, Input.GetAxis("Mouse X") * rotateSpeed);

                //摄像机围绕player的位置延自身的X轴旋转,旋转的速度为鼠标垂直滑动的速度
                transform.RotateAround(player.position, transform.right, Input.GetAxis("Mouse Y") * rotateSpeed);

                //获取摄像机x轴向的欧拉角
                float x = transform.eulerAngles.x;

                //如果摄像机的x轴旋转角度超出范围,恢复初始位置和角度
                if (x < 10 || x > 80)
                {
                    transform.position = pos;
                    transform.rotation = rot;
                }
            }

            //更新摄像机与player的位置偏移
            offsetPosition = transform.position - player.position;
        }
    }
}
事件相关

地图生成显然都是用地块填充的,所以为了控制地块,添加地块事件,以及设置地块属性等因素,一定会给地块绑定一个脚本。

而事件的触发,可通过配置决定是碰撞还是点击触发,在把消息派发到事件系统就好了。

关于事件的触发,可和这篇文章关联起来:寻路

地图起伏效果实现

//*****************************************************************************
//Created buy Gouhj on 2018/5/7.
//
//@Description 地块特效
//*****************************************************************************
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BlockMap : MonoBehaviour {


    [Header("地块是否起落")]
    public bool isDownUp = false;

    [Header("是否遮罩探索")]
    public bool isUnknow = false;

    [Header("设置玩家")]
    public GameObject player;

    [Header("上升位置起点")]
    public int downPosY = 10;

    [Header("上升速度")]
    public float upSpeed = 0.5f;

    // 地表,高空,事件
    GameObject surface, barrier, events;
   
    Transform tr;

    // 地表二维坐标系
    GameObject[,] blocks;

    // 函数和咧数
    public int row, col;

    // 地块大小;
    public float bsizeX = 2, bsizeZ = 2;

    private int startRow, startCol;
    // 附近的格子
    List<GameObject> nearList = new List<GameObject>();
    // 上升列表
    List<GameObject> upList = new List<GameObject>();
    // 地表默认平面在世界坐标中的高度
    int defaultSurfaceY = 0;
    // 默认圈数
    int defaultRoundCount = 2;

    // Use this for initialization
    void Start () {
        if (player != null)
        {
            tr = player.transform;
        }
        else
        {
            tr = GameObject.Find("player").transform;
        }
        surface = GameObject.Find("surface");
        barrier = GameObject.Find("barrier");
        events = GameObject.Find("events");
        blocks = new GameObject[row,col];

        GameObject obj;
        Block block;
        for (int i = 0; i < surface.transform.childCount; i++)
        {
            obj = surface.transform.GetChild(i).gameObject;
            block = obj.GetComponent<Block>();
            blocks[block.rowIndex, block.colIndex] = obj;
            if (block.isStartPoint)
            {
                startRow = block.rowIndex;
                startCol = block.colIndex;
            }
            if (isDownUp) {
                obj.SetActive(false);
            }
        }
	}
	
	// Update is called once per frame
	void Update () {
        UpAndDown();
    }

    // 显示周围
    void show(int r,int c)
    {
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                if (blocks[i, j] == null) continue;
            }
        }
    }

    // 判断是否是周围的格子
    bool IsNear(int r,int c,GameObject obj)
    {
        Block b = obj.GetComponent<Block>();
        //if(b.rowIndex-r)
        return true;
    }

    // 上下起伏效果实现
    void UpAndDown()
    {
        if (isDownUp) {
            ShowNear();
            UpListRun();
        }
       
    }

    void UpListRun() {
        if (upList.Count == 0) return;
        GameObject obj = null;
        for (int i = upList.Count - 1 ; i >= 0 ;i --) {
            obj = upList[i];
            // 地表默认平面
            if (obj.transform.position.y >= defaultSurfaceY) {
                upList.RemoveAt(i);
                obj.transform.position = new Vector3(obj.transform.position.x, 
                    defaultSurfaceY, obj.transform.position.z);
                continue;
            }
            obj.transform.position = new Vector3(obj.transform.position.x,
                    obj.transform.position.y + upSpeed, obj.transform.position.z);
        }
    }

    void ShowNear() {
        if (tr == null) return;

        SelectNear(nearList);
        GameObject obj = null;
        for (int i = 0; i < nearList.Count; i++) {
            obj = nearList[i];
            if (! obj.activeSelf) {
                // 下降到起伏位置
                obj.transform.position = new Vector3(obj.transform.position.x,
                    obj.transform.position.y - downPosY ,obj.transform.position.z);

                obj.SetActive(true);
                upList.Add(obj);
            }
        }
    }

    void SelectNear(List<GameObject> list) {
        list.Clear();
        float x = tr.position.x;
        float y = tr.position.y;
        float z = tr.position.z;
        int r = Mathf.CeilToInt(x/bsizeX);
        int c = Mathf.CeilToInt(z/bsizeZ);
        // 玩家位置
        list.Add(blocks[r, c]);
        SelectRound(list,r,c, defaultRoundCount);
    }

    void SelectRound(List<GameObject> list,int r,int c,int round) {
        for (int i = 1; i < round+1; i++) {
            //上,下,左,右
            CheckIn(list, r, c + i);
            CheckIn(list, r, c - i);
            CheckIn(list, r - i, c);
            CheckIn(list, r + i, c);
            //左上,左下,右上,右下
            CheckIn(list, r - i, c + i);
            CheckIn(list, r - i, c - i);
            CheckIn(list, r + i, c + i);
            CheckIn(list, r + i, c - i);
        }
    }

    bool CheckIn(List<GameObject> list,int r,int c) {
        if (r < 0) return false;
        if (r >= row) return false;
        if (c < 0) return false;
        if (c >= col) return false;
        GameObject obj = blocks[r, c];
        if (obj == null) return false;
        list.Add(obj);
        return true;
    }

}

猜你喜欢

转载自blog.csdn.net/gohuge/article/details/80272848