Perseguir e fugir
O fugitivo foge do mouse e o perseguidor segue o fugitivo. Os dois usam direction_to, só o sinal muda.
O editor acima está rodando este projeto. Mude uma linha e ele recarrega.
Classes do Godot usadas
Node2DLine2DVector2
O código
scripts/main.gd
extends Node
const RUNNER_SPEED: float = 340.0
const CHASER_SPEED: float = 250.0
const FLEE_RANGE: float = 340.0
const MARGIN: float = 100.0
const DRIFT_SPEED: float = 0.9
var runner: Node2D
var chaser: Node2D
var pointer: Polygon2D
var link: Line2D
var target: Vector2
var center: Vector2
var span: Vector2
var limit: Vector2
var drifting: bool = true
var elapsed: float = 0.0
func _ready() -> void:
_add_background()
var view: Vector2 = get_viewport().get_visible_rect().size
center = view * 0.5
span = view * 0.3
limit = view - Vector2(MARGIN, MARGIN)
target = center
link = Line2D.new()
link.width = 3.0
link.default_color = Color('#2a2f3d')
add_child(link)
pointer = _make_circle(11.0, Color('#f3d48d'))
pointer.position = target
add_child(pointer)
runner = _make_actor('runner', Color('#8eef97'), 26.0)
runner.position = center + Vector2(200, 60)
add_child(runner)
chaser = _make_actor('chaser', Color('#fc7f7f'), 30.0)
chaser.position = center - Vector2(320, 120)
add_child(chaser)
_add_label('every move is direction_to: the runner flees the mouse and the chaser, the chaser follows the runner', Vector2(40, 40))
print('move the mouse, the green shape runs away from it')
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
target = event.position
drifting = false
func _process(delta: float) -> void:
elapsed += delta
if drifting:
target = center + Vector2(cos(elapsed * DRIFT_SPEED), sin(elapsed * DRIFT_SPEED * 1.4)) * span
pointer.position = target
var flee: Vector2 = Vector2.ZERO
if target.distance_to(runner.position) < FLEE_RANGE:
flee += target.direction_to(runner.position)
if chaser.position.distance_to(runner.position) < FLEE_RANGE:
flee += chaser.position.direction_to(runner.position)
if flee == Vector2.ZERO:
flee = runner.position.direction_to(center)
runner.position += flee.normalized() * RUNNER_SPEED * delta
runner.position = runner.position.clamp(Vector2(MARGIN, MARGIN), limit)
chaser.position += chaser.position.direction_to(runner.position) * CHASER_SPEED * delta
link.points = PackedVector2Array([chaser.position, runner.position])
func _make_actor(text: String, color: Color, radius: float) -> Node2D:
var actor: Node2D = Node2D.new()
actor.add_child(_make_circle(radius, color))
var label: Label = Label.new()
label.text = text
label.position = Vector2(-30, radius + 10)
label.add_theme_color_override('font_color', color)
label.add_theme_font_size_override('font_size', 20)
actor.add_child(label)
return actor
func _add_label(text: String, at: Vector2) -> void:
var label: Label = Label.new()
label.text = text
label.position = at
label.add_theme_color_override('font_color', Color('#999999'))
label.add_theme_font_size_override('font_size', 20)
add_child(label)
func _make_circle(radius: float, color: Color) -> Polygon2D:
var points: PackedVector2Array = PackedVector2Array()
for i in 28:
points.append(Vector2(cos(TAU * i / 28.0), sin(TAU * i / 28.0)) * radius)
var circle: Polygon2D = Polygon2D.new()
circle.polygon = points
circle.color = color
return circle
func _add_background() -> void:
var background: ColorRect = ColorRect.new()
background.color = Color('#12141a')
add_child(background)
background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)