110 lines
3.2 KiB
GDScript
110 lines
3.2 KiB
GDScript
extends CharacterBody2D
|
|
|
|
@onready var state_machine: StateMachine = $StateMachine
|
|
#
|
|
@onready var sprite: Node = $Sprite2D
|
|
#
|
|
const MAX_SPEED: float = 150.0
|
|
const MAX_ACCELERATION: float = 300.0
|
|
const SLOWING_RADIUS: float = 80.0
|
|
const SHAKE_INTENSITY: float = 8.0
|
|
const ROTATION_SPEED: float = 5.0 # adians per second
|
|
#
|
|
@onready var detection_area: Area2D = $VisionCone
|
|
signal waste_detected(waste)
|
|
#
|
|
var battery_charge: float = 100.0
|
|
const battery_charge_drain_per_second: float = 5.0
|
|
const battery_charge_recharge_per_second: float = 30.0
|
|
# carry item
|
|
var carry_item: Node2D = null
|
|
|
|
|
|
func _ready() -> void:
|
|
pass
|
|
|
|
|
|
# detection_area.body_entered.connect(Callable(self, "_on_body_entered"))
|
|
# detection_area.area_entered.connect(Callable(self, "_on_area_entered"))
|
|
|
|
|
|
# func _on_body_entered(body):
|
|
# if body.is_in_group("waste"):
|
|
# emit_signal("waste_detected", body)
|
|
|
|
|
|
# func _on_area_entered(area):
|
|
# if area.is_in_group("waste"):
|
|
# emit_signal("waste_detected", area)
|
|
|
|
|
|
func _draw() -> void:
|
|
if velocity.length() > 0.1:
|
|
var local_velocity: Vector2 = global_transform.basis_xform_inv(velocity.normalized() * 400)
|
|
draw_line(Vector2.ZERO, local_velocity, Color(1, 0, 0), 2)
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
battery_charge -= battery_charge_drain_per_second * delta
|
|
%StateMachineInfoPanel.values["battery_charge"] = battery_charge
|
|
if carry_item:
|
|
# put the carry_item on the character
|
|
carry_item.position = position
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
rotate_towards_velocity(delta)
|
|
detect_waste()
|
|
queue_redraw()
|
|
|
|
|
|
func detect_waste() -> void:
|
|
var overlapping_bodies: Array[Node2D] = detection_area.get_overlapping_bodies()
|
|
for body in overlapping_bodies:
|
|
if body.is_in_group("waste"):
|
|
emit_signal("waste_detected", body)
|
|
|
|
|
|
func move_towards(target: Vector2, delta: float) -> void:
|
|
var to_target: Vector2 = target - position
|
|
var distance: float = to_target.length()
|
|
|
|
if distance < 5.0:
|
|
velocity = Vector2.ZERO
|
|
return
|
|
|
|
var desired_speed: float = MAX_SPEED
|
|
if distance < SLOWING_RADIUS:
|
|
desired_speed = lerp(0, int(MAX_SPEED), distance / SLOWING_RADIUS)
|
|
|
|
var desired_velocity: Vector2 = to_target.normalized() * desired_speed
|
|
|
|
var steering: Vector2 = desired_velocity - velocity
|
|
|
|
var steering_length: float = steering.length()
|
|
if steering_length > MAX_ACCELERATION * delta:
|
|
steering = steering.normalized() * MAX_ACCELERATION * delta
|
|
|
|
velocity += steering
|
|
|
|
if velocity.length() > 0.1:
|
|
var shake: Vector2 = Vector2(
|
|
rand_range(-SHAKE_INTENSITY, SHAKE_INTENSITY),
|
|
rand_range(-SHAKE_INTENSITY, SHAKE_INTENSITY)
|
|
)
|
|
velocity += shake
|
|
|
|
if velocity.length() > MAX_SPEED:
|
|
velocity = velocity.normalized() * MAX_SPEED
|
|
|
|
|
|
func rotate_towards_velocity(delta: float) -> void:
|
|
if velocity.length() > 0.1:
|
|
var target_angle: float = velocity.angle()
|
|
rotation = lerp_angle(rotation, target_angle, ROTATION_SPEED * delta)
|
|
sprite.rotation = -rotation
|
|
|
|
|
|
func rand_range(min: float, max: float) -> float:
|
|
return randf() * (max - min) + min
|