Seguir y limitar
Una Camera2D con suavizado de posición y las cuatro propiedades de límite. La cruz amarilla es el centro de la cámara, así puedes verla detenerse en el borde mientras el jugador sigue andando.
El editor de arriba está ejecutando este proyecto. Cambia una línea y se recarga.
Clases de Godot usadas
Camera2DLine2DPolygon2D
El código
scripts/main.gd
extends Node
const MAP: Vector2 = Vector2(2600, 1500)
const SPEED: float = 520.0
var player: Node2D
var camera: Camera2D
var crosshair: Node2D
var readout: Label
var angle: float = PI
var manual: bool = false
func _ready() -> void:
_add_background()
_add_map()
player = _make_square(52.0, Color('#8eef97'))
player.position = _orbit_point()
add_child(player)
camera = Camera2D.new()
camera.position_smoothing_enabled = true
camera.position_smoothing_speed = 4.0
camera.limit_left = 0
camera.limit_top = 0
camera.limit_right = int(MAP.x)
camera.limit_bottom = int(MAP.y)
camera.limit_smoothed = true
player.add_child(camera)
camera.make_current()
crosshair = _make_crosshair()
add_child(crosshair)
_add_hud()
print('the green square walks the map on its own, arrows drive it, the camera stops at the border')
func _process(delta: float) -> void:
var drive: Vector2 = Vector2(
float(Input.is_key_pressed(KEY_RIGHT)) - float(Input.is_key_pressed(KEY_LEFT)),
float(Input.is_key_pressed(KEY_DOWN)) - float(Input.is_key_pressed(KEY_UP))
)
if drive != Vector2.ZERO:
manual = true
if manual:
player.position += drive.normalized() * SPEED * delta
player.position = player.position.clamp(Vector2(60, 60), MAP - Vector2(60, 60))
else:
angle += delta * 0.6
player.position = _orbit_point()
var center: Vector2 = camera.get_screen_center_position()
crosshair.position = center
readout.text = 'player %d, %d camera %d, %d' % [player.position.x, player.position.y, center.x, center.y]
func _orbit_point() -> Vector2:
return MAP * 0.5 + Vector2(cos(angle) * MAP.x * 0.46, sin(angle) * MAP.y * 0.44)
func _add_map() -> void:
var floor_rect: Polygon2D = Polygon2D.new()
floor_rect.polygon = PackedVector2Array([Vector2.ZERO, Vector2(MAP.x, 0), MAP, Vector2(0, MAP.y)])
floor_rect.color = Color('#12141a').lerp(Color('#2a2f3d'), 0.55)
add_child(floor_rect)
for x in range(200, int(MAP.x), 200):
_add_line(Vector2(x, 0), Vector2(x, MAP.y), 2.0, Color('#2a2f3d'))
for y in range(200, int(MAP.y), 200):
_add_line(Vector2(0, y), Vector2(MAP.x, y), 2.0, Color('#2a2f3d'))
var rng: RandomNumberGenerator = RandomNumberGenerator.new()
rng.seed = 9
for row in 4:
for column in 6:
var block: Node2D = _make_square(rng.randf_range(70, 140), Color('#8da5f3').lerp(Color('#12141a'), 0.35))
block.position = Vector2(300 + column * 400, 260 + row * 340) + Vector2(rng.randf_range(-80, 80), rng.randf_range(-80, 80))
add_child(block)
var border: Line2D = Line2D.new()
border.points = PackedVector2Array([Vector2(8, 8), Vector2(MAP.x - 8, 8), MAP - Vector2(8, 8), Vector2(8, MAP.y - 8), Vector2(8, 8)])
border.width = 16.0
border.default_color = Color('#fc7f7f')
add_child(border)
func _add_line(from: Vector2, to: Vector2, width: float, color: Color) -> void:
var line: Line2D = Line2D.new()
line.points = PackedVector2Array([from, to])
line.width = width
line.default_color = color
add_child(line)
func _make_square(size: float, color: Color) -> Node2D:
var square: Polygon2D = Polygon2D.new()
square.polygon = PackedVector2Array([Vector2(-size, -size) * 0.5, Vector2(size, -size) * 0.5, Vector2(size, size) * 0.5, Vector2(-size, size) * 0.5])
square.color = color
return square
func _make_crosshair() -> Node2D:
var mark: Node2D = Node2D.new()
for points in [PackedVector2Array([Vector2(-34, 0), Vector2(34, 0)]), PackedVector2Array([Vector2(0, -34), Vector2(0, 34)])]:
var line: Line2D = Line2D.new()
line.points = points
line.width = 4.0
line.default_color = Color('#f3d48d')
mark.add_child(line)
return mark
func _add_hud() -> void:
var hud: CanvasLayer = CanvasLayer.new()
add_child(hud)
var title: Label = Label.new()
title.text = 'green square: player yellow cross: camera center'
title.add_theme_font_size_override('font_size', 20)
title.add_theme_color_override('font_color', Color('#8da5f3'))
title.position = Vector2(40, 34)
hud.add_child(title)
readout = Label.new()
readout.add_theme_font_size_override('font_size', 20)
readout.add_theme_color_override('font_color', Color('#f3d48d'))
readout.position = Vector2(40, 64)
hud.add_child(readout)
func _add_background() -> void:
var layer: CanvasLayer = CanvasLayer.new()
layer.layer = -1
add_child(layer)
var background: ColorRect = ColorRect.new()
background.color = Color('#12141a')
layer.add_child(background)
background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)