Просмотр исходного кода

Update Finite State Machine demo

Aaron Franke 5 лет назад
Родитель
Сommit
9975c95065
25 измененных файлов с 163 добавлено и 146 удалено
  1. 4 4
      2d/finite_state_machine/Demo.tscn
  2. 3 3
      2d/finite_state_machine/debug/ControlsPanel.tscn
  3. 3 4
      2d/finite_state_machine/debug/states_stack_displayer.gd
  4. 0 2
      2d/finite_state_machine/player/Player.tscn
  5. 0 1
      2d/finite_state_machine/player/bullet/Bullet.tscn
  6. 4 6
      2d/finite_state_machine/player/bullet/bullet.gd
  7. 1 0
      2d/finite_state_machine/player/bullet/bullet_spawner.gd
  8. 8 8
      2d/finite_state_machine/player/player_controller.gd
  9. 5 7
      2d/finite_state_machine/player/player_state_machine.gd
  10. 1 0
      2d/finite_state_machine/player/states/combat/attack.gd
  11. 4 7
      2d/finite_state_machine/player/states/combat/stagger.gd
  12. 3 1
      2d/finite_state_machine/player/states/debug/state_name_displayer.gd
  13. 3 3
      2d/finite_state_machine/player/states/die.gd
  14. 10 13
      2d/finite_state_machine/player/states/motion/in_air/jump.gd
  15. 5 3
      2d/finite_state_machine/player/states/motion/motion.gd
  16. 3 1
      2d/finite_state_machine/player/states/motion/on_ground/idle.gd
  17. 8 5
      2d/finite_state_machine/player/states/motion/on_ground/move.gd
  18. 1 0
      2d/finite_state_machine/player/states/motion/on_ground/on_ground.gd
  19. 1 2
      2d/finite_state_machine/player/weapon/Sword.tscn
  20. 45 34
      2d/finite_state_machine/player/weapon/sword.gd
  21. 4 2
      2d/finite_state_machine/player/weapon/weapon_pivot.gd
  22. 8 2
      2d/finite_state_machine/project.godot
  23. 18 15
      2d/finite_state_machine/state_machine/state.gd
  24. 21 19
      2d/finite_state_machine/state_machine/state_machine.gd
  25. 0 4
      3d/platformer/stage.tscn

+ 4 - 4
2d/finite_state_machine/Demo.tscn

@@ -1,13 +1,13 @@
 [gd_scene load_steps=5 format=2]
 
-[ext_resource path="res://debug/ControlsPanel.tscn" type="PackedScene" id=1]
+[ext_resource path="res://player/Player.tscn" type="PackedScene" id=1]
 [ext_resource path="res://debug/Explanations.tscn" type="PackedScene" id=2]
 [ext_resource path="res://debug/StatesStackDiplayer.tscn" type="PackedScene" id=3]
-[ext_resource path="res://player/Player.tscn" type="PackedScene" id=4]
+[ext_resource path="res://debug/ControlsPanel.tscn" type="PackedScene" id=4]
 
 [node name="Demo" type="Node"]
 
-[node name="Player" parent="." instance=ExtResource( 4 )]
+[node name="Player" parent="." instance=ExtResource( 1 )]
 
 [node name="Explanations" parent="." instance=ExtResource( 2 )]
 
@@ -20,6 +20,6 @@ __meta__ = {
 
 [node name="StatesStackDiplayer" parent="Control" instance=ExtResource( 3 )]
 
-[node name="ControlsPanel" parent="Control" instance=ExtResource( 1 )]
+[node name="ControlsPanel" parent="Control" instance=ExtResource( 4 )]
 
 [editable path="Player"]

+ 3 - 3
2d/finite_state_machine/debug/ControlsPanel.tscn

@@ -1,6 +1,6 @@
 [gd_scene load_steps=2 format=2]
 
-[ext_resource path="res://fonts/source_code_pro_explanations.tres" type="DynamicFont" id=2]
+[ext_resource path="res://fonts/source_code_pro_explanations.tres" type="DynamicFont" id=1]
 
 [node name="ControlsPanel" type="Panel"]
 anchor_left = 1.0
@@ -18,7 +18,7 @@ margin_left = 10.0
 margin_top = 10.0
 margin_right = -10.0
 margin_bottom = -10.0
-custom_fonts/font = ExtResource( 2 )
+custom_fonts/font = ExtResource( 1 )
 text = "Shoot:
 Attack:
 Stagger:
@@ -32,7 +32,7 @@ margin_left = 10.0
 margin_top = 10.0
 margin_right = -10.0
 margin_bottom = -10.0
-custom_fonts/font = ExtResource( 2 )
+custom_fonts/font = ExtResource( 1 )
 text = "R
 F
 X

+ 3 - 4
2d/finite_state_machine/debug/states_stack_displayer.gd

@@ -2,14 +2,13 @@ extends Panel
 
 onready var fsm_node = get_node("../../Player/StateMachine")
 
-func _process(delta):
-	var states_names = ''
-	var numbers = ''
+func _process(_delta):
+	var states_names = ""
+	var numbers = ""
 	var index = 0
 	for state in fsm_node.states_stack:
 		states_names += state.get_name() + '\n'
 		numbers += str(index) + '\n'
 		index += 1
-
 	$States.text = states_names
 	$Numbers.text = numbers

+ 0 - 2
2d/finite_state_machine/player/Player.tscn

@@ -49,7 +49,6 @@ __meta__ = {
 
 [node name="StateMachine" type="Node" parent="."]
 script = ExtResource( 2 )
-START_STATE = NodePath("Idle")
 
 [node name="Idle" type="Node" parent="StateMachine"]
 script = ExtResource( 3 )
@@ -116,7 +115,6 @@ align = 1
 valign = 1
 uppercase = true
 script = ExtResource( 15 )
-
 [connection signal="state_changed" from="StateMachine" to="BodyPivot/WeaponPivot/Offset/Sword" method="_on_StateMachine_state_changed"]
 [connection signal="state_changed" from="StateMachine" to="StateNameDisplayer" method="_on_StateMachine_state_changed"]
 [connection signal="animation_finished" from="AnimationPlayer" to="StateMachine" method="_on_animation_finished"]

+ 0 - 1
2d/finite_state_machine/player/bullet/Bullet.tscn

@@ -12,4 +12,3 @@ script = ExtResource( 1 )
 
 [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
 shape = SubResource( 1 )
-

+ 4 - 6
2d/finite_state_machine/player/bullet/bullet.gd

@@ -1,9 +1,7 @@
 extends KinematicBody2D
 
-
 var direction = Vector2()
-export(float) var SPEED = 1000.0
-
+export(float) var speed = 1000.0
 
 func _ready():
 	set_as_toplevel(true)
@@ -13,7 +11,7 @@ func _physics_process(delta):
 	if is_outside_view_bounds():
 		queue_free()
 
-	var motion = direction * SPEED * delta
+	var motion = direction * speed * delta
 	var collision_info = move_and_collide(motion)
 	if collision_info:
 		queue_free()
@@ -21,8 +19,8 @@ func _physics_process(delta):
 
 func is_outside_view_bounds():
 	return position.x > OS.get_screen_size().x or position.x < 0.0 \
-		or position.y > OS.get_screen_size().y or position.y < 0.0
+			or position.y > OS.get_screen_size().y or position.y < 0.0
 
 
 func _draw():
-	draw_circle(Vector2(), $CollisionShape2D.shape.radius, Color('#ffffff'))
+	draw_circle(Vector2(), $CollisionShape2D.shape.radius, Color.white)

+ 1 - 0
2d/finite_state_machine/player/bullet/bullet_spawner.gd

@@ -6,6 +6,7 @@ func _input(event):
 	if event.is_action_pressed("fire"):
 		fire(owner.look_direction)
 
+
 func fire(direction):
 	if not $CooldownTimer.is_stopped():
 		return

+ 8 - 8
2d/finite_state_machine/player/player_controller.gd

@@ -1,25 +1,25 @@
-"""
-The Player is a KinematicBody2D, in other words a physics-driven object.
-It can move, collide with the world...
-It HAS a state machine, but the body and the state machine are separate.
-"""
 extends KinematicBody2D
+# The Player is a KinematicBody2D, in other words a physics-driven object.
+# It can move, collide with the world, etc...
+# The player has a state machine, but the body and the state machine are separate.
 
 signal direction_changed(new_direction)
 
-var look_direction = Vector2(1, 0) setget set_look_direction
+var look_direction = Vector2.RIGHT setget set_look_direction
 
-func take_damage(attacker, amount, effect=null):
-	if self.is_a_parent_of(attacker):
+func take_damage(attacker, amount, effect = null):
+	if is_a_parent_of(attacker):
 		return
 	$States/Stagger.knockback_direction = (attacker.global_position - global_position).normalized()
 	$Health.take_damage(amount, effect)
 
+
 func set_dead(value):
 	set_process_input(not value)
 	set_physics_process(not value)
 	$CollisionPolygon2D.disabled = value
 
+
 func set_look_direction(value):
 	look_direction = value
 	emit_signal("direction_changed", value)

+ 5 - 7
2d/finite_state_machine/player/player_state_machine.gd

@@ -9,10 +9,9 @@ func _ready():
 		"attack": $Attack,
 	}
 
+
 func _change_state(state_name):
-	"""
-	The base state_machine interface this node extends does most of the work
-	"""
+	# The base state_machine interface this node extends does most of the work.
 	if not _active:
 		return
 	if state_name in ["stagger", "jump", "attack"]:
@@ -21,11 +20,10 @@ func _change_state(state_name):
 		$Jump.initialize($Move.speed, $Move.velocity)
 	._change_state(state_name)
 
+
 func _input(event):
-	"""
-	Here we only handle input that can interrupt states, attacking in this case
-	otherwise we let the state node handle it
-	"""
+	# Here we only handle input that can interrupt states, attacking in this case,
+	# otherwise we let the state node handle it.
 	if event.is_action_pressed("attack"):
 		if current_state in [$Attack, $Stagger]:
 			return

+ 1 - 0
2d/finite_state_machine/player/states/combat/attack.gd

@@ -3,5 +3,6 @@ extends "res://state_machine/state.gd"
 func enter():
 	owner.get_node("AnimationPlayer").play("idle")
 
+
 func _on_Sword_attack_finished():
 	emit_signal("finished", "previous")

+ 4 - 7
2d/finite_state_machine/player/states/combat/stagger.gd

@@ -1,15 +1,12 @@
-"""
-The stagger state end with the stagger animation from the AnimationPlayer
-The animation only affects the Body Sprite's modulate property so
-it could stack with other animations if we had two AnimationPlayer nodes
-"""
 extends "res://state_machine/state.gd"
-
-var knockback_direction = Vector2()
+# The stagger state end with the stagger animation from the AnimationPlayer.
+# The animation only affects the Body Sprite's modulate property so it
+# could stack with other animations if we had two AnimationPlayer nodes.
 
 func enter():
 	owner.get_node("AnimationPlayer").play("stagger")
 
+
 func _on_animation_finished(anim_name):
 	assert(anim_name == "stagger")
 	emit_signal("finished", "previous")

+ 3 - 1
2d/finite_state_machine/player/states/debug/state_name_displayer.gd

@@ -5,8 +5,10 @@ var start_position = Vector2()
 func _ready():
 	start_position = rect_position
 
-func _physics_process(delta):
+
+func _physics_process(_delta):
 	rect_position = $"../BodyPivot".position + start_position
 
+
 func _on_StateMachine_state_changed(current_state):
 	text = current_state.get_name()

+ 3 - 3
2d/finite_state_machine/player/states/die.gd

@@ -1,10 +1,10 @@
 extends "res://state_machine/state.gd"
 
-
-# Initialize the state. E.g. change the animation
+# Initialize the state. E.g. change the animation.
 func enter():
 	owner.set_dead(true)
 	owner.get_node("AnimationPlayer").play("die")
 
-func _on_animation_finished(anim_name):
+
+func _on_animation_finished(_anim_name):
 	emit_signal("finished", "dead")

+ 10 - 13
2d/finite_state_machine/player/states/motion/in_air/jump.gd

@@ -1,15 +1,12 @@
 extends "../motion.gd"
 
-export(float) var BASE_MAX_HORIZONTAL_SPEED = 400.0
+export(float) var base_max_horizontal_speed = 400.0
 
-export(float) var AIR_ACCELERATION = 1000.0
-export(float) var AIR_DECCELERATION = 2000.0
-export(float) var AIR_STEERING_POWER = 50.0
+export(float) var air_acceleration = 1000.0
+export(float) var air_deceleration = 2000.0
+export(float) var air_steering_power = 50.0
 
-export(float) var JUMP_HEIGHT = 120.0
-export(float) var JUMP_DURATION = 0.8
-
-export(float) var GRAVITY = 1600.0
+export(float) var gravity = 1600.0
 
 var enter_velocity = Vector2()
 
@@ -22,7 +19,7 @@ var height = 0.0
 
 func initialize(speed, velocity):
 	horizontal_speed = speed
-	max_horizontal_speed = speed if speed > 0.0 else BASE_MAX_HORIZONTAL_SPEED
+	max_horizontal_speed = speed if speed > 0.0 else base_max_horizontal_speed
 	enter_velocity = velocity
 
 func enter():
@@ -45,19 +42,19 @@ func update(delta):
 
 func move_horizontally(delta, direction):
 	if direction:
-		horizontal_speed += AIR_ACCELERATION * delta
+		horizontal_speed += air_acceleration * delta
 	else:
-		horizontal_speed -= AIR_DECCELERATION * delta
+		horizontal_speed -= air_deceleration * delta
 	horizontal_speed = clamp(horizontal_speed, 0, max_horizontal_speed)
 
 	var target_velocity = horizontal_speed * direction.normalized()
-	var steering_velocity = (target_velocity - horizontal_velocity).normalized() * AIR_STEERING_POWER
+	var steering_velocity = (target_velocity - horizontal_velocity).normalized() * air_steering_power
 	horizontal_velocity += steering_velocity
 
 	owner.move_and_slide(horizontal_velocity)
 
 func animate_jump_height(delta):
-	vertical_speed -= GRAVITY * delta
+	vertical_speed -= gravity * delta
 	height += vertical_speed * delta
 	height = max(0.0, height)
 

+ 5 - 3
2d/finite_state_machine/player/states/motion/motion.gd

@@ -1,16 +1,18 @@
-# Collection of important methods to handle direction and animation
 extends "res://state_machine/state.gd"
+# Collection of important methods to handle direction and animation.
 
 func handle_input(event):
 	if event.is_action_pressed("simulate_damage"):
 		emit_signal("finished", "stagger")
 
+
 func get_input_direction():
 	var input_direction = Vector2()
-	input_direction.x = int(Input.is_action_pressed("move_right")) - int(Input.is_action_pressed("move_left"))
-	input_direction.y = int(Input.is_action_pressed("move_down")) - int(Input.is_action_pressed("move_up"))
+	input_direction.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
+	input_direction.y = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
 	return input_direction
 
+
 func update_look_direction(direction):
 	if direction and owner.look_direction != direction:
 		owner.look_direction = direction

+ 3 - 1
2d/finite_state_machine/player/states/motion/on_ground/idle.gd

@@ -3,10 +3,12 @@ extends "on_ground.gd"
 func enter():
 	owner.get_node("AnimationPlayer").play("idle")
 
+
 func handle_input(event):
 	return .handle_input(event)
 
-func update(delta):
+
+func update(_delta):
 	var input_direction = get_input_direction()
 	if input_direction:
 		emit_signal("finished", "move")

+ 8 - 5
2d/finite_state_machine/player/states/motion/on_ground/move.gd

@@ -1,7 +1,7 @@
 extends "on_ground.gd"
 
-export(float) var MAX_WALK_SPEED = 450
-export(float) var MAX_RUN_SPEED = 700
+export(float) var max_walk_speed = 450
+export(float) var max_run_speed = 700
 
 func enter():
 	speed = 0.0
@@ -11,22 +11,25 @@ func enter():
 	update_look_direction(input_direction)
 	owner.get_node("AnimationPlayer").play("walk")
 
+
 func handle_input(event):
 	return .handle_input(event)
 
-func update(delta):
+
+func update(_delta):
 	var input_direction = get_input_direction()
 	if not input_direction:
 		emit_signal("finished", "idle")
 	update_look_direction(input_direction)
 
-	speed = MAX_RUN_SPEED if Input.is_action_pressed("run") else MAX_WALK_SPEED
+	speed = max_run_speed if Input.is_action_pressed("run") else max_walk_speed
 	var collision_info = move(speed, input_direction)
 	if not collision_info:
 		return
-	if speed == MAX_RUN_SPEED and collision_info.collider.is_in_group("environment"):
+	if speed == max_run_speed and collision_info.collider.is_in_group("environment"):
 		return null
 
+
 func move(speed, direction):
 	velocity = direction.normalized() * speed
 	owner.move_and_slide(velocity, Vector2(), 5, 2)

+ 1 - 0
2d/finite_state_machine/player/states/motion/on_ground/on_ground.gd

@@ -1,5 +1,6 @@
 extends "../motion.gd"
 
+# warning-ignore-all:unused_class_variable
 var speed = 0.0
 var velocity = Vector2()
 

+ 1 - 2
2d/finite_state_machine/player/weapon/Sword.tscn

@@ -234,11 +234,10 @@ anims/attack_fast = SubResource( 3 )
 anims/attack_medium = SubResource( 4 )
 anims/idle = SubResource( 5 )
 
-[node name="sword" type="Sprite" parent="."]
+[node name="Sword" type="Sprite" parent="."]
 position = Vector2( 4, 0 )
 texture = ExtResource( 2 )
 offset = Vector2( 67, 0 )
 
 [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
 polygon = PoolVector2Array( 28.0001, -15.9999, 136, -15.9995, 160, 0, 136, 16.0005, 27.9999, 16.0001 )
-

+ 45 - 34
2d/finite_state_machine/player/weapon/sword.gd

@@ -2,101 +2,112 @@ extends Area2D
 
 signal attack_finished
 
-enum STATES { IDLE, ATTACK }
+enum States { IDLE, ATTACK }
 var state = null
 
-enum ATTACK_INPUT_STATES { IDLE, LISTENING, REGISTERED }
-var attack_input_state = ATTACK_INPUT_STATES.IDLE
+enum AttackInputStates { IDLE, LISTENING, REGISTERED }
+var attack_input_state = AttackInputStates.IDLE
 var ready_for_next_attack = false
 const MAX_COMBO_COUNT = 3
 var combo_count = 0
 
 var attack_current = {}
 var combo = [{
-		'damage': 1,
-		'animation': 'attack_fast',
-		'effect': null
+		"damage": 1,
+		"animation": "attack_fast",
+		"effect": null
 	},
 	{
-		'damage': 1,
-		'animation': 'attack_fast',
-		'effect': null
+		"damage": 1,
+		"animation": "attack_fast",
+		"effect": null
 	},
 	{
-		'damage': 3,
-		'animation': 'attack_medium',
-		'effect': null
+		"damage": 3,
+		"animation": "attack_medium",
+		"effect": null
 	}]
 
 var hit_objects = []
 
 func _ready():
-	$AnimationPlayer.connect('animation_finished', self, "_on_animation_finished")
+	# warning-ignore:return_value_discarded
+	$AnimationPlayer.connect("animation_finished", self, "_on_animation_finished")
+	# warning-ignore:return_value_discarded
 	self.connect("body_entered", self, "_on_body_entered")
-	_change_state(STATES.IDLE)
+	_change_state(States.IDLE)
+
 
 func _change_state(new_state):
 	match state:
-		STATES.ATTACK:
+		States.ATTACK:
 			hit_objects = []
-			attack_input_state = ATTACK_INPUT_STATES.LISTENING
+			attack_input_state = AttackInputStates.LISTENING
 			ready_for_next_attack = false
 
 	match new_state:
-		STATES.IDLE:
+		States.IDLE:
 			combo_count = 0
 			$AnimationPlayer.stop()
 			visible = false
 			monitoring = false
-		STATES.ATTACK:
+		States.ATTACK:
 			attack_current = combo[combo_count -1]
-			$AnimationPlayer.play(attack_current['animation'])
+			$AnimationPlayer.play(attack_current["animation"])
 			visible = true
 			monitoring = true
 	state = new_state
 
+
 func _input(event):
-	if not state == STATES.ATTACK:
+	if not state == States.ATTACK:
 		return
-	if attack_input_state != ATTACK_INPUT_STATES.LISTENING:
+	if attack_input_state != AttackInputStates.LISTENING:
 		return
-	if event.is_action_pressed('attack'):
-		attack_input_state = ATTACK_INPUT_STATES.REGISTERED
+	if event.is_action_pressed("attack"):
+		attack_input_state = AttackInputStates.REGISTERED
+
 
-func _physics_process(delta):
-	if attack_input_state == ATTACK_INPUT_STATES.REGISTERED and ready_for_next_attack:
+func _physics_process(_delta):
+	if attack_input_state == AttackInputStates.REGISTERED and ready_for_next_attack:
 		attack()
 
+
 func attack():
 	combo_count += 1
-	_change_state(STATES.ATTACK)
+	_change_state(States.ATTACK)
+
 
-# use with AnimationPlayer func track
+# Use with AnimationPlayer func track.
 func set_attack_input_listening():
-	attack_input_state = ATTACK_INPUT_STATES.LISTENING
+	attack_input_state = AttackInputStates.LISTENING
 
-# use with AnimationPlayer func track
+
+# Use with AnimationPlayer func track.
 func set_ready_for_next_attack():
 	ready_for_next_attack = true
 
+
 func _on_body_entered(body):
-	if not body.has_node('Health'):
+	if not body.has_node("Health"):
 		return
 	if body.get_rid().get_id() in hit_objects:
 		return
 	hit_objects.append(body.get_rid().get_id())
-	body.take_damage(self, attack_current['damage'], attack_current['effect'])
+	body.take_damage(self, attack_current["damage"], attack_current["effect"])
 
-func _on_animation_finished(name):
+
+func _on_animation_finished(_name):
 	if not attack_current:
 		return
 
-	if attack_input_state == ATTACK_INPUT_STATES.REGISTERED and combo_count < MAX_COMBO_COUNT:
+	if attack_input_state == AttackInputStates.REGISTERED and combo_count < MAX_COMBO_COUNT:
 		attack()
 	else:
-		_change_state(STATES.IDLE)
+		_change_state(States.IDLE)
 		emit_signal("attack_finished")
 
+
 func _on_StateMachine_state_changed(current_state):
 	if current_state.name == "Attack":
 		attack()

+ 4 - 2
2d/finite_state_machine/player/weapon/weapon_pivot.gd

@@ -3,13 +3,15 @@ extends Position2D
 var z_index_start = 0
 
 func _ready():
-	owner.connect("direction_changed", self, '_on_Parent_direction_changed')
+	#warning-ignore:return_value_discarded
+	owner.connect("direction_changed", self, "_on_Parent_direction_changed")
 	z_index_start = z_index
 
+
 func _on_Parent_direction_changed(direction):
 	rotation = direction.angle()
 	match direction:
-		Vector2(0, -1):
+		Vector2.UP:
 			z_index = z_index_start - 1
 		_:
 			z_index = z_index_start

+ 8 - 2
2d/finite_state_machine/project.godot

@@ -37,6 +37,7 @@ move_left={
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
 , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
 , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
  ]
 }
 move_up={
@@ -44,6 +45,7 @@ move_up={
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
 , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
 , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
  ]
 }
 move_right={
@@ -51,6 +53,7 @@ move_right={
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
 , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
 , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
  ]
 }
 move_down={
@@ -58,18 +61,19 @@ move_down={
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
 , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
 , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
  ]
 }
 fire={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"unicode":0,"echo":false,"script":null)
-, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":7,"pressure":0.0,"pressed":false,"script":null)
  ]
 }
 run={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777237,"unicode":0,"echo":false,"script":null)
-, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":7,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
  ]
 }
 jump={
@@ -81,11 +85,13 @@ jump={
 simulate_damage={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":88,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":3,"pressure":0.0,"pressed":false,"script":null)
  ]
 }
 attack={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":70,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":6,"pressure":0.0,"pressed":false,"script":null)
  ]
 }
 

+ 18 - 15
2d/finite_state_machine/state_machine/state.gd

@@ -1,25 +1,28 @@
-"""
-Base interface for all states: it doesn't do anything in itself
-but forces us to pass the right arguments to the methods below
-and makes sure every State object had all of these methods.
-"""
 extends Node
+# Base interface for all states: it doesn't do anything by itself,
+# but forces us to pass the right arguments to the methods below
+# and makes sure every State object had all of these methods.
 
+# warning-ignore:unused_signal
 signal finished(next_state_name)
 
-# Initialize the state. E.g. change the animation
+# Initialize the state. E.g. change the animation.
 func enter():
-	return
+	pass
 
-# Clean up the state. Reinitialize values like a timer
+
+# Clean up the state. Reinitialize values like a timer.
 func exit():
-	return
+	pass
+
+
+func handle_input(_event):
+	pass
+
 
-func handle_input(event):
-	return
+func update(_delta):
+	pass
 
-func update(delta):
-	return
 
-func _on_animation_finished(anim_name):
-	return
+func _on_animation_finished(_anim_name):
+	pass

+ 21 - 19
2d/finite_state_machine/state_machine/state_machine.gd

@@ -1,21 +1,17 @@
-"""
-Base interface for a generic state machine
-It handles initializing, setting the machine active or not
-delegating _physics_process, _input calls to the State nodes,
-and changing the current/active state.
-See the PlayerV2 scene for an example on how to use it
-"""
 extends Node
+# Base interface for a generic state machine.
+# It handles initializing, setting the machine active or not
+# delegating _physics_process, _input calls to the State nodes,
+# and changing the current/active state.
+# See the PlayerV2 scene for an example on how to use it.
 
 signal state_changed(current_state)
 
-"""
-You must set a starting node from the inspector or on
-the node that inherits from this state machine interface
-If you don't the game will crash (on purpose, so you won't 
-forget to initialize the state machine)
-"""
-export(NodePath) var START_STATE
+# You must set a starting node from the inspector or on
+# the node that inherits from this state machine interface.
+# If you don't the game will crash (on purpose, so you won't
+# forget to initialize the state machine).
+export(NodePath) var start_state
 var states_map = {}
 
 var states_stack = []
@@ -23,18 +19,20 @@ var current_state = null
 var _active = false setget set_active
 
 func _ready():
-	if not START_STATE:
-		START_STATE = get_child(0).get_path()
+	if not start_state:
+		start_state = get_child(0).get_path()
 	for child in get_children():
 		child.connect("finished", self, "_change_state")
-	initialize(START_STATE)
+	initialize(start_state)
 
-func initialize(start_state):
+
+func initialize(initial_state):
 	set_active(true)
-	states_stack.push_front(get_node(start_state))
+	states_stack.push_front(get_node(initial_state))
 	current_state = states_stack[0]
 	current_state.enter()
 
+
 func set_active(value):
 	_active = value
 	set_physics_process(value)
@@ -43,17 +41,21 @@ func set_active(value):
 		states_stack = []
 		current_state = null
 
+
 func _input(event):
 	current_state.handle_input(event)
 
+
 func _physics_process(delta):
 	current_state.update(delta)
 
+
 func _on_animation_finished(anim_name):
 	if not _active:
 		return
 	current_state._on_animation_finished(anim_name)
 
+
 func _change_state(state_name):
 	if not _active:
 		return

+ 0 - 4
3d/platformer/stage.tscn

@@ -74,7 +74,6 @@ directional_shadow_normal_bias = 0.1
 environment = SubResource( 2 )
 
 [node name="Coins" type="Node" parent="."]
-editor/display_folded = true
 
 [node name="coin" parent="Coins" instance=ExtResource( 3 )]
 transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 18.5311, 2.85075, 5.24675 )
@@ -278,7 +277,6 @@ interior_enable = true
 interior_ambient_color = Color( 0.403137, 0.55498, 0.884824, 1 )
 
 [node name="SoundArea1" type="Area" parent="."]
-editor/display_folded = true
 reverb_bus_enable = true
 reverb_bus_name = "Reverb Large"
 reverb_bus_amount = 0.26
@@ -289,7 +287,6 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 14.7075, 5.19958, 9.21556 )
 shape = SubResource( 7 )
 
 [node name="SoundArea2" type="Area" parent="."]
-editor/display_folded = true
 transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 27.1673, 0, 0 )
 reverb_bus_enable = true
 reverb_bus_name = "Reverb Small"
@@ -301,7 +298,6 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 8.29529, 5.19958, 15.9933 )
 shape = SubResource( 8 )
 
 [node name="SoundArea3" type="Area" parent="."]
-editor/display_folded = true
 reverb_bus_enable = true
 reverb_bus_name = "Reverb Large"
 reverb_bus_amount = 0.26