Add state modifier stack to pop on/off state changes.
This commit is contained in:
parent
7d35942649
commit
e5e8c030f6
13
Main.tscn
13
Main.tscn
|
|
@ -1,10 +1,8 @@
|
||||||
[gd_scene load_steps=19 format=2]
|
[gd_scene load_steps=17 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://src/playerB/Player.tscn" type="PackedScene" id=1]
|
|
||||||
[ext_resource path="res://src/playerC/Player.tscn" type="PackedScene" id=2]
|
[ext_resource path="res://src/playerC/Player.tscn" type="PackedScene" id=2]
|
||||||
[ext_resource path="res://assets/Tiles/Assets/Assets.png" type="Texture" id=3]
|
[ext_resource path="res://assets/Tiles/Assets/Assets.png" type="Texture" id=3]
|
||||||
[ext_resource path="res://src/CameraControl-Position2D.gd" type="Script" id=5]
|
[ext_resource path="res://src/CameraControl-Position2D.gd" type="Script" id=5]
|
||||||
[ext_resource path="res://src/enemyB/Enemy2.tscn" type="PackedScene" id=6]
|
|
||||||
|
|
||||||
[sub_resource type="ConvexPolygonShape2D" id=2]
|
[sub_resource type="ConvexPolygonShape2D" id=2]
|
||||||
points = PoolVector2Array( 16, 16, 0, 16, 0, 0, 16, 0 )
|
points = PoolVector2Array( 16, 16, 0, 16, 0, 0, 16, 0 )
|
||||||
|
|
@ -145,12 +143,8 @@ __meta__ = {
|
||||||
"_edit_lock_": true
|
"_edit_lock_": true
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="Player" parent="." instance=ExtResource( 1 )]
|
[node name="Player" parent="." instance=ExtResource( 2 )]
|
||||||
position = Vector2( 154, 27 )
|
|
||||||
|
|
||||||
[node name="Player2" parent="." instance=ExtResource( 2 )]
|
|
||||||
position = Vector2( 81, 27 )
|
position = Vector2( 81, 27 )
|
||||||
player_number = 2
|
|
||||||
|
|
||||||
[node name="CameraControl" type="Position2D" parent="."]
|
[node name="CameraControl" type="Position2D" parent="."]
|
||||||
process_priority = 1
|
process_priority = 1
|
||||||
|
|
@ -194,6 +188,3 @@ shape = SubResource( 13 )
|
||||||
[node name="CollisionShape2D2" type="CollisionShape2D" parent="CameraBoundaries"]
|
[node name="CollisionShape2D2" type="CollisionShape2D" parent="CameraBoundaries"]
|
||||||
position = Vector2( 1281, 68 )
|
position = Vector2( 1281, 68 )
|
||||||
shape = SubResource( 13 )
|
shape = SubResource( 13 )
|
||||||
|
|
||||||
[node name="NewEnemy" parent="." instance=ExtResource( 6 )]
|
|
||||||
position = Vector2( 400, 81 )
|
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,32 @@ _global_script_classes=[ {
|
||||||
"path": "res://src/playerB/player_move_component.gd"
|
"path": "res://src/playerB/player_move_component.gd"
|
||||||
}, {
|
}, {
|
||||||
"base": "Node",
|
"base": "Node",
|
||||||
|
"class": "PushdownStateMachine",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/pushdown_state_machine.gd"
|
||||||
|
}, {
|
||||||
|
"base": "Node",
|
||||||
"class": "State",
|
"class": "State",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://src/state.gd"
|
"path": "res://src/state.gd"
|
||||||
|
}, {
|
||||||
|
"base": "Node",
|
||||||
|
"class": "StateMachine",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/state_machine.gd"
|
||||||
|
}, {
|
||||||
|
"base": "Node",
|
||||||
|
"class": "StateModifier",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/state_modifier.gd"
|
||||||
} ]
|
} ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
"Enemy": "",
|
"Enemy": "",
|
||||||
"Movement": "",
|
"Movement": "",
|
||||||
"State": ""
|
"PushdownStateMachine": "",
|
||||||
|
"State": "",
|
||||||
|
"StateMachine": "",
|
||||||
|
"StateModifier": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ func jump_to_grid_position():
|
||||||
else:
|
else:
|
||||||
$Camera2D.limit_left = -10000000
|
$Camera2D.limit_left = -10000000
|
||||||
if $Right.is_colliding():
|
if $Right.is_colliding():
|
||||||
print("Oh God! No! ", $Right.get_collision_point().x, $Right.global_position)
|
#print("Oh God! No! ", $Right.get_collision_point().x, $Right.global_position)
|
||||||
$Camera2D.limit_right = $Right.get_collision_point().x
|
$Camera2D.limit_right = $Right.get_collision_point().x
|
||||||
else:
|
else:
|
||||||
$Camera2D.limit_right = 10000000
|
$Camera2D.limit_right = 10000000
|
||||||
|
|
|
||||||
13
src/components/Hurtbox_Component.tscn
Normal file
13
src/components/Hurtbox_Component.tscn
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
[gd_scene load_steps=2 format=2]
|
||||||
|
|
||||||
|
[sub_resource type="RectangleShape2D" id=148]
|
||||||
|
extents = Vector2( 11.5, 14.5 )
|
||||||
|
|
||||||
|
[node name="Hurtbox_Component" type="Area2D"]
|
||||||
|
collision_layer = 16
|
||||||
|
collision_mask = 128
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
|
self_modulate = Color( 1, 0, 0, 1 )
|
||||||
|
position = Vector2( 0, -4 )
|
||||||
|
shape = SubResource( 148 )
|
||||||
|
|
@ -5,7 +5,7 @@ export (NodePath) var idle_node
|
||||||
onready var idle_state: State = get_node(idle_node)
|
onready var idle_state: State = get_node(idle_node)
|
||||||
var can_fire = true
|
var can_fire = true
|
||||||
|
|
||||||
func enter() -> void:
|
func enter(state_modifiers: Array = []) -> void:
|
||||||
.enter()
|
.enter()
|
||||||
parent.velocity.x = 0
|
parent.velocity.x = 0
|
||||||
parent.set_hitbox(false)
|
parent.set_hitbox(false)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ export (NodePath) var idle_node
|
||||||
|
|
||||||
onready var idle_state: State = get_node(idle_node)
|
onready var idle_state: State = get_node(idle_node)
|
||||||
|
|
||||||
func enter() -> void:
|
func enter(state_modifiers: Array = []) -> void:
|
||||||
.enter()
|
.enter()
|
||||||
parent.velocity.x = 0
|
parent.velocity.x = 0
|
||||||
parent.set_hurtbox(false)
|
parent.set_hurtbox(false)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ onready var fire_state: State = get_node(fire_node)
|
||||||
onready var wander_state: State = get_node(wander_node)
|
onready var wander_state: State = get_node(wander_node)
|
||||||
onready var attack_state: State = get_node(attack_node)
|
onready var attack_state: State = get_node(attack_node)
|
||||||
|
|
||||||
func enter() -> void:
|
func enter(state_modifiers: Array = []) -> void:
|
||||||
.enter()
|
.enter()
|
||||||
parent.set_hurtbox(true)
|
parent.set_hurtbox(true)
|
||||||
parent.velocity.x = 0
|
parent.velocity.x = 0
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ onready var move_state: State = get_node(move_node)
|
||||||
|
|
||||||
export var jump_force: float = 900.0
|
export var jump_force: float = 900.0
|
||||||
|
|
||||||
func enter() -> void:
|
func enter(state_modifiers: Array = []) -> void:
|
||||||
.enter()
|
.enter()
|
||||||
parent.velocity.y = -jump_force
|
parent.velocity.y = -jump_force
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ onready var attack_state: State = get_node(attack_node)
|
||||||
var flip_flop = false
|
var flip_flop = false
|
||||||
var move_direction_x = 1.0
|
var move_direction_x = 1.0
|
||||||
|
|
||||||
func enter() -> void:
|
func enter(state_modifiers: Array = []) -> void:
|
||||||
.enter()
|
.enter()
|
||||||
parent.set_hurtbox(true)
|
parent.set_hurtbox(true)
|
||||||
state_timeout.start()
|
state_timeout.start()
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,15 @@ var direction = Vector2(0,0)
|
||||||
|
|
||||||
export var player_number: int = 1
|
export var player_number: int = 1
|
||||||
|
|
||||||
|
export var sprite_facing_right: bool = true
|
||||||
|
|
||||||
onready var movement_animations: AnimatedSprite = $AnimatedSprite
|
onready var movement_animations: AnimatedSprite = $AnimatedSprite
|
||||||
|
|
||||||
onready var movement_state_machine: Node = $Controllers/state_machine
|
onready var movement_state_machine: Node = $Controllers/state_machine
|
||||||
|
|
||||||
onready var player_move_component = $Controllers/move_component
|
onready var player_move_component = $Controllers/move_component
|
||||||
|
|
||||||
onready var player_hurtbox = $Hurtbox/CollisionShape2D
|
onready var player_hurtbox = $Hurtbox_Component/CollisionShape2D
|
||||||
|
|
||||||
onready var gun = $Gun
|
onready var gun = $Gun
|
||||||
|
|
||||||
|
|
@ -62,118 +64,3 @@ func shoot_projectile():
|
||||||
var is_shooting = false
|
var is_shooting = false
|
||||||
is_shooting = gun.shoot(direction.x)
|
is_shooting = gun.shoot(direction.x)
|
||||||
|
|
||||||
#func _ready():
|
|
||||||
# # Static types are necessary here to avoid warnings.
|
|
||||||
# var camera: Camera2D = $Camera2D
|
|
||||||
# camera.custom_viewport = $"../.."
|
|
||||||
# yield(get_tree(), "idle_frame")
|
|
||||||
# camera.make_current()
|
|
||||||
|
|
||||||
#
|
|
||||||
#func _physics_process(delta):
|
|
||||||
# # Horizontal movement
|
|
||||||
# velocity.x = (Input.get_axis("ui_left", "ui_right") * WALK_MAX_SPEED)
|
|
||||||
#
|
|
||||||
# # Vertical movement code. Apply gravity.
|
|
||||||
# velocity.y += gravity * delta
|
|
||||||
#
|
|
||||||
# # Move based on the velocity and snap to the ground.
|
|
||||||
# #velocity = move_and_slide_with_snap(velocity, Vector2.DOWN, Vector2.UP)
|
|
||||||
# velocity = move_and_slide(velocity, Vector2(0, -1))
|
|
||||||
#
|
|
||||||
# # Check for jumping. is_on_floor() must be called after movement code.
|
|
||||||
# # Apply Jump velocity
|
|
||||||
# if is_on_floor() and Input.is_action_just_pressed("ui_accept"):
|
|
||||||
# velocity.y = -JUMP_SPEED
|
|
||||||
#
|
|
||||||
# # Animate based on last state and velocity
|
|
||||||
# if velocity.x > 0 and _animated_sprite.flip_h != true:
|
|
||||||
# _animated_sprite.flip_h = true
|
|
||||||
# if velocity.x < 0 and _animated_sprite.flip_h != false:
|
|
||||||
# _animated_sprite.flip_h = false
|
|
||||||
#
|
|
||||||
# # forced state changes like falling an gitting hurt
|
|
||||||
# if velocity.y > 0 and player_state != STATE.JUMP and player_state != STATE.FALL:
|
|
||||||
# print("STATE_TRANSITION: Fall")
|
|
||||||
# player_state = STATE.FALL
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# # Each state should trigger its own animation
|
|
||||||
# match player_state:
|
|
||||||
# STATE.IDLE:
|
|
||||||
# # Transitions
|
|
||||||
# if velocity.y == -JUMP_SPEED:
|
|
||||||
# print("STATE_TRANSITION: Jump")
|
|
||||||
# player_last_state = STATE.IDLE
|
|
||||||
# player_state = STATE.JUMP
|
|
||||||
# elif velocity.x != 0:
|
|
||||||
# print("STATE_TRANSITION: Run")
|
|
||||||
# player_last_state = STATE.IDLE
|
|
||||||
# player_state = STATE.RUN
|
|
||||||
# # Animation
|
|
||||||
# if player_last_state != STATE.IDLE:
|
|
||||||
# $IdleTimeout.start()
|
|
||||||
# _animated_sprite.play("idle")
|
|
||||||
# player_last_state = STATE.IDLE
|
|
||||||
# if $IdleTimeout.time_left == 0 and _animated_sprite.animation != 'blink':
|
|
||||||
# _animated_sprite.play("blink")
|
|
||||||
# animation_play_finished = false
|
|
||||||
# if $IdleTimeout.time_left == 0 and animation_play_finished == true:
|
|
||||||
# $IdleTimeout.start()
|
|
||||||
# _animated_sprite.play("idle")
|
|
||||||
# print("blink over")
|
|
||||||
#
|
|
||||||
# STATE.JUMP:
|
|
||||||
# # Transitions
|
|
||||||
# if is_on_floor():
|
|
||||||
# print("STATE_TRANSITION: Idle")
|
|
||||||
# _animated_sprite.play("idle")
|
|
||||||
# player_last_state = STATE.JUMP
|
|
||||||
# player_state = STATE.IDLE
|
|
||||||
# # Animation
|
|
||||||
# if player_last_state != STATE.JUMP:
|
|
||||||
# _animated_sprite.play("jump")
|
|
||||||
# player_last_state = STATE.JUMP
|
|
||||||
#
|
|
||||||
# STATE.FALL:
|
|
||||||
# # Transitions
|
|
||||||
# if is_on_floor():
|
|
||||||
# print("STATE_TRANSITION: Idle")
|
|
||||||
# _animated_sprite.play("idle")
|
|
||||||
# player_last_state = STATE.FALL
|
|
||||||
# player_state = STATE.IDLE
|
|
||||||
# # Animation
|
|
||||||
# if player_last_state != STATE.FALL:
|
|
||||||
# _animated_sprite.animation = "jump"
|
|
||||||
# _animated_sprite.frame = 8
|
|
||||||
# _animated_sprite.stop()
|
|
||||||
# player_last_state = STATE.FALL
|
|
||||||
#
|
|
||||||
# STATE.RUN:
|
|
||||||
# # print (_animated_sprite.animation ) # apparentl playing doesn't stop when loop is disabled.
|
|
||||||
# # Transitions
|
|
||||||
# if velocity.y == -JUMP_SPEED:
|
|
||||||
# print("STATE_TRANSITION: Jump")
|
|
||||||
# _animated_sprite.play("jump")
|
|
||||||
# player_last_state = STATE.RUN
|
|
||||||
# player_state = STATE.JUMP
|
|
||||||
# elif velocity.x == 0:
|
|
||||||
# print("STATE_TRANSITION: Idle")
|
|
||||||
# _animated_sprite.play("idle")
|
|
||||||
# player_last_state = STATE.RUN
|
|
||||||
# player_state = STATE.IDLE
|
|
||||||
# # Animation
|
|
||||||
# if player_last_state == STATE.IDLE:
|
|
||||||
# _animated_sprite.play("step")
|
|
||||||
# animation_play_finished = false
|
|
||||||
# player_last_state = STATE.RUN
|
|
||||||
# elif animation_play_finished == true:
|
|
||||||
# _animated_sprite.play("run")
|
|
||||||
# animation_play_finished = false
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#func _on_AnimatedSprite_animation_finished():
|
|
||||||
# animation_play_finished = true
|
|
||||||
# print($AnimatedSprite.animation," anim over ", $IdleTimeout.time_left, animation_play_finished)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=86 format=2]
|
[gd_scene load_steps=88 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://src/playerC/Player-KinematicBody2D.gd" type="Script" id=1]
|
[ext_resource path="res://src/playerC/Player-KinematicBody2D.gd" type="Script" id=1]
|
||||||
[ext_resource path="res://src/playerC/states/idle.gd" type="Script" id=2]
|
[ext_resource path="res://src/playerC/states/idle.gd" type="Script" id=2]
|
||||||
|
|
@ -10,6 +10,9 @@
|
||||||
[ext_resource path="res://src/playerC/states/hurt.gd" type="Script" id=8]
|
[ext_resource path="res://src/playerC/states/hurt.gd" type="Script" id=8]
|
||||||
[ext_resource path="res://src/playerC/Gun.gd" type="Script" id=9]
|
[ext_resource path="res://src/playerC/Gun.gd" type="Script" id=9]
|
||||||
[ext_resource path="res://src/playerC/states/fire.gd" type="Script" id=10]
|
[ext_resource path="res://src/playerC/states/fire.gd" type="Script" id=10]
|
||||||
|
[ext_resource path="res://src/playerC/states/none.gd" type="Script" id=11]
|
||||||
|
[ext_resource path="res://src/components/Hurtbox_Component.tscn" type="PackedScene" id=12]
|
||||||
|
[ext_resource path="res://src/state_modifier.gd" type="Script" id=13]
|
||||||
|
|
||||||
[sub_resource type="StreamTexture" id=75]
|
[sub_resource type="StreamTexture" id=75]
|
||||||
load_path = "res://.import/MegaMan.png-dc2c293e5a0f5d183ee961942ac90e4a.stex"
|
load_path = "res://.import/MegaMan.png-dc2c293e5a0f5d183ee961942ac90e4a.stex"
|
||||||
|
|
@ -399,9 +402,6 @@ animations = [ {
|
||||||
[sub_resource type="RectangleShape2D" id=74]
|
[sub_resource type="RectangleShape2D" id=74]
|
||||||
extents = Vector2( 14, 18.5 )
|
extents = Vector2( 14, 18.5 )
|
||||||
|
|
||||||
[sub_resource type="RectangleShape2D" id=148]
|
|
||||||
extents = Vector2( 11.5, 14.5 )
|
|
||||||
|
|
||||||
[node name="Player" type="KinematicBody2D"]
|
[node name="Player" type="KinematicBody2D"]
|
||||||
collision_layer = 2
|
collision_layer = 2
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
||||||
|
|
@ -409,7 +409,7 @@ script = ExtResource( 1 )
|
||||||
[node name="AnimatedSprite" type="AnimatedSprite" parent="."]
|
[node name="AnimatedSprite" type="AnimatedSprite" parent="."]
|
||||||
frames = SubResource( 147 )
|
frames = SubResource( 147 )
|
||||||
animation = "idle"
|
animation = "idle"
|
||||||
frame = 26
|
frame = 1
|
||||||
playing = true
|
playing = true
|
||||||
flip_h = true
|
flip_h = true
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
|
|
@ -431,6 +431,9 @@ shape = SubResource( 74 )
|
||||||
|
|
||||||
[node name="Controllers" type="Node" parent="."]
|
[node name="Controllers" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="move_component" type="Node" parent="Controllers"]
|
||||||
|
script = ExtResource( 6 )
|
||||||
|
|
||||||
[node name="state_machine" type="Node" parent="Controllers"]
|
[node name="state_machine" type="Node" parent="Controllers"]
|
||||||
script = ExtResource( 3 )
|
script = ExtResource( 3 )
|
||||||
starting_state = NodePath("idle")
|
starting_state = NodePath("idle")
|
||||||
|
|
@ -439,6 +442,7 @@ starting_state = NodePath("idle")
|
||||||
script = ExtResource( 2 )
|
script = ExtResource( 2 )
|
||||||
animation_name = "idle"
|
animation_name = "idle"
|
||||||
move_speed = 90.0
|
move_speed = 90.0
|
||||||
|
transition_state_nodes = [ NodePath("../jump") ]
|
||||||
jump_node = NodePath("../jump")
|
jump_node = NodePath("../jump")
|
||||||
fall_node = NodePath("../fall")
|
fall_node = NodePath("../fall")
|
||||||
move_node = NodePath("../move")
|
move_node = NodePath("../move")
|
||||||
|
|
@ -482,17 +486,17 @@ animation_name = "fire"
|
||||||
timeout_seconds = 1.0
|
timeout_seconds = 1.0
|
||||||
idle_node = NodePath("../idle")
|
idle_node = NodePath("../idle")
|
||||||
|
|
||||||
[node name="move_component" type="Node" parent="Controllers"]
|
[node name="attack" type="Node" parent="Controllers/state_machine"]
|
||||||
script = ExtResource( 6 )
|
script = ExtResource( 13 )
|
||||||
|
timeout_seconds = 2.0
|
||||||
|
|
||||||
[node name="Hurtbox" type="Area2D" parent="."]
|
[node name="AttackStateMachine" type="Node" parent="Controllers"]
|
||||||
collision_layer = 16
|
script = ExtResource( 3 )
|
||||||
collision_mask = 128
|
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Hurtbox"]
|
[node name="none" type="Node" parent="Controllers/AttackStateMachine"]
|
||||||
self_modulate = Color( 1, 0, 0, 1 )
|
script = ExtResource( 11 )
|
||||||
position = Vector2( 0, -4 )
|
|
||||||
shape = SubResource( 148 )
|
[node name="Hurtbox_Component" parent="." instance=ExtResource( 12 )]
|
||||||
|
|
||||||
[node name="Gun" type="Position2D" parent="."]
|
[node name="Gun" type="Position2D" parent="."]
|
||||||
physics_interpolation_mode = 1
|
physics_interpolation_mode = 1
|
||||||
|
|
@ -509,4 +513,3 @@ width = 2.0
|
||||||
default_color = Color( 1, 0.607843, 0, 1 )
|
default_color = Color( 1, 0.607843, 0, 1 )
|
||||||
|
|
||||||
[connection signal="animation_finished" from="AnimatedSprite" to="." method="_on_AnimatedSprite_animation_finished"]
|
[connection signal="animation_finished" from="AnimatedSprite" to="." method="_on_AnimatedSprite_animation_finished"]
|
||||||
[connection signal="area_entered" from="Hurtbox" to="." method="_on_Hurtbox_area_entered"]
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ func enter() -> void:
|
||||||
parent.set_hurtbox(false)
|
parent.set_hurtbox(false)
|
||||||
state_timeout.start()
|
state_timeout.start()
|
||||||
can_fire = true
|
can_fire = true
|
||||||
|
if modifier_stack_ref.has($"../attack") == false:
|
||||||
|
$"../attack".state_timeout.start()
|
||||||
|
modifier_stack_ref.push_front($"../attack")
|
||||||
|
|
||||||
func process_input(_event: InputEvent) -> State:
|
func process_input(_event: InputEvent) -> State:
|
||||||
# if move_component.get_movement_direction() != 0.0:
|
# if move_component.get_movement_direction() != 0.0:
|
||||||
|
|
@ -45,3 +48,11 @@ func process_physics(delta: float) -> State:
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
|
||||||
|
func exit() -> void:
|
||||||
|
for mods in modifier_stack_ref:
|
||||||
|
print(mods.name)
|
||||||
|
|
||||||
|
# var testmod :StateModifier = StateModifier.new()
|
||||||
|
# testmod.name
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
|
||||||
1
src/playerC/states/none.gd
Normal file
1
src/playerC/states/none.gd
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
extends State
|
||||||
46
src/pushdown_state_machine.gd
Normal file
46
src/pushdown_state_machine.gd
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
class_name PushdownStateMachine extends Node
|
||||||
|
|
||||||
|
export (NodePath) var starting_state
|
||||||
|
|
||||||
|
var current_state: State
|
||||||
|
var state_stack = []
|
||||||
|
|
||||||
|
# Initialize the state machine by giving each child state a reference to the
|
||||||
|
# parent object it belongs to and enter the default starting_state.
|
||||||
|
func init(parent: KinematicBody2D, animations: AnimatedSprite, move_component) -> void:
|
||||||
|
for child in get_children():
|
||||||
|
child.parent = parent
|
||||||
|
child.animations = animations
|
||||||
|
child.move_component = move_component
|
||||||
|
|
||||||
|
# Initialize to the default state
|
||||||
|
change_state(get_node(starting_state))
|
||||||
|
|
||||||
|
# Change to the new state by first calling any exit logic on the current state.
|
||||||
|
func change_state(new_state: State) -> void:
|
||||||
|
if current_state:
|
||||||
|
current_state.exit()
|
||||||
|
|
||||||
|
current_state = new_state
|
||||||
|
current_state.enter()
|
||||||
|
|
||||||
|
func push_state(new_state: State) -> void:
|
||||||
|
state_stack.push_front(new_state)
|
||||||
|
|
||||||
|
|
||||||
|
# Pass through functions for the Player to call,
|
||||||
|
# handling state changes as needed.
|
||||||
|
func process_physics(delta: float) -> void:
|
||||||
|
var new_state = current_state.process_physics(delta)
|
||||||
|
if new_state:
|
||||||
|
change_state(new_state)
|
||||||
|
|
||||||
|
func process_input(event: InputEvent) -> void:
|
||||||
|
var new_state = current_state.process_input(event)
|
||||||
|
if new_state:
|
||||||
|
change_state(new_state)
|
||||||
|
|
||||||
|
func process_frame(delta: float) -> void:
|
||||||
|
var new_state = current_state.process_frame(delta)
|
||||||
|
if new_state:
|
||||||
|
change_state(new_state)
|
||||||
20
src/state.gd
20
src/state.gd
|
|
@ -1,13 +1,25 @@
|
||||||
class_name State
|
class_name State
|
||||||
extends Node
|
extends Node
|
||||||
|
## Animation and movement state class
|
||||||
|
##
|
||||||
|
## A state intended to control the movement and animation
|
||||||
|
## functions of a KinimaticBody2D node. Initialized with a
|
||||||
|
## player, movement node, and kinematicbody2d
|
||||||
|
## I think if we also had modifier states that transfered along with the enter and entrance of nodes, that would be helpful.
|
||||||
|
##
|
||||||
|
## @WIP
|
||||||
|
|
||||||
|
|
||||||
export var animation_name: String
|
export var animation_name: String
|
||||||
export var move_speed: float = 60
|
export var move_speed: float = 60
|
||||||
export var timeout_seconds: float = 0.0
|
export var timeout_seconds: float = 0.0
|
||||||
|
|
||||||
export(Array, String) var animation_sequence
|
export(Array, String) var animation_sequence
|
||||||
|
export(Array, NodePath) var transition_state_nodes
|
||||||
|
|
||||||
var animation_index: int = 0
|
var animation_index: int = 0
|
||||||
var current_animation_sequence: int = 0
|
var current_animation_sequence: int = 0
|
||||||
|
var modifier_stack_ref: Array # Well this didn't work
|
||||||
|
|
||||||
var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity")
|
var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity")
|
||||||
|
|
||||||
|
|
@ -20,6 +32,7 @@ var parent: KinematicBody2D
|
||||||
var state_timeout: Timer
|
var state_timeout: Timer
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
# Only add timout node if timer value was specified.
|
||||||
if(timeout_seconds > 0.0):
|
if(timeout_seconds > 0.0):
|
||||||
state_timeout = Timer.new()
|
state_timeout = Timer.new()
|
||||||
state_timeout.wait_time = timeout_seconds
|
state_timeout.wait_time = timeout_seconds
|
||||||
|
|
@ -30,6 +43,7 @@ func _ready():
|
||||||
|
|
||||||
func enter() -> void:
|
func enter() -> void:
|
||||||
print(parent.name, " entering State: ", self.name)
|
print(parent.name, " entering State: ", self.name)
|
||||||
|
#modifier_stack_ref = state_modifiers
|
||||||
if animation_name != '':
|
if animation_name != '':
|
||||||
animations.play(animation_name)
|
animations.play(animation_name)
|
||||||
elif animation_sequence.size() > 0:
|
elif animation_sequence.size() > 0:
|
||||||
|
|
@ -54,9 +68,3 @@ func process_frame(_delta: float) -> State:
|
||||||
|
|
||||||
func process_physics(_delta: float) -> State:
|
func process_physics(_delta: float) -> State:
|
||||||
return null
|
return null
|
||||||
|
|
||||||
#func get_movement_input() -> float:
|
|
||||||
# return move_component.get_movement_direction()
|
|
||||||
#
|
|
||||||
#func get_jump() -> bool:
|
|
||||||
# return move_component.wants_jump()
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
extends Node
|
class_name StateMachine extends Node
|
||||||
|
|
||||||
export (NodePath) var starting_state
|
export (NodePath) var starting_state
|
||||||
|
|
||||||
var current_state: State
|
var current_state: State
|
||||||
|
var state_modifiers: Array
|
||||||
|
|
||||||
# Initialize the state machine by giving each child state a reference to the
|
# Initialize the state machine by giving each child state a reference to the
|
||||||
# parent object it belongs to and enter the default starting_state.
|
# parent object it belongs to and enter the default starting_state.
|
||||||
func init(parent: KinematicBody2D, animations: AnimatedSprite, move_component) -> void:
|
func init(parent: KinematicBody2D, animations: AnimatedSprite, move_component) -> void:
|
||||||
for child in get_children():
|
for child in get_children():
|
||||||
|
if child is State:
|
||||||
|
print("Initializing State Node for ", parent.name, ": ", child.name)
|
||||||
child.parent = parent
|
child.parent = parent
|
||||||
child.animations = animations
|
child.animations = animations
|
||||||
child.move_component = move_component
|
child.move_component = move_component
|
||||||
|
child.modifier_stack_ref = state_modifiers
|
||||||
|
|
||||||
# Initialize to the default state
|
# Initialize to the default state
|
||||||
change_state(get_node(starting_state))
|
change_state(get_node(starting_state))
|
||||||
|
|
@ -22,6 +26,10 @@ func change_state(new_state: State) -> void:
|
||||||
|
|
||||||
current_state = new_state
|
current_state = new_state
|
||||||
current_state.enter()
|
current_state.enter()
|
||||||
|
if(state_modifiers.size() > 0):
|
||||||
|
print("Active Modifiers:")
|
||||||
|
for mods in state_modifiers:
|
||||||
|
print(mods.name)
|
||||||
|
|
||||||
# Pass through functions for the Player to call,
|
# Pass through functions for the Player to call,
|
||||||
# handling state changes as needed.
|
# handling state changes as needed.
|
||||||
|
|
@ -36,6 +44,14 @@ func process_input(event: InputEvent) -> void:
|
||||||
change_state(new_state)
|
change_state(new_state)
|
||||||
|
|
||||||
func process_frame(delta: float) -> void:
|
func process_frame(delta: float) -> void:
|
||||||
|
# Check the state modifiers for timeouts, and maybe more conditions later
|
||||||
|
# If the modifier is no longer valid, pop it from the stack.
|
||||||
|
# We could iterate through a whole list of states but I'm not sure i want
|
||||||
|
# states to be that complex.
|
||||||
|
if state_modifiers.empty() == false:
|
||||||
|
if state_modifiers[-1].state_timeout.time_left == 0:
|
||||||
|
print("Pop State Modifier: ", state_modifiers[-1].name)
|
||||||
|
state_modifiers.pop_back()
|
||||||
var new_state = current_state.process_frame(delta)
|
var new_state = current_state.process_frame(delta)
|
||||||
if new_state:
|
if new_state:
|
||||||
change_state(new_state)
|
change_state(new_state)
|
||||||
|
|
|
||||||
37
src/state_modifier.gd
Normal file
37
src/state_modifier.gd
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
class_name StateModifier
|
||||||
|
extends Node
|
||||||
|
## State modification
|
||||||
|
##
|
||||||
|
## A state modifier doesn't have any direct control of a game object.
|
||||||
|
## They are transfered from the enter and exit of other states and
|
||||||
|
## influence the movement or animation of their parent states.
|
||||||
|
## Rather than going full into paralell state machines I hope that this
|
||||||
|
## modifier will be suitable for a basic state machine.
|
||||||
|
##
|
||||||
|
## @WIP
|
||||||
|
|
||||||
|
|
||||||
|
export var animation_name: String
|
||||||
|
export var move_speed: float = 60
|
||||||
|
export var timeout_seconds: float = 0.0
|
||||||
|
|
||||||
|
export(Array, String) var animation_sequence
|
||||||
|
export(Array, NodePath) var transition_state_nodes
|
||||||
|
var animation_index: int = 0
|
||||||
|
var current_animation_sequence: int = 0
|
||||||
|
|
||||||
|
var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity")
|
||||||
|
|
||||||
|
#var animation_sequence_timer: Timer
|
||||||
|
|
||||||
|
var state_timeout: Timer
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
state_timeout = Timer.new()
|
||||||
|
state_timeout.wait_time = timeout_seconds
|
||||||
|
state_timeout.one_shot = true
|
||||||
|
state_timeout.autostart = false
|
||||||
|
add_child(state_timeout)
|
||||||
|
|
||||||
|
func _update():
|
||||||
|
pass
|
||||||
Loading…
Reference in New Issue
Block a user