From aa25860d6db5d9c2b5428d2be638d875d293cb0b Mon Sep 17 00:00:00 2001 From: Fabio Iotti Date: Sat, 5 Oct 2024 17:56:18 +0200 Subject: [PATCH] Improve fleets --- scenes/ships_fleet/ship/ship.gd | 29 +++++++++++++++++++++ scenes/ships_fleet/ships_fleet.gd | 36 +++++++++++++++++++-------- scenes/templates/scene_templates.tres | 2 +- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/scenes/ships_fleet/ship/ship.gd b/scenes/ships_fleet/ship/ship.gd index f35601e..27ca9f2 100644 --- a/scenes/ships_fleet/ship/ship.gd +++ b/scenes/ships_fleet/ship/ship.gd @@ -1,10 +1,39 @@ class_name Ship extends Node2D +const ACCELERATION = 100. +const ROTATION_SPEED = 3. +const MAX_SPEED = 100. + @export var color: Color : set(value): color = value _update_color(color) +@export var target_position: Vector2 + +var velocity: Vector2 + +func _process(delta: float) -> void: + var target_velocity := (target_position - global_position).normalized() * MAX_SPEED + var adjusted_target_velocity := target_velocity - velocity + var acceleration := Vector2.ZERO if adjusted_target_velocity == Vector2.ZERO else adjusted_target_velocity.normalized() * ACCELERATION + + var decelerate_at_distance := velocity.length_squared() / (2. * ACCELERATION) + var distance_squared := global_position.distance_squared_to(target_position) + var slow_down := distance_squared < decelerate_at_distance*decelerate_at_distance + if slow_down: + acceleration = velocity.normalized() * -ACCELERATION + + velocity += acceleration * delta + + var speed_squared := velocity.length_squared() + if speed_squared > MAX_SPEED*MAX_SPEED: + velocity = velocity / sqrt(speed_squared) * MAX_SPEED + + global_position += velocity * delta + + rotation = rotate_toward(rotation, global_position.angle_to_point(target_position), min(1., delta) * ROTATION_SPEED) + func _update_color(ship_color: Color) -> void: %LineTrail.material.set_shader_parameter('color', ship_color) diff --git a/scenes/ships_fleet/ships_fleet.gd b/scenes/ships_fleet/ships_fleet.gd index 3f1f270..98acb04 100644 --- a/scenes/ships_fleet/ships_fleet.gd +++ b/scenes/ships_fleet/ships_fleet.gd @@ -1,6 +1,11 @@ extends Node2D class_name ShipsFleet +const RANK_SIZE = 7 +const RANKS_DISTANCE = 12. +const SHOULDER_DISTANCE = 8. +const DISPERSE_AT_DISTANCE = 100. + @export var departed_at: int # Time.get_ticks_msec() @export var arrives_at: int # Time.get_ticks_msec() @@ -14,7 +19,7 @@ class_name ShipsFleet @export var count: int : set(value): count = value - _update_instances_count() + _update_ships_count() @export var trail: Trail @@ -32,24 +37,24 @@ func _exit_tree() -> void: #region Graphics -var _instances: Array[Node2D] = [] +var _ships: Array[Ship] = [] @export var ship_template: PackedScene -func _update_instances_count() -> void: - var diff = count - _instances.size() +func _update_ships_count() -> void: + var diff = count - _ships.size() for i in range(diff): - var j = float(1 + _instances.size()) var ship: Ship = ship_template.instantiate() ship.color = player.color add_child(ship) - ship.position = Vector2.from_angle(j) * j * 2. - ship.look_at(to - from) - _instances.push_back(ship) + ship.position = from + ship.rotation = randf_range(0, 2 * PI) + ship.velocity = randf_range(60., 120.) * Vector2.from_angle(ship.rotation) + _ships.push_back(ship) for i in range(-diff): - var ship: Node2D = _instances.pop_back() + var ship: Ship = _ships.pop_back() remove_child(ship) var _arrived := false @@ -58,7 +63,18 @@ func _update_position(tick: int) -> void: if not _arrived: var clamped_tick := clampi(tick, departed_at, arrives_at) var progress := float(clamped_tick - departed_at) / float(arrives_at - departed_at) - position = lerp(from, to, smoothstep(0., 1., progress)) + var fleet_position: Vector2 = lerp(from, to, clampf(progress, 0., 1.)) + var dispersiveness := clampf(sqrt(minf(fleet_position.distance_squared_to(from), fleet_position.distance_squared_to(to))) / DISPERSE_AT_DISTANCE, 0., 1.) + + var angle = from.angle_to_point(to) + var ranks_count := ceili(float(_ships.size()) / RANK_SIZE) + for i in range(_ships.size()): + var rank := floori(float(i) / RANK_SIZE) + var position_in_rank := i % RANK_SIZE + var ships_in_rank := RANK_SIZE if rank != ranks_count - 1 else (_ships.size() - (ranks_count - 1) * RANK_SIZE) + var assigned_position := Vector2(rank * -RANKS_DISTANCE - abs(position_in_rank - ships_in_rank / 2.) * 5., float(position_in_rank - (ships_in_rank - 1) * .5) * SHOULDER_DISTANCE) + _ships[i].target_position = fleet_position + lerp(Vector2.ZERO, assigned_position.rotated(angle) + Vector2.from_angle(sin(i + tick / 10.)) * 2., dispersiveness) + if tick >= arrives_at: _arrived = true trail.show_trail = false diff --git a/scenes/templates/scene_templates.tres b/scenes/templates/scene_templates.tres index 1ec1b07..971f166 100644 --- a/scenes/templates/scene_templates.tres +++ b/scenes/templates/scene_templates.tres @@ -1,4 +1,4 @@ -[gd_resource type="Resource" script_class="TemplateScenes" load_steps=5 format=3 uid="uid://cp0dudi0f5r62"] +[gd_resource type="Resource" script_class="SceneTemplates" load_steps=5 format=3 uid="uid://cp0dudi0f5r62"] [ext_resource type="PackedScene" uid="uid://dq00mi6jwsa1f" path="res://scenes/control_planet/control_planet.tscn" id="1_3rbtf"] [ext_resource type="Script" path="res://scenes/templates/scene_templates.gd" id="1_yvn3m"]