unity复刻重装机兵(三)地图的切换和队列简单跟随

场景布局:

基础精灵拆分代码:

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

public class CardSprites : MonoBehaviour
{
    [HideInInspector]
    public Sprite[] sprites;
    Texture2D texture2D;
    string alphabet = "0123456789abcdefghijklmnopqrstuvwxyz";
    //string alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    public void GetMapSprite(string path)
    {
        texture2D = Resources.Load<Texture2D>(path);

        int index = -1;
        int row = texture2D.height / 32;
        int col = texture2D.width / 32;

        sprites = new Sprite[row * col];

        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                index++;
                Sprite sp = Sprite.Create(texture2D, new Rect(j * 32, (row - 1 - i) * 32, 32, 32), new Vector2(0.5f, 0.5f));
                sprites[index] = sp;
                int dex = index / col;
                string str = alphabet[dex].ToString();
                str = str + "" + (index % col).ToString();
                sprites[index].name = str;
            }
        }
    }

}

镇子的加载:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;

public class TownMap : MonoBehaviour
{

    public Transform maps;
    //[HideInInspector]
    public Sprite[] spritesmap;
    [HideInInspector]
    public string[,] mapdataRoad;
    string[,] mapUpdate;

    public TextAsset textAssets;

    public string imgPath;
    public int row = 0;
    public int col = 0;

    //设置字典,保存每个卡片的精灵和ID,而每个ID对应唯一卡片坐标
    public Dictionary<int, Sprite> dSprite = new Dictionary<int, Sprite>();


    void Start()
    {
        for (int i = 0; i < 272; i++)
        {
            GameObject item = new GameObject("card");
            item.AddComponent<SpriteRenderer>();
            item.GetComponent<SpriteRenderer>().drawMode = SpriteDrawMode.Sliced;
            item.transform.GetComponent<SpriteRenderer>().size = new Vector2(1, 1);
            item.transform.SetParent(maps);
            item.SetActive(false);
        }

    }

    public void ChangeMap(int posX, int posY)
    {

        StartCoroutine(WaitMap(posX, posY));
    }

    IEnumerator WaitMap(int posX, int posY)
    {

        GetComponent<CardSprites>().GetMapSprite(imgPath);
        yield return new WaitUntil(() => GetComponent<CardSprites>().sprites != null);
        string str = textAssets.ToString();
        InitMapData(str, row, col);

        yield return new WaitUntil(() => dSprite != null);

        LoadMapData(posX, posY);
    }


    public void InitMapData(string mapData, int mapRow, int mappCol)
    {
        dSprite.Clear();

        string strAll = mapData;
        row = mapRow;
        col = mappCol;
        spritesmap = transform.GetComponent<CardSprites>().sprites;

        string result = strAll.ToString().Replace("\n", "");
        string str2 = Regex.Replace(result, @"\s", "");
        //拆分地图数据给二维数组
        string[] parts = str2.Split(',');
        string[,] mapArray = new string[col, row];
        mapdataRoad = new string[col, row];//其他脚本引用使用

        for (int i = 0; i < col; i++)
        {
            for (int j = 0; j < row; j++)
            {
                mapArray[i, j] = parts[i + (col * j)];

            }
        }
        mapUpdate = mapArray;

        string[,] map = mapUpdate;

        int cardCount = -1;

        for (int y = 0; y < row; y++)
        {
            for (int x = 0; x < col; x++)
            {
                cardCount++;
                string tileType = map[x, y];

                //给精灵图片赋值
                foreach (Sprite s in spritesmap)
                {
                    if (s.name == tileType)
                    {
                        dSprite.Add(cardCount, s);
                        break;
                    }
                }
                mapdataRoad[x, y] = tileType;
            }
        }

    }

    public void LoadMapData(int _x, int _y)
    {

        int childID = -1;
        for (int x = _x - 8; x <= _x + 8; x++)
        {
            for (int y = _y - 8; y < _y + 8; y++)
            {
                if (x >= 0 && x < col)
                {
                    if (y <= 0 && y > -row)
                    {
                        int SpriteID = (x + (col * -y));

                        childID++;
                        Transform card = maps.GetChild(childID);
                        card.position = new Vector2(x, y);
                        card.GetComponent<SpriteRenderer>().sprite = dSprite[SpriteID];

                        card.GetComponent<SpriteRenderer>().size = new Vector2(1, 1);
                        card.gameObject.SetActive(true);
                    }
                    else
                    {
                        childID++;
                        Transform card = maps.GetChild(childID);
                        card.position = new Vector2(x, y);
                        card.GetComponent<SpriteRenderer>().sprite = spritesmap[0];
                        card.GetComponent<SpriteRenderer>().size = new Vector2(1, 1);
                        card.gameObject.SetActive(true);
                    }
                }
                else
                {
                    childID++;
                    Transform card = maps.GetChild(childID);
                    card.position = new Vector2(x, y);
                    card.GetComponent<SpriteRenderer>().sprite = spritesmap[0];
                    card.GetComponent<SpriteRenderer>().size = new Vector2(1, 1);
                    card.gameObject.SetActive(true);
                }

            }
        }

    }

    //移动后更新卡片
    public void ShowMapSprite(int posX, int posY)
    {
        string dir = KeyBoardMove.dir;
        for (int i = 0; i < maps.transform.childCount; i++)
        {
            if (dir == "UP")
            {
                if (maps.transform.GetChild(i).position.y == posY - 9)
                {
                    Transform trans = maps.GetChild(i);
                    trans.position = new Vector2(trans.position.x, trans.position.y + 16);
                    NextBoardCard(trans);
                }

            }
            else if (dir == "DOWN")
            {
                if (maps.transform.GetChild(i).position.y == posY + 9)
                {
                    Transform trans = maps.GetChild(i);
                    trans.position = new Vector2(trans.position.x, trans.position.y - 16);
                    NextBoardCard(trans);
                }
            }
            else if (dir == "LEFT")
            {
                if (maps.GetChild(i).position.x == posX + 9)
                {
                    Transform trans = maps.transform.GetChild(i);
                    trans.position = new Vector2(trans.position.x - 17, trans.position.y);
                    NextBoardCard(trans);
                }
            }
            else if (dir == "RIGHT")
            {
                if (maps.GetChild(i).position.x == posX - 10)
                {
                    Transform trans = maps.GetChild(i);
                    trans.position = new Vector2(trans.position.x + 17, trans.position.y);
                    NextBoardCard(trans);
                }
            }
        }
    }


    void NextBoardCard(Transform trans)
    {

        int x = (int)trans.position.x;//映射这个卡片在地图数组中的X坐标
        int y = (int)trans.position.y;//映射这个卡片在地图数组中的X坐标
        int SpriteID = (x + (col * -y));

        if (x >= 0 && x < col)
        {
            if (y <= 0 && y > -row)
            {
                Transform card = trans;
                card.GetComponent<SpriteRenderer>().sprite = dSprite[SpriteID];
            }
            else
            {
                trans.GetComponent<SpriteRenderer>().sprite = spritesmap[0];
            }
        }
        else
        {
            trans.GetComponent<SpriteRenderer>().sprite = spritesmap[0];
        }

    }


}

世界地图的加载:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;

public class WordMap : MonoBehaviour
{

    public Transform maps;
    //[HideInInspector]
    public Sprite[] spritesmap;
    [HideInInspector]
    public string[,] mapdataRoad;
    string[,] mapUpdate;

    public TextAsset[] textAssets;

    public string imgPath;
    public int row = 0;
    public int col = 0;

    //设置字典,保存每个卡片的精灵和ID,而每个ID对应唯一卡片坐标
    public Dictionary<int, Sprite> dSprite = new Dictionary<int, Sprite>();
    //组装世界地图
    static List<string> mapTxts = new List<string>();

    string map_word;

    public void ChangeMap(int posX, int posY)
    {
        StartCoroutine(WaitMap(posX, posY));
    }

    IEnumerator WaitMap(int posX, int posY)
    {

        GetComponent<CardSprites>().GetMapSprite(imgPath);
        yield return new WaitUntil(() => GetComponent<CardSprites>().sprites != null);

        MakeAllStr();
        yield return new WaitUntil(() => map_word != string.Empty);
        InitMapData(map_word, row, col);
        LoadMapData(posX, posY);
    }

    private void MakeAllStr()
    {

        for (int i = 0; i < textAssets.Length; i++)
        {
            mapTxts.Add(textAssets[i].ToString());
        }

        for (int i = 0; i < mapTxts.Count; i++)
        {
            map_word += mapTxts[i];
        }

    }

    public void InitMapData(string mapData, int mapRow, int mappCol)
    {
        dSprite.Clear();

        string strAll = mapData;
        row = mapRow;
        col = mappCol;
        spritesmap = transform.GetComponent<CardSprites>().sprites;

        string result = strAll.ToString().Replace("\n", "");
        string str2 = Regex.Replace(result, @"\s", "");
        //拆分地图数据给二维数组
        string[] parts = str2.Split(',');
        string[,] mapArray = new string[col, row];
        mapdataRoad = new string[col, row];//其他脚本引用使用

        for (int i = 0; i < col; i++)
        {
            for (int j = 0; j < row; j++)
            {
                mapArray[i, j] = parts[i + (col * j)];

            }
        }
        mapUpdate = mapArray;

        string[,] map = mapUpdate;

        int cardCount = -1;

        for (int y = 0; y < row; y++)
        {
            for (int x = 0; x < col; x++)
            {
                cardCount++;
                string tileType = map[x, y];

                //给精灵图片赋值
                foreach (Sprite s in spritesmap)
                {
                    if (s.name == tileType)
                    {
                        dSprite.Add(cardCount, s);
                        break;
                    }
                }
                mapdataRoad[x, y] = tileType;
            }
        }

    }

    public void LoadMapData(int _x, int _y)
    {

        int childID = -1;
        for (int x = _x - 8; x <= _x + 8; x++)
        {
            for (int y = _y - 8; y < _y + 8; y++)
            {
                if (x >= 0 && x < col)
                {
                    if (y <= 0 && y > -row)
                    {
                        int SpriteID = (x + (col * -y));

                        childID++;
                        Transform card = maps.GetChild(childID);
                        card.position = new Vector2(x, y);
                        card.GetComponent<SpriteRenderer>().sprite = dSprite[SpriteID];


                        card.GetComponent<SpriteRenderer>().size = new Vector2(1, 1);
                        card.gameObject.SetActive(true);
                    }
                    else
                    {
                        childID++;
                        Transform card = maps.GetChild(childID);
                        card.position = new Vector2(x, y);
                        //card.GetComponent<SpriteRenderer>().sprite = spritesmap[0];
                        card.GetComponent<SpriteRenderer>().size = new Vector2(1, 1);
                        card.gameObject.SetActive(true);
                    }
                }
                else
                {
                    childID++;
                    Transform card = maps.GetChild(childID);
                    card.position = new Vector2(x, y);
                    //card.GetComponent<SpriteRenderer>().sprite = spritesmap[0];
                    card.GetComponent<SpriteRenderer>().size = new Vector2(1, 1);
                    card.gameObject.SetActive(true);
                }

            }
        }

    }

    //移动后更新卡片
    public void ShowMapSprite(int posX, int posY)
    {
        string dir = KeyBoardMove.dir;
        for (int i = 0; i < maps.transform.childCount; i++)
        {
            if (dir == "UP")
            {
                if (maps.transform.GetChild(i).position.y == posY - 9)
                {
                    Transform trans = maps.GetChild(i);
                    trans.position = new Vector2(trans.position.x, trans.position.y + 16);
                    NextBoardCard(trans);
                }

            }
            else if (dir == "DOWN")
            {
                if (maps.transform.GetChild(i).position.y == posY + 9)
                {
                    Transform trans = maps.GetChild(i);
                    trans.position = new Vector2(trans.position.x, trans.position.y - 16);
                    NextBoardCard(trans);
                }
            }
            else if (dir == "LEFT")
            {
                if (maps.GetChild(i).position.x == posX + 9)
                {
                    Transform trans = maps.transform.GetChild(i);
                    trans.position = new Vector2(trans.position.x - 17, trans.position.y);
                    NextBoardCard(trans);
                }
            }
            else if (dir == "RIGHT")
            {
                if (maps.GetChild(i).position.x == posX - 10)
                {
                    Transform trans = maps.GetChild(i);
                    trans.position = new Vector2(trans.position.x + 17, trans.position.y);
                    NextBoardCard(trans);
                }
            }
        }
    }


    void NextBoardCard(Transform trans)
    {

        int x = (int)trans.position.x;//映射这个卡片在地图数组中的X坐标
        int y = (int)trans.position.y;//映射这个卡片在地图数组中的X坐标
        int SpriteID = (x + (col * -y));

        if (x >= 0 && x < col)
        {
            if (y <= 0 && y > -row)
            {
                Transform card = trans;
                card.GetComponent<SpriteRenderer>().sprite = dSprite[SpriteID];
            }
            else
            {
                trans.GetComponent<SpriteRenderer>().sprite = spritesmap[0];
            }
        }
        else
        {
            trans.GetComponent<SpriteRenderer>().sprite = spritesmap[0];
        }

    }


}

世界地图和镇子的加载貌似是一样的为什么还要分开来,方便为后面的世界地图动态水做准备。
玩家队列布局:

Items的Y轴为什么是0.125f,因为玩家卡片不是和背景重合的,它比背景高这么多,仔细观察会发现NES里面玩家脑袋是要超出卡片0.125个单位的
玩家也使用了精灵拆分工具加载了对应图集,
PSprites代码:

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

public class PSprites : MonoBehaviour
{
    SpriteRenderer sRenderer;
    Sprite[] sprites;
    [HideInInspector]
    public float animTimer = 0;//动画帧
    public float speed = 3;//这个速度和followObj的速度必须保持一致
    public string imgPath;
    void Start()
    {
        sRenderer = GetComponent<SpriteRenderer>();
        StartCoroutine(WaitSprites());
    }
    IEnumerator WaitSprites()
    {
        GetComponent<CardSprites>().GetMapSprite(imgPath);
        yield return new WaitUntil(() => GetComponent<CardSprites>().sprites != null);
        // 加载精灵图集
        sprites = GetComponent<CardSprites>().sprites;
        sRenderer.sprite = sprites[0];
        sRenderer.size = Vector2.one;
    }

    //移动一步的动画
    public void PlayerAnim(string dir, int stage)
    {
        //stage为0,各方向第一张精灵图,非移动状态
        //stage为1,各方向第二张精灵图,移动状态

        switch (dir)
        {
            case "UP":
                sRenderer.sprite = sprites[12 + stage];
                break;
            case "LEFT":
                sRenderer.sprite = sprites[4 + stage];
                break;
            case "RIGHT":
                sRenderer.sprite = sprites[8 + stage];
                break;
            case "DOWN":
                sRenderer.sprite = sprites[0 + stage];
                break;
        }

    }
}

首位玩家的移动:

using System.Collections;
using UnityEngine;

public class Player : MonoBehaviour
{
    public string inMapName = "";//当前地图名字
    public int playerID = 1;//玩家在队列的编号,头部玩家编号是1
    public TownMap townMap;
    public WordMap wordMap;
    [HideInInspector]
    public int currentStep = 0;

    [HideInInspector]
    public int player2WSAD = -1;
    public string dir = "";//移动方向
    public bool isMoving = false;

    Vector3 myCoordinate;//探路动画坐标
    int STEP = 0;//移动步数
    string currentStr = "DOWN";//默认方向

    public int tox = 0;
    public int toy = 0;

    bool isMapChangeing = false;

    void Start()
    {
        transform.localPosition = new Vector2(tox, toy);
        myCoordinate = transform.localPosition;

        InitGame();
    }

    void InitGame()
    {
        for (int i = 0; i < transform.parent.childCount; i++)
        {
            transform.parent.GetChild(i).localPosition = new Vector2(tox, toy);
            if (i>0)
            {
                transform.parent.GetChild(i).GetComponent<FollowMe>().InitPos(tox, toy);
            }
        }
        inMapName = "laduo";
        townMap.ChangeMap(tox, toy);//动态加载地图生成玩家位置
    }

    void Update()
    {

        if (myCoordinate == transform.localPosition)
        {
            if (isMoving)
            {
                //TODO 到了目标点执行任务
                MyNextTask();
            }
            isMoving = false;
            KeyBoardMove.isMoving = false;
            dir = KeyBoardMove.dir;
            switch (dir)
            {
                case "UP":
                    tox = (int)myCoordinate.x;
                    toy = (int)myCoordinate.y + 1;
                    break;
                case "LEFT":
                    tox = (int)myCoordinate.x - 1;
                    toy = (int)myCoordinate.y;
                    break;
                case "RIGHT":
                    tox = (int)myCoordinate.x + 1;
                    toy = (int)myCoordinate.y;
                    break;
                case "DOWN":
                    tox = (int)myCoordinate.x;
                    toy = (int)myCoordinate.y - 1;
                    break;
            }

            if (currentStr != dir)
            {
                if (KeyBoardMove.keyboard < 2)
                {
                    transform.GetComponent<PSprites>().PlayerAnim(dir,0);//多个障碍可以原地转向
                    currentStr = dir;
                }
            }

            //不可移动判断
            if (KeyBoardMove.isKeyUp)
            {
                return;
            }

            //加载移动路径,其他为障碍物
            //if (NotMove())
            //{
            //    return;//注销取消障碍
            //}


            GetComponent<PSprites>().animTimer = 0;
            myCoordinate = new Vector2(tox, toy);
            STEP++;

            if (inMapName == "word")
            {
                wordMap.ShowMapSprite(tox, toy);
            }
            else
            {
                townMap.ShowMapSprite(tox, toy);
            }
        }
        else
        {
            if (isMapChangeing)
            {
                return;
            }

            isMoving = true;
            KeyBoardMove.isMoving = true;
            transform.localPosition = Vector2.MoveTowards(transform.localPosition, myCoordinate, GetComponent<PSprites>().speed * Time.deltaTime);

            //处理玩家移动动画
            if (GetComponent<PSprites>().animTimer < GetComponent<PSprites>().speed)
            {
                GetComponent<PSprites>().animTimer += GetComponent<PSprites>().speed * Time.deltaTime;

                if (GetComponent<PSprites>().animTimer < 0.5f)
                {
                    transform.GetComponent<PSprites>().PlayerAnim(dir,1);
                }
                else
                {
                    transform.GetComponent<PSprites>().PlayerAnim(dir, 0);
                }
            }
        }

    }

    private void MyNextTask()
    {
        int boardX = (int)myCoordinate.x;
        int boardY = (int)myCoordinate.y;//第四象限

        if (inMapName == "laduo")
        {
            if (boardX <= 0 || boardY >= 0 || boardX >= 25 || boardY <= -16)
            {
                //切换到世界地图
                StopAllCoroutines();
                StartCoroutine(MapChange("word", 36, -79));
            }
            else
            {
                //TODO
                //到屋子里面去

            }
        }
        else if (inMapName == "word")
        {                
            //进入村庄
            StopAllCoroutines();

            if (boardX == 36 && boardY == -79)
            {
                StartCoroutine(MapChange("laduo", 14, -15));
            }

        }
    }


    IEnumerator MapChange(string name, int x,int y)
    {
        isMapChangeing = true;
        transform.localPosition = new Vector2(x, y);
        myCoordinate = new Vector2(x, y);
        tox = x;
        toy = y;
        for (int i = 1; i < transform.parent.childCount; i++)
        {
            transform.parent.GetChild(i).GetComponent<FollowMe>().InitPos(tox, toy);
            transform.parent.GetChild(i).GetComponent<FollowMe>().isMapChangeing = true;
        }
        inMapName = name;

        if (name=="word")
        {
            wordMap.ChangeMap(x, y);//动态加载地图生成玩家位置
        }
        else
        {
            townMap.ChangeMap(x, y);//动态加载地图生成玩家位置
        }

        yield return new WaitForSeconds(1);
        isMapChangeing = false;
        for (int i = 1; i < transform.parent.childCount; i++)
        {
            transform.parent.GetChild(i).GetComponent<FollowMe>().isMapChangeing = false;
        }
    }

    //增加移动路径

    private bool NotMove()
    {

        int _toy = Mathf.Abs(toy);

        if (_toy > 254)
        {
            return true;//防止移出边界
        }

        if (tox < 0 || toy > 0)
        {
            return true;//防止移出边界
        }
        if (tox > 254 || toy < -254)
        {
            return true;//防止移出边界
        }

        if (inMapName == "word")
        {
            Debug.Log(tox + "~~~" + _toy);
            if (wordMap.mapdataRoad[tox, _toy] == "01") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "08") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "09") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "12") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "13") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "27") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "28") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "39") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "44") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "45") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "50") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "51") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "52") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "53") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "60") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "65") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "66") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "68") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "69") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "70") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "71") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "b7") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "b8") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "b9") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "c0") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "c1") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "c2") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "c3") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "c4") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "c7") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "d2") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "d5") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "e0") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "e1") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "e2") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "e3") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "e9") return false;
            if (wordMap.mapdataRoad[tox, _toy] == "f0") return false;

        }
        else
        {
            if (inMapName == "laduo")
            {

                if (tox < 26 && _toy < 17)
                {
                    if (townMap.mapdataRoad[tox, _toy] == "00") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "01") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "15") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "30") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "32") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "33") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "36") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "41") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "43") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "53") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "62") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "75") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "82") return false;
                    if (townMap.mapdataRoad[tox, _toy] == "83") return false;

                }
                else
                {
                    return true;
                }
            }
        }

        return true;
    }


}

队列跟随部分:

Tank01跟随的是Player3,Player3跟随的是Player2,Player2跟随的是Player1,
它们都在PSprites填了对应精灵图集路径ImgPath。
KeyBoardMove代码,随便一个按键方向工具:

using UnityEngine;

public class KeyBoardMove : MonoBehaviour
{
    public static string dir = "";//移动方向
    public static bool isKeyUp = true;
    public static bool isMoving = false;
    public static int keyboard = 0;

    void Update()
    {
        if (Input.GetKeyUp(KeyCode.S) || Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.D) || Input.GetKeyUp(KeyCode.W))
        {
            keyboard = 0;
            isKeyUp = true;
        }

        if (Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.S)
            || Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.A)
             || Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.D)
             || Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.A)
             || Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.D)
             || Input.GetKey(KeyCode.A) && Input.GetKey(KeyCode.D))
        {
            keyboard = 2;//同时有两个按键则返回
            isKeyUp = true;
        }

        if (!isMoving)
        {
            if (Input.GetKey(KeyCode.W))
            {
                isKeyUp = false;
                dir = "UP";
            }
            else if (Input.GetKey(KeyCode.S))
            {
                isKeyUp = false;
                dir = "DOWN";
            }
            else if (Input.GetKey(KeyCode.A))
            {
                isKeyUp = false;
                dir = "LEFT";
            }
            else if (Input.GetKey(KeyCode.D))
            {
                isKeyUp = false;
                dir = "RIGHT";

            }

        }

        //多个方向同时按键则急停
        switch (dir)
        {
            case "UP":
                if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D) || Input.GetKeyUp(KeyCode.W))
                {
                    isKeyUp = true;
                }
                break;
            case "LEFT":
                if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.D) || Input.GetKeyUp(KeyCode.A))
                {
                    isKeyUp = true;
                }
                break;
            case "RIGHT":
                if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.W) || Input.GetKeyUp(KeyCode.D))
                {
                    isKeyUp = true;
                }
                break;
            case "DOWN":
                if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D) || Input.GetKeyUp(KeyCode.S))
                {
                    isKeyUp = true;
                }
                break;
        }

    }
}

人物跟随代码:

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

public class FollowMe : MonoBehaviour
{

    public Transform followObj;//跟随目标

    Vector3 movePoint;//下一个移动点
    Vector3 prevPos;//玩家移动插值帧
    Vector3 prevSelfPos;//自身移动插值帧
    string dir = "DOWN";//默认移动方向
    string lateDir = "";//移动后朝向
    [HideInInspector]
    public bool startFollow = false;//第一次如果是重合防止移动
    [HideInInspector]
    public bool isImgLoading = false;
    [HideInInspector]
    public bool isMapChangeing = false;
    public void InitPos(int x,int y)
    {
        transform.localPosition = new Vector2(x, y);
        prevPos = new Vector2(x, y);
        movePoint = new Vector2(x, y);

        startFollow = false;
        isImgLoading = true;

    }

    private void Update()
    {
        if (isImgLoading && !isMapChangeing)
        {
            Follow();
        }

    }


    void Follow()
    {
        if (Vector3.Distance(transform.localPosition, followObj.localPosition) >= 1)
        {
            startFollow = true;
        }

        if (followObj && startFollow)
        {
            transform.localPosition = Vector3.MoveTowards(transform.localPosition, movePoint, GetComponent<PSprites>().speed * Time.deltaTime);

            float moveX = followObj.localPosition.x - prevPos.x;
            float moveY = followObj.localPosition.y - prevPos.y;

            float mX = transform.localPosition.x - prevSelfPos.x;
            float mY = transform.localPosition.y - prevSelfPos.y;
            
            if (mX > 0)
            {
                dir = "RIGHT";
            }
            if (mX < 0)
            {
                dir = "LEFT";
            }
            if (mY > 0)
            {
                dir = "UP";
            }
            if (mY < 0)
            {
                dir = "DOWN";
            }
            //跟随原理,unity玩家队列跟随
            if (Vector3.Distance(movePoint, transform.localPosition) == 0)
            {
                PlayerLateAnim(0);

                if (Vector3.Distance(transform.localPosition, followObj.localPosition) != 1)
                {
                    GetComponent<PSprites>().animTimer = 0;
                    movePoint = new Vector3(Mathf.RoundToInt(prevPos.x), Mathf.RoundToInt(prevPos.y), 0);
                }
                if (Vector3.Distance(transform.localPosition, followObj.localPosition) > 1)
                {
                    if (transform.localPosition.x == followObj.localPosition.x && moveX == 0)
                    {
                        if (transform.localPosition.y < followObj.localPosition.y)
                        {
                            transform.localPosition = new Vector3(followObj.localPosition.x, followObj.localPosition.y - 1, 0);
                        }
                        else if (transform.position.y > followObj.position.y)
                        {
                            transform.localPosition = new Vector3(followObj.localPosition.x, followObj.localPosition.y + 1, 0);
                        }
                    }
                    if (transform.localPosition.y == followObj.localPosition.y && moveY == 0)
                    {
                        if (transform.localPosition.x < followObj.localPosition.x)
                        {
                            transform.localPosition = new Vector3(followObj.localPosition.x - 1, followObj.localPosition.y, 0);
                        }
                        else if (transform.localPosition.x > followObj.localPosition.x)
                        {
                            transform.localPosition = new Vector3(followObj.localPosition.x + 1, followObj.localPosition.y, 0);
                        }
                    }
                }
                prevPos = followObj.localPosition;
                prevSelfPos = transform.localPosition;
            }
            else
            {
                //处理玩家移动动画
                if (GetComponent<PSprites>().animTimer < GetComponent<PSprites>().speed)
                {
                    GetComponent<PSprites>().animTimer += GetComponent<PSprites>().speed * Time.deltaTime;

                    if (GetComponent<PSprites>().animTimer < 0.5f)
                    {
                        transform.GetComponent<PSprites>().PlayerAnim(dir, 1);
                    }
                    else
                    {
                        transform.GetComponent<PSprites>().PlayerAnim(dir, 0);
                    }
                }
            }
        }
    }

    //移动完毕后需要朝向跟随的玩家
    public void PlayerLateAnim(int stage)
    {
        int fX = Mathf.RoundToInt(followObj.localPosition.x);
        int fY = Mathf.RoundToInt(followObj.localPosition.y);

        int selfX = Mathf.RoundToInt(transform.localPosition.x);
        int selfY = Mathf.RoundToInt(transform.localPosition.y);

        if (selfX == fX)
        {
            if (selfY < fY)
            {
                lateDir = "UP";
            }
            else if (selfY > fY)
            {
                lateDir = "DOWN";
            }
        }
        else if (selfY == fY)
        {
            if (selfX < fX)
            {
                lateDir = "RIGHT";
            }
            else if (selfX > fX)
            {
                lateDir = "LEFT";
            }
        }

        dir = lateDir;
        transform.GetComponent<PSprites>().PlayerAnim(dir, stage);

    }

}

PlayerLateAnim()方法//移动完毕后需要朝向跟随的玩家
每移动完一步之后的朝向需要更改。

地图数据:

拉多地图的二维数组:

不使用JSON数组,太长了拥挤,直接用字符串:

精灵编号查看工具图片:

精灵编号查看工具GetImgIndex代码:

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class GetImgIndex : MonoBehaviour
{

    public SpriteRenderer sr;
    public string TexName = "";

    Texture2D tex;
    int texSize = 32;//图片的一个格子分辨率,有的默认是16需要注意
    int nullRow = 0;//去掉无用行
    int nullCol = 0;//去掉无用列
    int downCount = 0;//图片底部多出来的空白区域分辨率
    int rightCound = 0;//图片右部多出来的空白区域分辨率

    //[HideInInspector]
    public Sprite[] _sprites;

    void Start()
    {
        if (TexName == "word")
        {
            nullRow = 0;
            nullCol = 0;
            downCount = 0;
            texSize = 32;
            tex = Resources.Load<Texture2D>("sprite/mm1_world_mt");
        }
        else if (TexName == "town")
        {
            nullRow = 0;
            nullCol = 0;
            downCount = 0;
            texSize = 32;
            tex = Resources.Load<Texture2D>("sprite/mm1_locate_general");
        }
        int index = -1;
        int row = tex.height / texSize - nullRow;
        int col = tex.width / texSize - nullCol;
        _sprites = new Sprite[row * col];

        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                index++;
                Sprite sp = Sprite.Create(tex, new Rect(j * texSize + rightCound, (row - 1 - i) * texSize + downCount, texSize, texSize), new Vector2(0.5f, 0.5f));
                _sprites[index] = sp;
                _sprites[index].name = index.ToString();

            }
        }

        GetImgID();
    }

    /// <summary>
    /// 获取精灵下标
    /// </summary>
    void GetImgID()
    {
        int index = -1;
        int row = tex.height / texSize - nullRow;
        int col = tex.width / texSize - nullCol;

        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                index++;
                GameObject go = Instantiate(sr.gameObject);
                go.transform.position = new Vector2(j, row - 1 - i);
                go.transform.GetComponent<SpriteRenderer>().sprite = _sprites[index];
                go.transform.GetComponent<SpriteRenderer>().size = new Vector2(1, 1);
                go.SetActive(true);
                go.transform.GetChild(0).GetComponent<TextMeshPro>().text = index.ToString();
                go.name = "card" + index;
            }
        }
    }

    /// <summary>
    /// 获取图片的一部分
    /// </summary>
    /// <param name="tex">图片</param>
    /// <param name="size">要将图片分为n*n的图块的集合,如3*3</param>
    /// <param name="id">目标图块的Id(左下角是(0,0),右上角是(n-1,n-1))</param>
    /// <returns></returns>
    //private Sprite GetSprite(Texture2D tex, Vector2Int size, Vector2Int id)
    //{
    //    var x = (float)tex.width / size.x;
    //    var y = (float)tex.height / size.y;
    //    var sprite = Sprite.Create(tex, new Rect(id.x * x, id.y * y, x, y), new Vector2(0.5f, 0.5f));
    //    return sprite;
    //}
}

下面是世界地图的编辑工具,世界地图是5*5总共25张:

世界地图编辑的场景布局:

WordCard工具代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;

public class WordCard : MonoBehaviour
{
    public Transform maps;
    [HideInInspector]
    public Sprite[] spritesmap;
    [HideInInspector]
    public string[,] mapdataRoad;
    string[,] mapUpdate;

    public string imgPath;
    public int row = 0;
    public int col = 0;

    public TextAsset[] textAssets;

    //设置字典,保存每个卡片的精灵和ID,而每个ID对应唯一卡片坐标
    public Dictionary<int, Sprite> dSprite = new Dictionary<int, Sprite>();

    //------------地图滚动---------------

    [HideInInspector]
    public float animTimer = 0;//动画帧

    //----------UI处理------------
    [HideInInspector]
    public bool UIOpen = false;

    bool isLoad = false;
    void Start()
    {
        for (int i = 0; i < row * col; i++)
        {
            GameObject item = new GameObject("card");
            item.AddComponent<SpriteRenderer>();
            item.GetComponent<SpriteRenderer>().drawMode = SpriteDrawMode.Sliced;
            item.transform.GetComponent<SpriteRenderer>().size = new Vector2(1, 1);
            item.transform.SetParent(maps);
            item.SetActive(false);
        }
        ChangeMap();
    }
    public void ChangeMap()
    {
        StartCoroutine(WaitMap());
    }

    IEnumerator WaitMap()
    {
        GetComponent<CardSprites>().GetMapSprite(imgPath);
        yield return new WaitUntil(() => GetComponent<CardSprites>().sprites != null);
        string str = textAssets[0].ToString();
        InitMapData(str, row, col);
        LoadMapData();

    }

    public void InitMapData(string mapData, int mapRow, int mappCol)
    {
        dSprite.Clear();

        string strAll = mapData;
        row = mapRow;
        col = mappCol;
        spritesmap = transform.GetComponent<CardSprites>().sprites;

        string result = strAll.ToString().Replace("\n", "");
        string str2 = Regex.Replace(result, @"\s", "");

        //拆分地图数据给二维数组
        string[] parts = str2.Split(',');

        string[,] mapArray = new string[col, row];
        mapdataRoad = new string[col, row];//其他脚本引用使用

        for (int i = 0; i < col; i++)
        {
            for (int j = 0; j < row; j++)
            {
                mapArray[i, j] = parts[i + (col * j)];
            }
        }
        mapUpdate = mapArray;

        string[,] map = mapUpdate;

        int cardCount = -1;

        for (int y = 0; y < row; y++)
        {
            for (int x = 0; x < col; x++)
            {
                cardCount++;
                string tileType = map[x, y];

                //给精灵图片赋值
                foreach (Sprite s in spritesmap)
                {
                    if (s.name == tileType)
                    {
                        dSprite.Add(cardCount, s);
                        break;
                    }
                }
                mapdataRoad[x, y] = tileType;
            }
        }

    }

    public void LoadMapData()
    {

        int childID = -1;
        for (int x = 0; x < col; x++)
        {
            for (int y = 0; y < row; y++)
            {
                int SpriteID = (x + (col * y));
                childID++;
                Transform card = maps.GetChild(childID);
                card.position = new Vector2(x, -y);
                card.GetComponent<SpriteRenderer>().sprite = dSprite[SpriteID];

                card.GetComponent<SpriteRenderer>().size = new Vector2(1, 1);
                card.gameObject.SetActive(true);
            }
        }
        isLoad = true;
    }

    private void Update()
    {
        if (isLoad)
        {
            if (Input.GetKeyDown(KeyCode.K))
            {
                ChangeMap();
            }

        }

    }

}

如果你修改了TXT地图文本,按下K建刷新一下地图,这样就不用频繁运行窗口了。
如何使用:

每个块有对应编号:

世界地图总共是255行和255列,分成五个块就是每个块51行和51列
我这里测试了加载word_01:
运行后如下:

在正式游戏窗口里面我加载了word_01和word_0两个组合体:

word_01在word_00上面,它两加起来有102行,还是只有51列。
在WordMap代码里的对应方法:
定义一个全局字符串

string map_word;

拼装两个文本:

等待字符串不为空即可加载地图了。
玩家的出生情况:

他出生在了拉多的12,-8坐标的位置
切换了地图:
在这里插入图片描述

正式的运行效果:

运行效果

玩家现在是超人,需要开启障碍路径:

根据自己文本的卡片ID添加可移动路径。
我这里添加的是可移动路径,不是添加的障碍,因为障碍的ID太多了比较麻烦:

路径一添加,超人立马变凡人。
源码:磨刀不误砍柴工

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值