beta-1.0
This commit is contained in:
33
Scripts/Characters/Chicken/npc_chicken.gd
Normal file
33
Scripts/Characters/Chicken/npc_chicken.gd
Normal file
@@ -0,0 +1,33 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
enum States {
|
||||
IDLE,
|
||||
PECKING
|
||||
}
|
||||
|
||||
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
|
||||
|
||||
var current_state := States.IDLE
|
||||
var pecking_sched := randf_range(8.0, 25.0)
|
||||
var pecking_timer := 0.0
|
||||
|
||||
func _ready() -> void:
|
||||
_print_sched()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if current_state == States.IDLE:
|
||||
pecking_timer += delta
|
||||
if pecking_timer >= pecking_sched:
|
||||
current_state = States.PECKING
|
||||
animated_sprite_2d.play("pecking")
|
||||
await animated_sprite_2d.animation_finished
|
||||
animated_sprite_2d.play("idle")
|
||||
pecking_sched = randf_range(8.0, 25.0)
|
||||
pecking_timer = 0
|
||||
current_state = States.IDLE
|
||||
_print_sched()
|
||||
|
||||
|
||||
func _print_sched() -> void:
|
||||
print("%s Pecking Schedule: %f" % [name, pecking_sched])
|
||||
1
Scripts/Characters/Chicken/npc_chicken.gd.uid
Normal file
1
Scripts/Characters/Chicken/npc_chicken.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c5pt6iroi01si
|
||||
@@ -0,0 +1,10 @@
|
||||
extends Node
|
||||
|
||||
@export var state_machine: PlayerStateMachine
|
||||
|
||||
# Public Methods
|
||||
func OnMovementInput(_movement_vector: Vector2) -> void:
|
||||
var current_state := state_machine.GetCurrentStateEnum()
|
||||
if current_state == PlayerStateMachine.States.IDLE:
|
||||
var idle_state := state_machine.current_state as PlayerIdleState
|
||||
idle_state.QueueMovement()
|
||||
@@ -0,0 +1 @@
|
||||
uid://ctoxjn2rvtjs6
|
||||
33
Scripts/Characters/Player/States/base_state.gd
Normal file
33
Scripts/Characters/Player/States/base_state.gd
Normal file
@@ -0,0 +1,33 @@
|
||||
class_name BaseState
|
||||
extends Node
|
||||
|
||||
@export var state_machine: PlayerStateMachine
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
push_error("Unimplemented Method: BaseState.GetName")
|
||||
return PlayerStateMachine.States.IDLE
|
||||
|
||||
|
||||
func GetAnimationBaseName() -> String:
|
||||
var state: String = PlayerStateMachine.States.keys()[GetStateEnum()]
|
||||
return state.to_lower()
|
||||
|
||||
|
||||
func Enter(_extra_parameters: Dictionary) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func Exit() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func IsActive() -> bool:
|
||||
return state_machine.GetCurrentStateEnum() == GetStateEnum()
|
||||
|
||||
|
||||
func IsStateActionable() -> bool:
|
||||
return true
|
||||
1
Scripts/Characters/Player/States/base_state.gd.uid
Normal file
1
Scripts/Characters/Player/States/base_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cb57l5vpq5bee
|
||||
29
Scripts/Characters/Player/States/cutscene_state.gd
Normal file
29
Scripts/Characters/Player/States/cutscene_state.gd
Normal file
@@ -0,0 +1,29 @@
|
||||
extends BaseState
|
||||
class_name PlayerCutsceneState
|
||||
|
||||
@onready var interact_scanner: InteractScanner = $"../../../Marker2D/InteractScanner"
|
||||
|
||||
# Public Methods
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.CUTSCENE
|
||||
|
||||
|
||||
func GetAnimationBaseName() -> String:
|
||||
return "idle"
|
||||
|
||||
|
||||
func Enter(_extra_parameters: Dictionary) -> void:
|
||||
print("Cutscene Started")
|
||||
interact_scanner.disable_interactions = true
|
||||
|
||||
|
||||
func Exit() -> void:
|
||||
interact_scanner.disable_interactions = false
|
||||
|
||||
|
||||
func OnCutsceneEnded() -> void:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.IDLE)
|
||||
|
||||
|
||||
func IsStateActionable() -> bool:
|
||||
return false
|
||||
1
Scripts/Characters/Player/States/cutscene_state.gd.uid
Normal file
1
Scripts/Characters/Player/States/cutscene_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bnontuqj3cnom
|
||||
37
Scripts/Characters/Player/States/drawing_bow_state.gd
Normal file
37
Scripts/Characters/Player/States/drawing_bow_state.gd
Normal file
@@ -0,0 +1,37 @@
|
||||
extends BaseState
|
||||
|
||||
signal PlayerBeganDrawingBow
|
||||
|
||||
@export var strafing_speed := 35
|
||||
@export var movement_componenent: MovementComponent
|
||||
@export var body: CharacterBody2D
|
||||
|
||||
var used_item_action: String
|
||||
var animation_finished := false
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.DRAWING_BOW
|
||||
|
||||
|
||||
func Enter(extra_parameters: Dictionary) -> void:
|
||||
animation_finished = false
|
||||
used_item_action = extra_parameters.action_name
|
||||
PlayerBeganDrawingBow.emit()
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
if !animation_finished:
|
||||
return
|
||||
|
||||
if !Input.is_action_pressed(used_item_action):
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.FIRING_ARROW)
|
||||
return
|
||||
|
||||
var movement_vector := movement_componenent.movement_vector
|
||||
if movement_vector != Vector2.ZERO:
|
||||
body.velocity = movement_vector * strafing_speed
|
||||
body.move_and_slide()
|
||||
|
||||
|
||||
func OnDrawingBowAnimationFinished() -> void:
|
||||
animation_finished = true
|
||||
@@ -0,0 +1 @@
|
||||
uid://bnp1vowmu15lg
|
||||
30
Scripts/Characters/Player/States/firing_arrow_state.gd
Normal file
30
Scripts/Characters/Player/States/firing_arrow_state.gd
Normal file
@@ -0,0 +1,30 @@
|
||||
extends BaseState
|
||||
|
||||
signal PlayerBeganFiringArrow
|
||||
signal PlayerFiredArrow(spawn_position: Vector2, direction: Vector2)
|
||||
|
||||
@export var direction_component: FacingDirectionComponent
|
||||
@export var arrow_spawn_marker: Marker2D
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.FIRING_ARROW
|
||||
|
||||
|
||||
func Enter(_extra_parameters: Dictionary) -> void:
|
||||
PlayerBeganFiringArrow.emit()
|
||||
|
||||
var position := arrow_spawn_marker.global_position
|
||||
var direction := Vector2.ZERO
|
||||
if direction_component.current_direction == Enums.Directions.LEFT:
|
||||
direction = Vector2.LEFT
|
||||
elif direction_component.current_direction == Enums.Directions.RIGHT:
|
||||
direction = Vector2.RIGHT
|
||||
elif direction_component.current_direction == Enums.Directions.UP:
|
||||
direction = Vector2.UP
|
||||
elif direction_component.current_direction == Enums.Directions.DOWN:
|
||||
direction = Vector2.DOWN
|
||||
PlayerFiredArrow.emit(position, direction)
|
||||
|
||||
|
||||
func OnFiringArrowAnimationFinished() -> void:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.IDLE)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cd2ewadcm8oi5
|
||||
47
Scripts/Characters/Player/States/idle_state.gd
Normal file
47
Scripts/Characters/Player/States/idle_state.gd
Normal file
@@ -0,0 +1,47 @@
|
||||
extends BaseState
|
||||
class_name PlayerIdleState
|
||||
|
||||
@export var movement_component: MovementComponent
|
||||
|
||||
signal PlayerBecameIdle
|
||||
|
||||
var _sit_queued := false
|
||||
var _sit_queue_pos: Vector2
|
||||
var _sit_queue_dir: Enums.Directions
|
||||
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.IDLE
|
||||
|
||||
|
||||
func Enter(_extra_parameters: Dictionary) -> void:
|
||||
PlayerBecameIdle.emit()
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
var item_a := Input.is_action_just_pressed("use_item_a")
|
||||
|
||||
if item_a:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.USING_ITEM_A, {})
|
||||
return
|
||||
|
||||
if _sit_queued:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.SITTING, {"pos": _sit_queue_pos, "dir": _sit_queue_dir})
|
||||
_sit_queued = false
|
||||
return
|
||||
|
||||
if movement_component.movement_vector != Vector2.ZERO:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.WALKING)
|
||||
|
||||
|
||||
func OnSitOnFurnitureTriggered(sitting_position: Vector2, sitting_direction: Enums.Directions) -> void:
|
||||
if state_machine.GetCurrentStateEnum() != GetStateEnum():
|
||||
return
|
||||
|
||||
_sit_queued = true
|
||||
_sit_queue_pos = sitting_position
|
||||
_sit_queue_dir = sitting_direction
|
||||
|
||||
|
||||
func OnCutsceneStarted() -> void:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.CUTSCENE)
|
||||
1
Scripts/Characters/Player/States/idle_state.gd.uid
Normal file
1
Scripts/Characters/Player/States/idle_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dkmc1t43gomdb
|
||||
25
Scripts/Characters/Player/States/sitting_state.gd
Normal file
25
Scripts/Characters/Player/States/sitting_state.gd
Normal file
@@ -0,0 +1,25 @@
|
||||
extends BaseState
|
||||
|
||||
@onready var player: PlayerCharacter = $"../../.."
|
||||
@onready var facing_direction_component: FacingDirectionComponent = $"../../../Components/FacingDirectionComponent"
|
||||
|
||||
func GetAnimationBaseName() -> String:
|
||||
return "idle"
|
||||
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.SITTING
|
||||
|
||||
|
||||
func Enter(extra_parameters: Dictionary) -> void:
|
||||
var pos := extra_parameters["pos"] as Vector2
|
||||
var dir := extra_parameters["dir"] as Enums.Directions
|
||||
|
||||
player.position = pos
|
||||
facing_direction_component.SetDirectionManually(dir)
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
if Input.is_action_just_pressed("player_interact"):
|
||||
player.position = Vector2(player.position.x, player.position.y + 16)
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.IDLE)
|
||||
1
Scripts/Characters/Player/States/sitting_state.gd.uid
Normal file
1
Scripts/Characters/Player/States/sitting_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bx1a35al4yiej
|
||||
15
Scripts/Characters/Player/States/using_item_a_state.gd
Normal file
15
Scripts/Characters/Player/States/using_item_a_state.gd
Normal file
@@ -0,0 +1,15 @@
|
||||
extends BaseState
|
||||
|
||||
@export var body: CharacterBody2D
|
||||
@export var direction_component: FacingDirectionComponent
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.USING_ITEM_A
|
||||
|
||||
|
||||
func GetAnimationBaseName() -> String:
|
||||
return "idle"
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.DRAWING_BOW, { "action_name": "use_item_a" })
|
||||
@@ -0,0 +1 @@
|
||||
uid://ckn7gmtc23b8l
|
||||
22
Scripts/Characters/Player/States/walking_state.gd
Normal file
22
Scripts/Characters/Player/States/walking_state.gd
Normal file
@@ -0,0 +1,22 @@
|
||||
extends BaseState
|
||||
|
||||
@export var walking_speed := 100
|
||||
|
||||
@export var movement_component: MovementComponent
|
||||
@export var direction_component: FacingDirectionComponent
|
||||
@export var body: CharacterBody2D
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.WALKING
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
if movement_component.movement_vector == Vector2.ZERO:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.IDLE)
|
||||
return
|
||||
|
||||
var movement_vector := movement_component.movement_vector
|
||||
body.velocity = movement_vector * walking_speed
|
||||
body.move_and_slide()
|
||||
|
||||
direction_component.ChangeDirectionUsingMovementVector(movement_vector)
|
||||
1
Scripts/Characters/Player/States/walking_state.gd.uid
Normal file
1
Scripts/Characters/Player/States/walking_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bwmmah30t3m0u
|
||||
@@ -1,7 +1,11 @@
|
||||
extends Area2D
|
||||
class_name InteractScanner
|
||||
|
||||
signal InteractionActionTriggered()
|
||||
|
||||
@export var parent: Node2D
|
||||
@export var direction_component: FacingDirectionComponent
|
||||
@export var disable_interactions := false
|
||||
|
||||
# Public Methods
|
||||
func OnDirectionChanged() -> void:
|
||||
@@ -14,3 +18,11 @@ func OnDirectionChanged() -> void:
|
||||
parent.rotation = deg_to_rad(180)
|
||||
else:
|
||||
parent.rotation = deg_to_rad(0)
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if disable_interactions:
|
||||
return
|
||||
if Input.is_action_just_pressed("player_interact"):
|
||||
InputManager.IgnoreAction("player_interact")
|
||||
InteractionActionTriggered.emit()
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
extends Node
|
||||
class_name MovementComponent
|
||||
|
||||
signal MovementPerformed(movement_vector: Vector2)
|
||||
|
||||
# Constant Exports
|
||||
@export var SPEED := 100.0
|
||||
signal MovementInput(movement_vector: Vector2)
|
||||
|
||||
# Dynamic Exports
|
||||
@export var body: CharacterBody2D
|
||||
|
||||
var movement_vector: Vector2
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
var direction_vector := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
|
||||
|
||||
if direction_vector:
|
||||
var movement_vector := direction_vector * SPEED
|
||||
body.velocity = movement_vector
|
||||
body.move_and_slide()
|
||||
|
||||
MovementPerformed.emit(movement_vector)
|
||||
movement_vector = direction_vector
|
||||
MovementInput.emit(movement_vector)
|
||||
else:
|
||||
movement_vector = Vector2.ZERO
|
||||
|
||||
@@ -1,12 +1,56 @@
|
||||
extends CharacterBody2D
|
||||
class_name PlayerCharacter
|
||||
|
||||
signal InteractScannerAreaEntered(area: Area2D)
|
||||
signal InteractScannerAreaExited(area: Area2D)
|
||||
|
||||
signal InteractScannerBodyEntered(body: Node2D)
|
||||
signal InteractScannerBodyExited(body: Node2D)
|
||||
|
||||
signal InteractionActionTriggered()
|
||||
|
||||
signal ArrowFired(fire_position: Vector2, direction: Vector2)
|
||||
signal SitOnFurnitureTriggered(sitting_position: Vector2, sitting_direction: Enums.Directions)
|
||||
|
||||
signal CutsceneStarted()
|
||||
signal CutsceneEnded()
|
||||
|
||||
@onready var state_machine: PlayerStateMachine = $StateMachine
|
||||
|
||||
# Public Methods
|
||||
func OnSitOnFurnitureTriggered(sitting_position: Vector2, sitting_direction: Enums.Directions):
|
||||
SitOnFurnitureTriggered.emit(sitting_position, sitting_direction)
|
||||
|
||||
|
||||
func OnCutsceneStarted() -> void:
|
||||
CutsceneStarted.emit()
|
||||
|
||||
|
||||
func OnCutsceneEnded() -> void:
|
||||
CutsceneEnded.emit()
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _on_interact_scanner_area_entered(area: Area2D) -> void:
|
||||
InteractScannerAreaEntered.emit(area)
|
||||
|
||||
|
||||
func _on_interact_scanner_area_exited(area: Area2D) -> void:
|
||||
InteractScannerAreaExited.emit(area)
|
||||
|
||||
|
||||
func _on_interact_scanner_body_entered(body: Node2D) -> void:
|
||||
InteractScannerBodyEntered.emit(body)
|
||||
|
||||
|
||||
func _on_interact_scanner_body_exited(body: Node2D) -> void:
|
||||
InteractScannerBodyExited.emit(body)
|
||||
|
||||
|
||||
func _on_interaction_action_triggered() -> void:
|
||||
if state_machine.current_state.IsStateActionable():
|
||||
InteractionActionTriggered.emit()
|
||||
|
||||
|
||||
func _on_using_item_a_state_arrow_fired(fire_position: Vector2, direction: Vector2) -> void:
|
||||
ArrowFired.emit(fire_position, direction)
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
extends Node2D
|
||||
|
||||
signal DrawingBowAnimationFinished
|
||||
signal FiringArrowAnimationFinished
|
||||
|
||||
@export var state_machine: PlayerStateMachine
|
||||
@export var direction_component: FacingDirectionComponent
|
||||
|
||||
@onready var full: AnimatedSprite2D = $Full
|
||||
@onready var base: AnimatedSprite2D = $Base
|
||||
@onready var hair: AnimatedSprite2D = $Hair
|
||||
@onready var pants: AnimatedSprite2D = $Pants
|
||||
@@ -15,7 +19,7 @@ var is_flipped := false
|
||||
|
||||
# Public Methods
|
||||
func UpdateSprite() -> void:
|
||||
var current_state := state_machine.GetCurrentState()
|
||||
var current_state := state_machine.current_state
|
||||
var current_direction := direction_component.GetCurrentDirection()
|
||||
var animation := _build_animation_name(current_state, current_direction)
|
||||
var should_flip := _should_flip_horizontal()
|
||||
@@ -31,18 +35,26 @@ func UpdateSprite() -> void:
|
||||
part.play()
|
||||
part.flip_h = should_flip
|
||||
|
||||
|
||||
func OnAnimationFinished() -> void:
|
||||
if current_animation.begins_with("drawing-bow-"):
|
||||
DrawingBowAnimationFinished.emit()
|
||||
elif current_animation.begins_with("firing-arrow-"):
|
||||
FiringArrowAnimationFinished.emit()
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
all_parts = [
|
||||
base, hair, pants, hands, shoes
|
||||
full, #base, hair, pants, hands, shoes
|
||||
]
|
||||
|
||||
UpdateSprite()
|
||||
|
||||
|
||||
func _build_animation_name(state: PlayerStateMachine.States, direction: Enums.Directions) -> String:
|
||||
func _build_animation_name(state: BaseState, direction: Enums.Directions) -> String:
|
||||
# e.g. "idle-down", "walking-up"
|
||||
var state_str = PlayerStateMachine.States.keys()[state].to_lower()
|
||||
var state_str = state.GetAnimationBaseName().replace("_", "-")
|
||||
var direction_str = _direction_to_animation_state(direction)
|
||||
return "%s-%s" % [state_str, direction_str]
|
||||
|
||||
|
||||
@@ -2,18 +2,54 @@ extends Node
|
||||
class_name PlayerStateMachine
|
||||
|
||||
enum States {
|
||||
IDLE, WALKING
|
||||
UNSET, IDLE, WALKING, USING_ITEM_A, DRAWING_BOW, FIRING_ARROW,
|
||||
SITTING, CUTSCENE
|
||||
}
|
||||
|
||||
@export var states_container: Node
|
||||
@export var current_state: BaseState
|
||||
|
||||
var state_dict := {}
|
||||
var queued_state: PlayerStateMachine.States = PlayerStateMachine.States.UNSET
|
||||
var queued_parameters: Dictionary = {}
|
||||
|
||||
# Public Methods
|
||||
func GetCurrentState() -> States:
|
||||
return States.IDLE
|
||||
func GetCurrentStateEnum() -> States:
|
||||
return current_state.GetStateEnum()
|
||||
|
||||
|
||||
func QueueStateChange(to_state_enum: PlayerStateMachine.States, extra_parameters: Dictionary = {}) -> void:
|
||||
queued_state = to_state_enum
|
||||
queued_parameters = extra_parameters
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
pass # Replace with function body.
|
||||
var children := states_container.get_children()
|
||||
for child in children:
|
||||
if child is not BaseState:
|
||||
continue
|
||||
var state := child as BaseState
|
||||
state_dict[state.GetStateEnum()] = state
|
||||
|
||||
if current_state:
|
||||
current_state.Enter({})
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta: float) -> void:
|
||||
pass
|
||||
func _process(delta: float) -> void:
|
||||
if current_state:
|
||||
current_state.Update(delta)
|
||||
|
||||
if queued_state != PlayerStateMachine.States.UNSET:
|
||||
_swap_state()
|
||||
|
||||
|
||||
func _swap_state() -> void:
|
||||
if current_state:
|
||||
current_state.Exit()
|
||||
|
||||
current_state = state_dict[queued_state] as BaseState
|
||||
current_state.Enter(queued_parameters)
|
||||
queued_state = PlayerStateMachine.States.UNSET
|
||||
queued_parameters = {}
|
||||
|
||||
Reference in New Issue
Block a user