# 【摄像机适应地图】
可以让摄像机动态适应地图大小,并且可进行移动摄像机。
以下是摄像机挂载的代码。
extends Camera2D
@export var tilemap: TileMap
# 加速度
var acceleration = 200
# 速度
var velocity:Vector2 = Vector2.ZERO
# 停止衰减
var release_falloff = 10.0
# 最大速度
var max_speed = 30.0
func _ready():
set_anchor_mode(Camera2D.ANCHOR_MODE_FIXED_TOP_LEFT)
var zoom_vector = get_camera_zoom_to_tilemap()
set_zoom(zoom_vector)
apply_camera_limits()
func _process(_delta):
var input_vector = Input.get_vector("camera_move_left","camera_move_right","camera_move_up","camera_move_down")
calculate_velocity(input_vector)
update_global_position()
pass
func apply_camera_limits():
var tilemap_info = get_tilemap_info()
var level_side = Vector2i(tilemap_info.tile_size * tilemap_info.size)
set_limit(SIDE_LEFT,0)
set_limit(SIDE_TOP,0)
set_limit(SIDE_RIGHT,level_side.x)
set_limit(SIDE_BOTTOM,level_side.y)
func update_global_position():
var delta = get_process_delta_time()
global_position += lerp(
velocity,
Vector2.ZERO,
pow(2,-32 * delta)
)
# 处理摄像机位置超出地图的情况
var zoomed_viewport_size = get_viewport_to_zoom_scale()
var left_limit = get_limit(SIDE_LEFT)
var right_limit = get_limit(SIDE_RIGHT) - zoomed_viewport_size.x
var top_limit = get_limit(SIDE_TOP)
var bottom_limit = get_limit(SIDE_BOTTOM) - zoomed_viewport_size.y
global_position.x = clamp(global_position.x,left_limit,right_limit)
global_position.y = clamp(global_position.y,top_limit,bottom_limit)
func get_viewport_to_zoom_scale():
var zoom_vector = get_zoom()
var zoomed_viewport_size = Vector2i(
get_viewport().size[0] / zoom_vector.x,
get_viewport().size[1] / zoom_vector.y
)
return zoomed_viewport_size
func calculate_velocity(direction):
var delta = get_process_delta_time()
velocity += direction * acceleration * delta
if direction.x == 0:
# velocity.x = lerp(velocity.x,0.0,release_falloff * delta) 线性
velocity.x = lerp(0.0,velocity.x,pow(2,-release_falloff * delta)) # 曲线
if direction.y == 0:
# velocity.y = lerp(velocity.y,0.0,release_falloff * delta) 线性
velocity.y = lerp(0.0,velocity.y,pow(2,-release_falloff * delta)) # 曲线
velocity.x = clamp(
velocity.x,
-max_speed,
max_speed
)
velocity.y = clamp(
velocity.y,
-max_speed,
max_speed
)
func get_camera_zoom_to_tilemap():
var viewport_size = get_viewport().size # [x , y]
var tilemap_info = get_tilemap_info()
var level_size = Vector2i(tilemap_info.tile_size * tilemap_info.size)
var viewport_aspect = viewport_size[0] / viewport_size[1]
var level_aspect = float(level_size.x) / level_size.y
var new_zoom = 1.0
if level_aspect > viewport_aspect:
new_zoom = viewport_size[1] / level_size.y
else:
new_zoom = viewport_size[0] / level_size.x
# 可以限制缩放
new_zoom = clamp(new_zoom,2,3.5)
return Vector2(new_zoom,new_zoom)
func get_tilemap_info():
var tile_size = tilemap.get_tileset().tile_size
var tilemap_rect = tilemap.get_used_rect()
var tilemap_size = Vector2i(
tilemap_rect.end.x - tilemap_rect.position.x,
tilemap_rect.end.y - tilemap_rect.position.y
)
return {"size":tilemap_size, "tile_size":tile_size}
← 【保存游戏】