Suivi et limites
Une Camera2D avec lissage de position et les quatre propriétés de limite. La croix jaune est le centre de la caméra, on la voit donc s'arrêter au bord pendant que le joueur continue.
L'éditeur ci-dessus fait tourner ce projet. Changez une ligne et il se recharge.
Classes Godot utilisées
Camera2DLine2DPolygon2D
Le code
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)