📜  地图循环 (1)

📅  最后修改于: 2023-12-03 15:08:06.883000             🧑  作者: Mango

地图循环

简介

地图循环指的是在某个区域内循环进行地图展示。常见的应用场景是在游戏中,当角色走出屏幕时,新的地图会自动加载并展示出来。

作为程序员,实现地图循环对我们来说是不可或缺的技能之一。

实现方法

实现地图循环的方法有很多种,下面列举几种常用的方法:

1. 通过地图坐标循环

这是最简单的一种实现方法,具体步骤如下:

  • 在游戏中,地图坐标是非常重要的,我们可以通过判断角色的位置与地图坐标的关系来确定应该显示哪个地图。
  • 当角色的位置超出当前地图的范围时,就需要展示下一个地图。
  • 如果角色移动到了下一个地图的范围内,就需要把当前地图隐藏,并展示下一个地图。

示例代码:

void Update()
{
    var currentPosition = player.transform.position;
    var currentMap = GetCurrentMap(currentPosition);
    if(currentMap != null && currentMap != currentMapShown)
    {
        HideMap(currentMapShown);
        ShowMap(currentMap);
    }
}

Map GetCurrentMap(Vector3 currentPosition)
{
    foreach(var map in maps)
    {
        if(map.Contains(currentPosition))
        {
            return map;
        }
    }
    return null;
}

void HideMap(Map map)
{
    map.gameObject.SetActive(false);
}

void ShowMap(Map map)
{
    map.gameObject.SetActive(true);
}
2. 通过相机边界循环

这种方法把相机边界作为判断依据,具体步骤如下:

  • 获取相机的四个边界,当角色移动到某个边界外面时,就需要加载下一个地图。
  • 加载下一个地图时,需要把新地图与当前地图的边界相连,以实现无缝循环展示。

示例代码:

void Update()
{
    var currentPosition = player.transform.position;
    var currentMap = GetCurrentMap(currentPosition);
    if(currentMap != null && currentMap != currentMapShown)
    {
        HideMap(currentMapShown);
        ShowMap(currentMap);
    }
}

Map GetCurrentMap(Vector3 currentPosition)
{
    foreach(var map in maps)
    {
        if(map.Contains(currentPosition))
        {
            return map;
        }
    }
    return null;
}

void HideMap(Map map)
{
    map.gameObject.SetActive(false);
}

void ShowMap(Map map)
{
    map.gameObject.SetActive(true);
    var bounds = map.bounds;
    var cameraBounds = GetCameraBounds();
    if(cameraBounds.max.x > bounds.max.x)
    {
        var newMap = GetMapOnRight(map);
        if(newMap != null)
        {
            var newPosition = newMap.bounds.min + ((Vector3)bounds.max - (Vector3)cameraBounds.max);
            newMap.transform.position = newPosition;
        }
    }
    else if(cameraBounds.min.x < bounds.min.x)
    {
        var newMap = GetMapOnLeft(map);
        if(newMap != null)
        {
            var newPosition = newMap.bounds.max + ((Vector3)bounds.min - (Vector3)cameraBounds.min);
            newMap.transform.position = newPosition;
        }
    }
    else if(cameraBounds.max.y > bounds.max.y)
    {
        var newMap = GetMapAbove(map);
        if(newMap != null)
        {
            var newPosition = newMap.bounds.min + ((Vector3)bounds.max - (Vector3)cameraBounds.max);
            newMap.transform.position = newPosition;
        }
    }
    else if(cameraBounds.min.y < bounds.min.y)
    {
        var newMap = GetMapBelow(map);
        if(newMap != null)
        {
            var newPosition = newMap.bounds.max + ((Vector3)bounds.min - (Vector3)cameraBounds.min);
            newMap.transform.position = newPosition;
        }
    }
}

Bounds GetCameraBounds()
{
    var camera = Camera.main;
    var cameraHeight = 2f * camera.orthographicSize;
    var cameraWidth = cameraHeight * camera.aspect;
    var cameraBounds = new Bounds(camera.transform.position, new Vector3(cameraWidth + CAMERA_BOUND_PADDING, cameraHeight + CAMERA_BOUND_PADDING));
    return cameraBounds;
}

Map GetMapOnRight(Map currentMap)
{
    foreach(var map in maps)
    {
        if(currentMap != map && currentMap.bounds.max.x == map.bounds.min.x)
        {
            return map;
        }
    }
    return null;
}

Map GetMapOnLeft(Map currentMap)
{
    foreach(var map in maps)
    {
        if(currentMap != map && currentMap.bounds.min.x == map.bounds.max.x)
        {
            return map;
        }
    }
    return null;
}

Map GetMapAbove(Map currentMap)
{
    foreach(var map in maps)
    {
        if(currentMap != map && currentMap.bounds.max.y == map.bounds.min.y)
        {
            return map;
        }
    }
    return null;
}

Map GetMapBelow(Map currentMap)
{
    foreach(var map in maps)
    {
        if(currentMap != map && currentMap.bounds.min.y == map.bounds.max.y)
        {
            return map;
        }
    }
    return null;
}
结语

以上是两种实现地图循环的方法,可以根据游戏情况选择适合的实现方法。实现地图循环不仅可以提升游戏体验,而且也是很好的练习编程技能的机会。