Implemented state machine & added NPC ship template

This commit is contained in:
2ndbeam 2024-05-01 17:45:17 +03:00
commit bda9232e72
15 changed files with 284 additions and 22 deletions

View file

@ -0,0 +1,52 @@
extends State
@onready var ship = get_parent().get_parent()
@onready var star_system = get_tree().current_scene
@onready var update_timer = $UpdateDestination
## Ship will strive to achieve this angle
var destination_degrees: float = 0:
set(value):
if value > 180:
destination_degrees = value - 360
elif value < -180:
destination_degrees = 360 + value
else:
destination_degrees = value
## Delta to destination_degrees
var destination_difference: float = 15.0
## available map bounds (use with absolute position)
var available_bounds: Vector2
func _ready():
available_bounds = Vector2(star_system.width / 2, star_system.height / 2)
randomize()
func enter(_message):
update_timer.start()
update_destination()
func process(_delta):
# checking if need to apply torque
var current_destination_difference = destination_degrees - ship.hull.global_rotation_degrees
var rotation_sign = sign(current_destination_difference)
if current_destination_difference < 0:
current_destination_difference = 180 - current_destination_difference
if current_destination_difference > 180:
current_destination_difference -= 180
if abs(current_destination_difference) > destination_difference:
ship.engine.rotation_axis = rotation_sign * (current_destination_difference / 180)
else:
ship.engine.rotation_axis = 0.0
# making ship always accelerate
ship.engine.acceleration_axis = 1.0
# if ship is out of star system bounds, set destination angle to center
if abs(ship.global_position.x) > available_bounds.x or abs(ship.global_position.y) > available_bounds.y:
destination_degrees = rad_to_deg(ship.global_position.angle_to_point(Vector2.ZERO))
func exit():
update_timer.stop()
## Set new random direction
func update_destination():
destination_degrees += randi_range(-180, 180)

View file

@ -0,0 +1,20 @@
extends Node
class_name State
var tree : StateTree
func enter(_message : Dictionary):
pass
func exit():
pass
func process(_delta):
pass
func physics_process(_delta):
pass
func input(_message : Dictionary):
pass

View file

@ -0,0 +1,51 @@
extends Node
class_name StateTree
## Emitted when active state is transitioned
signal transitioned(to_state)
## Active state
@export var state : State
## Dictionary of all states
var cached_states = {}
func _ready():
for child in get_children():
child.tree = self
cached_states[child.name] = child
state.enter({})
## Make another state active. Optionally, properties can be provided with message
func transit(to : String, message : Dictionary = {}):
state.exit()
state = cached_states[to]
state.enter(message)
transitioned.emit(to)
## Provides properties to active state
func send_input(message : Dictionary = {}):
state.input(message)
## Provides properties to all states
func send_input_to_system(message : Dictionary = {}):
for state in cached_states.values():
state.input(message)
## Returns state with provided name
func get_state(state_name) -> State:
return cached_states[state_name]
#region Перегруженные виртуальные функции гойды
func _process(delta) -> void:
state.process(delta)
func _physics_process(delta) -> void:
state.physics_process(delta)
#endregion