简单实现无限地图

无限地图顾名思义就是永远也到达不了终点的地图。但并不意味着要不停的加载生成地图。

可以通过算法实现分块加载地图,并改变地图的位置来实现无限地图。

首先在场景中创建一个空对象。挂上此脚本。

 Player是主角,playerwh和terrainwh是玩家和地图的检查范围,prefab是地图预制体。

代码如下:

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

public class TerrainMgr : MonoBehaviour
{
    public GameObject player;
    public float playerWH;
    public float TerrainWH;
    public GameObject prefab;
    Vector3 playerpos;
      GameObject terrain;
    Dictionary<Vector2, GameObject> showDic = new Dictionary<Vector2, GameObject>();
    //对象池
    Queue<GameObject> pool = new Queue<GameObject>();

    void Start()
    {
        playerpos = player.transform.position;
        player.transform.position = new Vector3(0.1f, 0, 0);
       
    }

    // Update is called once per frame
    void Update()
    {

        if (playerpos != player.transform.position)
        {
            List<Vector2> showlist = new List<Vector2>();

            Rect playerRect = new Rect(player.transform.position.x, player.transform.position.z, playerWH, playerWH);

            int x = (int)(player.transform.position.x / TerrainWH);
            int z = (int)(player.transform.position.z / TerrainWH);
            showlist.Add(new Vector2(x, z));
            if (IsLap(playerRect, new Rect((x + 1) * TerrainWH, z * TerrainWH, TerrainWH, TerrainWH)))
            {
                showlist.Add(new Vector2(x + 1, z));
            }

            if (IsLap(playerRect, new Rect((x - 1) * TerrainWH, z * TerrainWH, TerrainWH, TerrainWH)))
            {
                showlist.Add(new Vector2(x - 1, z));
            }

            if (IsLap(playerRect, new Rect(x * TerrainWH, (z + 1) * TerrainWH, TerrainWH, TerrainWH)))
            {
                showlist.Add(new Vector2(x, z + 1));
            }

            if (IsLap(playerRect, new Rect(x * TerrainWH, (z - 1) * TerrainWH, TerrainWH, TerrainWH)))
            {
                showlist.Add(new Vector2(x, z - 1));
            }

            if (IsLap(playerRect, new Rect((x + 1) * TerrainWH, (z + 1) * TerrainWH, TerrainWH, TerrainWH)))
            {
                showlist.Add(new Vector2(x + 1, z + 1));
            }

            if (IsLap(playerRect, new Rect((x - 1) * TerrainWH, (z + 1) * TerrainWH, TerrainWH, TerrainWH)))
            {
                showlist.Add(new Vector2(x - 1, z + 1));
            }

            if (IsLap(playerRect, new Rect((x + 1) * TerrainWH, (z - 1) * TerrainWH, TerrainWH, TerrainWH)))
            {
                showlist.Add(new Vector2(x + 1, z - 1));
            }

            if (IsLap(playerRect, new Rect((x - 1) * TerrainWH, (z - 1) * TerrainWH, TerrainWH, TerrainWH)))
            {
                showlist.Add(new Vector2(x - 1, z - 1));
            }
            

            List<Vector2> deslist = new List<Vector2>();

            foreach (var item in showDic.Keys)
            {
                if (!showlist.Contains(item))
                {
                    showDic[item].SetActive(false);
                    pool.Enqueue(showDic[item]);
                    deslist.Add(item);
                }
            }

            foreach (var item in deslist)
            {
                showDic.Remove(item);
            }

            foreach (var item in showlist)
            {
                if (!showDic.ContainsKey(item))
                {
                  
                    if (pool.Count>0)
                    {
                        terrain = pool.Dequeue();
                        terrain.SetActive(true);
                    }
                    else
                    {
                        terrain = Instantiate(prefab);
                    }
                    terrain.transform.position = new Vector3(item.x * TerrainWH, 0, item.y * TerrainWH);
                    showDic.Add(item, terrain);
                }
            }
            playerpos = player.transform.position;

        }



    }

    public bool IsLap(Rect a, Rect b)
    {
        float aMinX = a.x - a.width / 2;
        float aMaxX = a.x + a.width / 2;
        float aMinZ = a.y - a.height / 2;
        float aMaxZ = a.y + a.height / 2;

        float bMinX = b.x - b.width / 2;
        float bMaxX = b.x + b.width / 2;
        float bMinZ = b.y - b.height / 2;
        float bMaxZ = b.y + b.height / 2;
        if (aMinX < bMaxX &&
             bMinX < aMaxX &&
             aMinZ < bMaxZ &&
             bMinZ < aMaxZ
            )
        {
            return true;

        }
        else
        {
            return false;
        }


    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当然可以,下面是一个简单的 Dijkstra 算法实现,用于寻找从起点到终点的最短路径。 ```c #include <stdio.h> #include <stdlib.h> #include <limits.h> #define MAX_NODES 1000 int graph[MAX_NODES][MAX_NODES]; int visited[MAX_NODES]; int distance[MAX_NODES]; int path[MAX_NODES]; // 寻找未访问节点中距离最短的节点 int min_distance(int n) { int min = INT_MAX; int min_index = -1; for (int i = 0; i < n; i++) { if (!visited[i] && distance[i] <= min) { min = distance[i]; min_index = i; } } return min_index; } void dijkstra(int start, int end, int n) { // 初始化距离数组为无限大 for (int i = 0; i < n; i++) { distance[i] = INT_MAX; } // 起点距离为0 distance[start] = 0; for (int i = 0; i < n - 1; i++) { int u = min_distance(n); visited[u] = 1; for (int v = 0; v < n; v++) { if (!visited[v] && graph[u][v] && distance[u] != INT_MAX && distance[u] + graph[u][v] < distance[v]) { distance[v] = distance[u] + graph[u][v]; path[v] = u; } } } // 输出最短路径 if (distance[end] != INT_MAX) { int i = end; printf("Shortest path from %d to %d: ", start, end); printf("%d", i); while (i != start) { printf(" <- %d", path[i]); i = path[i]; } printf("\nDistance: %d\n", distance[end]); } else { printf("No path from %d to %d!\n", start, end); } } int main() { int n, m, u, v, w, start, end; printf("Enter number of nodes and edges: "); scanf("%d %d", &n, &m); // 初始化图 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { graph[i][j] = 0; } visited[i] = 0; distance[i] = INT_MAX; path[i] = -1; } // 读入边 for (int i = 0; i < m; i++) { printf("Enter edge %d (u v w): ", i + 1); scanf("%d %d %d", &u, &v, &w); graph[u][v] = w; graph[v][u] = w; } printf("Enter start node and end node: "); scanf("%d %d", &start, &end); dijkstra(start, end, n); return 0; } ``` 输入格式为: ``` Enter number of nodes and edges: <n> <m> Enter edge <i> (u v w): <u> <v> <w> ... Enter start node and end node: <start> <end> ``` 其中,`n` 表示节点数,`m` 表示边数,`u`、`v` 和 `w` 分别表示边的起点、终点和权重,`start` 和 `end` 分别表示起点和终点的节点编号。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值