Player Movement intiated via the PlayerStateMachine
This commit is contained in:
parent
6500d525cd
commit
67f2466f8c
18
.vscode/launch.json
vendored
Normal file
18
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "GDScript Godot",
|
||||||
|
"type": "godot",
|
||||||
|
"request": "launch",
|
||||||
|
"project": "${workspaceFolder}",
|
||||||
|
"port": 6007,
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"launch_game_instance": true,
|
||||||
|
"launch_scene": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -14,6 +14,16 @@ _global_script_classes=[ {
|
|||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://src/Actor/Actor.gd"
|
"path": "res://src/Actor/Actor.gd"
|
||||||
}, {
|
}, {
|
||||||
|
"base": "Line2D",
|
||||||
|
"class": "RayCastDebugLines",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/RayCasters/RayCastDebugLines.gd"
|
||||||
|
}, {
|
||||||
|
"base": "Node2D",
|
||||||
|
"class": "RayCaster",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/RayCasters/RayCaster.gd"
|
||||||
|
}, {
|
||||||
"base": "Node",
|
"base": "Node",
|
||||||
"class": "StateMachine",
|
"class": "StateMachine",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
@ -21,6 +31,8 @@ _global_script_classes=[ {
|
|||||||
} ]
|
} ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
"Actor": "",
|
"Actor": "",
|
||||||
|
"RayCastDebugLines": "",
|
||||||
|
"RayCaster": "",
|
||||||
"StateMachine": ""
|
"StateMachine": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +46,10 @@ config/icon="res://icon.png"
|
|||||||
|
|
||||||
PlayerData="*res://src/Autoload/PlayerData.tscn"
|
PlayerData="*res://src/Autoload/PlayerData.tscn"
|
||||||
|
|
||||||
|
[debug]
|
||||||
|
|
||||||
|
settings/fps/force_fps=144
|
||||||
|
|
||||||
[display]
|
[display]
|
||||||
|
|
||||||
window/stretch/mode="2d"
|
window/stretch/mode="2d"
|
||||||
|
|||||||
@ -4,6 +4,6 @@ class_name Actor
|
|||||||
const FLOOR_NORMAL: = Vector2.UP
|
const FLOOR_NORMAL: = Vector2.UP
|
||||||
|
|
||||||
export var speed: = Vector2(300, 1000)
|
export var speed: = Vector2(300, 1000)
|
||||||
export var gravity: = 100.0
|
export var gravity: = 9800.0
|
||||||
|
|
||||||
var _velocity: = Vector2.ZERO
|
var _velocity: = Vector2.ZERO
|
||||||
@ -2,7 +2,7 @@ extends Actor
|
|||||||
|
|
||||||
export var stomp_impulse: = 1000.0
|
export var stomp_impulse: = 1000.0
|
||||||
|
|
||||||
|
# TODO Move events to StateMachine
|
||||||
func _on_EnemyDetector_area_entered(area: Area2D) -> void:
|
func _on_EnemyDetector_area_entered(area: Area2D) -> void:
|
||||||
_velocity = calculate_stomp_velocity(_velocity, stomp_impulse)
|
_velocity = calculate_stomp_velocity(_velocity, stomp_impulse)
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ func _on_EnemyDetector_body_entered(body: Node) -> void:
|
|||||||
die()
|
die()
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func apply_movement(delta: float) -> void:
|
||||||
var is_jump_interrupted: = Input.is_action_just_released("jump") and _velocity.y < 0.0
|
var is_jump_interrupted: = Input.is_action_just_released("jump") and _velocity.y < 0.0
|
||||||
var direction: = get_direction()
|
var direction: = get_direction()
|
||||||
_velocity = calculate_move_velocity(_velocity, speed, direction, is_jump_interrupted)
|
_velocity = calculate_move_velocity(_velocity, speed, direction, is_jump_interrupted)
|
||||||
@ -60,5 +60,3 @@ func die() -> void:
|
|||||||
queue_free()
|
queue_free()
|
||||||
PlayerData.deaths += 1
|
PlayerData.deaths += 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,30 +1,37 @@
|
|||||||
[gd_scene load_steps=5 format=2]
|
[gd_scene load_steps=8 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://start-assets/player.png" type="Texture" id=1]
|
[ext_resource path="res://start-assets/player.png" type="Texture" id=1]
|
||||||
[ext_resource path="res://src/Actor/Blobby.gd" type="Script" id=2]
|
[ext_resource path="res://src/Actor/PlayerStateMachine.gd" type="Script" id=2]
|
||||||
|
[ext_resource path="res://src/RayCasters/RayCaster.gd" type="Script" id=3]
|
||||||
|
[ext_resource path="res://src/RayCasters/RayCastDebugLines.gd" type="Script" id=4]
|
||||||
|
[ext_resource path="res://src/Actor/Blobby.gd" type="Script" id=5]
|
||||||
|
|
||||||
[sub_resource type="RectangleShape2D" id=1]
|
[sub_resource type="RectangleShape2D" id=1]
|
||||||
extents = Vector2( 4.85252, 5.80644 )
|
extents = Vector2( 30.8418, 32 )
|
||||||
|
|
||||||
[sub_resource type="RectangleShape2D" id=2]
|
[sub_resource type="RectangleShape2D" id=2]
|
||||||
extents = Vector2( 30.9321, 24.5597 )
|
extents = Vector2( 30.9321, 24.5597 )
|
||||||
|
|
||||||
[node name="Blobby" type="KinematicBody2D"]
|
[node name="Blobby" type="KinematicBody2D"]
|
||||||
collision_mask = 8
|
collision_mask = 8
|
||||||
script = ExtResource( 2 )
|
script = ExtResource( 5 )
|
||||||
speed = Vector2( 300, 3000 )
|
|
||||||
|
|
||||||
[node name="player" type="Sprite" parent="."]
|
[node name="player" type="Sprite" parent="."]
|
||||||
position = Vector2( 2.38419e-07, -31.3866 )
|
position = Vector2( 1.79366e-43, 5.72205e-06 )
|
||||||
scale = Vector2( 0.641109, 0.653888 )
|
scale = Vector2( 0.64, 0.64 )
|
||||||
texture = ExtResource( 1 )
|
texture = ExtResource( 1 )
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
position = Vector2( 1.05112, -31.5796 )
|
|
||||||
scale = Vector2( 5.68128, 5.29182 )
|
|
||||||
shape = SubResource( 1 )
|
shape = SubResource( 1 )
|
||||||
|
|
||||||
|
[node name="RayCaster" type="Node2D" parent="CollisionShape2D"]
|
||||||
|
script = ExtResource( 3 )
|
||||||
|
|
||||||
|
[node name="RayCastDebugLines" type="Line2D" parent="CollisionShape2D/RayCaster"]
|
||||||
|
script = ExtResource( 4 )
|
||||||
|
|
||||||
[node name="Camera2D" type="Camera2D" parent="."]
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
|
visible = false
|
||||||
position = Vector2( 0, -181 )
|
position = Vector2( 0, -181 )
|
||||||
current = true
|
current = true
|
||||||
limit_left = 0
|
limit_left = 0
|
||||||
@ -42,7 +49,9 @@ collision_mask = 2
|
|||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="EnemyDetector"]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="EnemyDetector"]
|
||||||
modulate = Color( 0.2, 0, 0.494118, 1 )
|
modulate = Color( 0.2, 0, 0.494118, 1 )
|
||||||
position = Vector2( -0.210228, -30.5284 )
|
|
||||||
shape = SubResource( 2 )
|
shape = SubResource( 2 )
|
||||||
|
|
||||||
|
[node name="StateMachine" type="Node" parent="."]
|
||||||
|
script = ExtResource( 2 )
|
||||||
[connection signal="area_entered" from="EnemyDetector" to="." method="_on_EnemyDetector_area_entered"]
|
[connection signal="area_entered" from="EnemyDetector" to="." method="_on_EnemyDetector_area_entered"]
|
||||||
[connection signal="body_entered" from="EnemyDetector" to="." method="_on_EnemyDetector_body_entered"]
|
[connection signal="body_entered" from="EnemyDetector" to="." method="_on_EnemyDetector_body_entered"]
|
||||||
|
|||||||
@ -1,22 +1,30 @@
|
|||||||
extends StateMachine
|
extends StateMachine
|
||||||
|
|
||||||
|
# Adds the intial states
|
||||||
func _ready():
|
func _ready():
|
||||||
add_state("idle")
|
add_state("idle")
|
||||||
add_state("run")
|
add_state("run")
|
||||||
add_state("jump")
|
add_state("jump")
|
||||||
add_state("fall")
|
add_state("fall")
|
||||||
call_deferred("set_state", states.idle)
|
print_debug(states)
|
||||||
|
set_state(states.idle);
|
||||||
|
|
||||||
|
|
||||||
|
# Calls the parent behaviours according to state
|
||||||
func _state_logic(delta):
|
func _state_logic(delta):
|
||||||
parent.handle_move_input()
|
parent.get_node("CollisionShape2D/RayCaster")._raycast(Vector2.DOWN, parent.get_node("CollisionShape2D").get_shape(), parent.collision_mask)
|
||||||
parent.apply_gravity(delta)
|
parent.apply_movement(delta)
|
||||||
parent.apply_movement()
|
|
||||||
|
|
||||||
|
|
||||||
|
# Determines which state should be active at the moment
|
||||||
func _get_transition(delta):
|
func _get_transition(delta):
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
|
||||||
|
|
||||||
func _enter_state(new_state, old_state):
|
func _enter_state(new_state, old_state):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
func _exit_state(old_state, new_state):
|
func _exit_state(old_state, new_state):
|
||||||
pass
|
pass
|
||||||
@ -39,8 +39,6 @@ tile_data = PoolIntArray( -1048576, 0, 0, -1048564, 0, 0, -983040, 0, 0, -983028
|
|||||||
|
|
||||||
[node name="Blobby" parent="." instance=ExtResource( 1 )]
|
[node name="Blobby" parent="." instance=ExtResource( 1 )]
|
||||||
position = Vector2( 131, 560 )
|
position = Vector2( 131, 560 )
|
||||||
speed = Vector2( 800, 1500 )
|
|
||||||
gravity = 4000.0
|
|
||||||
|
|
||||||
[node name="player" parent="Blobby" index="0"]
|
[node name="player" parent="Blobby" index="0"]
|
||||||
position = Vector2( 0, -32 )
|
position = Vector2( 0, -32 )
|
||||||
|
|||||||
@ -64,8 +64,6 @@ tile_data = PoolIntArray( 0, 0, 0, 34, 0, 0, 35, 0, 0, 65536, 0, 0, 65570, 0, 0,
|
|||||||
|
|
||||||
[node name="Blobby" parent="." instance=ExtResource( 1 )]
|
[node name="Blobby" parent="." instance=ExtResource( 1 )]
|
||||||
position = Vector2( 131, 560 )
|
position = Vector2( 131, 560 )
|
||||||
speed = Vector2( 800, 3000 )
|
|
||||||
gravity = 4000.0
|
|
||||||
|
|
||||||
[node name="Camera2D" parent="Blobby" index="2"]
|
[node name="Camera2D" parent="Blobby" index="2"]
|
||||||
limit_top = 100000000
|
limit_top = 100000000
|
||||||
|
|||||||
@ -1,57 +0,0 @@
|
|||||||
extends Node2D
|
|
||||||
|
|
||||||
const UP = Vector2(0, -1)
|
|
||||||
const DOWN = Vector2(0, 1)
|
|
||||||
const LEFT = Vector2(-1, 0)
|
|
||||||
const RIGHT = Vector2(1, 0)
|
|
||||||
const SKIN_WIDTH = 1
|
|
||||||
|
|
||||||
export (int) var buffer_size = 3 setget _set_buffer_size
|
|
||||||
var buffer = []
|
|
||||||
|
|
||||||
func _raycast(direction, rect, mask, exceptions = [], ray_length = 16, buffer = self.buffer):
|
|
||||||
if !(direction == UP || direction == DOWN || direction == LEFT || direction == RIGHT):
|
|
||||||
return 0
|
|
||||||
|
|
||||||
var space_state = get_world_2d().direct_space_state
|
|
||||||
var extents = rect.extents - Vector2(SKIN_WIDTH, SKIN_WIDTH)
|
|
||||||
var count = 0
|
|
||||||
var ray_count = buffer.size()
|
|
||||||
var cast_to = (ray_length + SKIN_WIDTH) * direction
|
|
||||||
var origin
|
|
||||||
var spacing
|
|
||||||
|
|
||||||
if direction == UP || direction == DOWN:
|
|
||||||
spacing = extents.x * 2 / (ray_count - 1)
|
|
||||||
else:
|
|
||||||
spacing = extents.y * 2 / (ray_count - 1)
|
|
||||||
|
|
||||||
for i in range(ray_count):
|
|
||||||
if direction == UP || direction == DOWN:
|
|
||||||
origin = Vector2(-extents.x + spacing * i, extents.y)
|
|
||||||
if direction == UP:
|
|
||||||
origin.y = -origin.y
|
|
||||||
else:
|
|
||||||
origin = Vector2(extents.x, -extents.y + spacing * i)
|
|
||||||
if direction == UP:
|
|
||||||
origin.x = -origin.x
|
|
||||||
|
|
||||||
var result = space_state.intersect_ray(global_position + origin, global_position + origin + cast_to,
|
|
||||||
exceptions, mask)
|
|
||||||
if result:
|
|
||||||
buffer[count] = result
|
|
||||||
count += 1
|
|
||||||
return {buffer = buffer, count = count}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func _set_buffer_size(value):
|
|
||||||
buffer_size = max(value, 2)
|
|
||||||
buffer.resize(buffer_size)
|
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
|
||||||
func _ready():
|
|
||||||
_set_buffer_size(buffer_size)
|
|
||||||
|
|
||||||
25
src/RayCasters/RayCastDebugLines.gd
Normal file
25
src/RayCasters/RayCastDebugLines.gd
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
extends Line2D
|
||||||
|
class_name RayCastDebugLines
|
||||||
|
|
||||||
|
# Declare member variables here. Examples:
|
||||||
|
# var a: int = 2
|
||||||
|
# var b: String = "text"
|
||||||
|
var Lines = []
|
||||||
|
|
||||||
|
func add_line(origin, destination, color):
|
||||||
|
Lines.append([origin, destination, color])
|
||||||
|
|
||||||
|
func clear_lines():
|
||||||
|
Lines = []
|
||||||
|
|
||||||
|
func _draw():
|
||||||
|
for i in range(len(Lines)):
|
||||||
|
draw_line(Lines[i][0],Lines[i][1],Lines[i][2])
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
#func _process(delta: float) -> void:
|
||||||
|
# pass
|
||||||
73
src/RayCasters/RayCaster.gd
Normal file
73
src/RayCasters/RayCaster.gd
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
extends Node2D
|
||||||
|
class_name RayCaster
|
||||||
|
|
||||||
|
const UP = Vector2(0, -1)
|
||||||
|
const DOWN = Vector2(0, 1)
|
||||||
|
const LEFT = Vector2(-1, 0)
|
||||||
|
const RIGHT = Vector2(1, 0)
|
||||||
|
const SKIN_WIDTH = 0
|
||||||
|
|
||||||
|
export (int) var buffer_size = 10 setget _set_buffer_size
|
||||||
|
var buffer = []
|
||||||
|
|
||||||
|
# Casts Rays into a given direction.
|
||||||
|
# direction: 2D up, down, left or right vector
|
||||||
|
# rect: Shape of the node the raycaster is attached to
|
||||||
|
# mask: Collision layers
|
||||||
|
# exceptions: Excepted collision layers
|
||||||
|
# ray_length: Length of the rays
|
||||||
|
# ray_buffer: Array to which the rays get saved
|
||||||
|
func _raycast(direction, rect, mask, exceptions = [], ray_length = 16, ray_buffer = self.buffer):
|
||||||
|
if !(direction == UP || direction == DOWN || direction == LEFT || direction == RIGHT):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# TODO Manage debug options globally
|
||||||
|
self.get_child(0).clear_lines()
|
||||||
|
|
||||||
|
var space_state = get_world_2d().direct_space_state
|
||||||
|
var extents = rect.extents - Vector2(SKIN_WIDTH, SKIN_WIDTH)
|
||||||
|
var count = 0
|
||||||
|
var ray_count = ray_buffer.size()
|
||||||
|
var cast_to = (ray_length + SKIN_WIDTH) * direction
|
||||||
|
var origin
|
||||||
|
var spacing
|
||||||
|
|
||||||
|
if direction == UP || direction == DOWN:
|
||||||
|
spacing = extents.x * 2 / (ray_count - 1)
|
||||||
|
else:
|
||||||
|
spacing = extents.y * 2 / (ray_count - 1)
|
||||||
|
|
||||||
|
for i in range(ray_count):
|
||||||
|
if direction == UP || direction == DOWN:
|
||||||
|
origin = Vector2(-extents.x + spacing * i, extents.y)
|
||||||
|
if direction == UP:
|
||||||
|
origin.y = -origin.y
|
||||||
|
else:
|
||||||
|
# TODO Manage debug options globally
|
||||||
|
self.get_child(0).add_line(origin, Vector2(origin.x, origin.y + ray_length), Color( 1, 0, 0, 1 ))
|
||||||
|
else:
|
||||||
|
origin = Vector2(extents.x, -extents.y + spacing * i)
|
||||||
|
if direction == LEFT:
|
||||||
|
origin.x = -origin.x
|
||||||
|
else:
|
||||||
|
draw_line(origin, Vector2(origin.x + ray_length, origin.y), Color( 1, 0, 0, 1 ))
|
||||||
|
|
||||||
|
var result = space_state.intersect_ray(global_position + origin, global_position + origin + cast_to,
|
||||||
|
exceptions, mask)
|
||||||
|
if result:
|
||||||
|
ray_buffer[count] = result
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
self.get_child(0).update()
|
||||||
|
|
||||||
|
return {ray_buffer = ray_buffer, count = count}
|
||||||
|
|
||||||
|
|
||||||
|
func _set_buffer_size(value):
|
||||||
|
buffer_size = max(value, 2)
|
||||||
|
self.buffer.resize(buffer_size)
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready():
|
||||||
|
_set_buffer_size(buffer_size)
|
||||||
@ -19,6 +19,10 @@ __meta__ = {
|
|||||||
[node name="background" type="TextureRect" parent="."]
|
[node name="background" type="TextureRect" parent="."]
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
|
margin_left = -1.5874
|
||||||
|
margin_top = 3.96851
|
||||||
|
margin_right = -1.5874
|
||||||
|
margin_bottom = 3.96851
|
||||||
texture = ExtResource( 4 )
|
texture = ExtResource( 4 )
|
||||||
expand = true
|
expand = true
|
||||||
stretch_mode = 2
|
stretch_mode = 2
|
||||||
|
|||||||
@ -5,35 +5,38 @@ var state = null setget set_state
|
|||||||
var previous_state = null
|
var previous_state = null
|
||||||
var states = {}
|
var states = {}
|
||||||
|
|
||||||
|
# Parent Node that uses these states
|
||||||
onready var parent = get_parent()
|
onready var parent = get_parent()
|
||||||
|
|
||||||
|
# Basic process flow for every SM
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
if state != null:
|
if state != null:
|
||||||
_state_logic(delta)
|
_state_logic(delta)
|
||||||
var transition = _get_transition(delta)
|
var transition = _get_transition(delta)
|
||||||
if transition != null:
|
if transition != null:
|
||||||
set_state(transition)
|
set_state(transition)
|
||||||
|
|
||||||
|
# Game logic consequences of state
|
||||||
func _state_logic(_delta):
|
func _state_logic(_delta):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func _get_transition(_delta):
|
func _get_transition(_delta):
|
||||||
return null
|
return null
|
||||||
|
|
||||||
func _enter_state(_new_state, _previous_state):
|
func _enter_state(_new_state, _previous_state):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func _exit_state(_previous_state, _new_state):
|
func _exit_state(_previous_state, _new_state):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func set_state(new_state):
|
func set_state(new_state):
|
||||||
previous_state = state
|
previous_state = state
|
||||||
state = new_state
|
state = new_state
|
||||||
|
|
||||||
if previous_state != null:
|
if previous_state != null:
|
||||||
_exit_state(previous_state, new_state)
|
_exit_state(previous_state, new_state)
|
||||||
if new_state != null:
|
if new_state != null:
|
||||||
_enter_state(new_state, previous_state)
|
_enter_state(new_state, previous_state)
|
||||||
|
|
||||||
func add_state(state_name):
|
func add_state(state_name):
|
||||||
states[states.size()] = state_name
|
states[state_name] = state_name
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user