【Godot】将 Camera 的视野范围限制在 TileMap 内

Godot 3.3.2

将摄像机视野范围限制在 TileMap 的范围内

#==================================================
#  Tile Map Group
#==================================================
#  将摄像机视野范围限制在当前节点下的所有 TileMap 大小内
#==================================================
# @datetime: 2021-8-27 00:46:48
#==================================================

extends Node2D


## 选中的节点是当前所有 tilemap 的
export (NodePath) var _camera : NodePath = @""
export var min_zoom : float = 1.0
export var max_zoom : float = 10.0
## 顶部与左侧最大位置(只有比这个值小才相机范围限制会被赋值)
export var max_limit_top_left : Vector2 = Vector2(0, 0)
## 底部与右侧最大位置(只有比这个值大才相机范围限制会被赋值)
export var max_limit_bottom_right : Vector2 = Vector2(100000, 100000)



#==================================================
#   内置方法
#==================================================
func _ready() -> void:
    var tilemap_list = []
    for child in get_children():
        if child is TileMap:
            tilemap_list.push_back(child)
    set_camera_prop(tilemap_list)


##  设置摄像机属性 
## @tilemap_list  tilemap 列表
func set_camera_prop(tilemap_list : Array) -> void:
    var camera : Camera2D = get_node_or_null(_camera) as Camera2D
    if camera == null || tilemap_list.size() == 0:
        return

    # 设置默认摄像机大小为第一个 tilemap 的大小
    var camera_size : Rect2 = tilemap_list[0].get_used_rect()
    camera_size.size *= tilemap_list[0].cell_size
    camera_size.position *= tilemap_list[0].cell_size
    tilemap_list.remove(0)

    # 计算所有 tilemap 的最大边界位置
    for tilemap in tilemap_list:
        var used_rect = tilemap.get_used_rect()
        used_rect.size *= tilemap.cell_size
        used_rect.position *= tilemap.cell_size

        if camera_size.position.x > used_rect.position.x:
            camera_size.position.x = used_rect.position.x
        if camera_size.position.y > used_rect.position.y:
            camera_size.position.y = used_rect.position.y
        if camera_size.end.x < used_rect.end.x:
            camera_size.end.x = used_rect.end.x
        if camera_size.end.y < used_rect.end.y:
            camera_size.end.y = used_rect.end.y

    # 设置最大位置的居中位置
#  camera.global_position = (camera_size.end - camera_size.position) / 2

    # 游戏窗口大小
    var w = ProjectSettings.get("display/window/size/width")
    var h = ProjectSettings.get("display/window/size/height")

    var scale_zoom = camera_size.size / Vector2(w, h)
    var zoom = min(scale_zoom.x, scale_zoom.y)
    zoom = max(min_zoom, zoom)
    zoom = min(max_zoom, zoom)

    # 限制视野范围
    if max_limit_top_left.x > camera_size.position.x:
        camera.limit_left = camera_size.position.x
    if max_limit_top_left.y > camera_size.position.y:
        camera.limit_top = camera_size.position.y

    if max_limit_bottom_right.x > camera_size.end.x:
        camera.limit_right = camera_size.end.x
    if max_limit_bottom_right.y > camera_size.end.y:
        camera.limit_bottom = camera_size.end.y

    camera.zoom = Vector2(zoom, zoom)

注意,节点要放在这个节点的下边
在这里插入图片描述

对比默认和运行后的效果

编辑器中默认的视野范围
在这里插入图片描述
运行后的视野范围
在这里插入图片描述
可以看到,已经全部覆盖到了

发表评论