diff --git a/project.godot b/project.godot index e4143b1..705ab8c 100644 --- a/project.godot +++ b/project.godot @@ -13,9 +13,15 @@ _global_script_classes=[ { "class": "Actor", "language": "GDScript", "path": "res://src/Actor/Actor.gd" +}, { +"base": "Node", +"class": "StateMachine", +"language": "GDScript", +"path": "res://src/StateMachines/StateMachine.gd" } ] _global_script_class_icons={ -"Actor": "" +"Actor": "", +"StateMachine": "" } [application] diff --git a/src/Actor/Blobby.gd b/src/Actor/Blobby.gd index 4547714..f5e2df8 100644 --- a/src/Actor/Blobby.gd +++ b/src/Actor/Blobby.gd @@ -2,24 +2,38 @@ extends Actor export var stomp_impulse: = 1000.0 + func _on_EnemyDetector_area_entered(area: Area2D) -> void: - _velocity = calculate_stomp_velocity(_velocity, stomp_impulse) + _velocity = calculate_stomp_velocity(_velocity, stomp_impulse) + func _on_EnemyDetector_body_entered(body: Node) -> void: die() + func _physics_process(delta: float) -> void: var is_jump_interrupted: = Input.is_action_just_released("jump") and _velocity.y < 0.0 var direction: = get_direction() _velocity = calculate_move_velocity(_velocity, speed, direction, is_jump_interrupted) _velocity = move_and_slide(_velocity, FLOOR_NORMAL) + func get_direction() -> Vector2: return Vector2( Input.get_action_strength("move_right") - Input.get_action_strength("move_left"), -1.0 if Input.is_action_just_pressed("jump") and is_on_floor() else 1.0 ) + +func handle_move_input(): + return null + + +func apply_gravity(delta, velocity:Vector2): + velocity.y += gravity * delta + return velocity + + func calculate_move_velocity( linear_velocity: Vector2, speed: Vector2, @@ -28,13 +42,14 @@ func calculate_move_velocity( ) -> Vector2: var out: = linear_velocity out.x = speed.x * direction.x - out.y += gravity * get_physics_process_delta_time() + out = apply_gravity(get_physics_process_delta_time(), out) if direction.y == -1: out.y = speed.y * direction.y if is_jump_interrupted: out.y = 0 return out + func calculate_stomp_velocity(linear_velocity: Vector2, impulse: float) -> Vector2: var out: = linear_velocity out.y = -impulse diff --git a/src/Actor/PlayerStateMachine.gd b/src/Actor/PlayerStateMachine.gd new file mode 100644 index 0000000..4e2963f --- /dev/null +++ b/src/Actor/PlayerStateMachine.gd @@ -0,0 +1,22 @@ +extends StateMachine + +func _ready(): + add_state("idle") + add_state("run") + add_state("jump") + add_state("fall") + call_deferred("set_state", states.idle) + +func _state_logic(delta): + parent.handle_move_input() + parent.apply_gravity(delta) + parent.apply_movement() + +func _get_transition(delta): + return null + +func _enter_state(new_state, old_state): + pass + +func _exit_state(old_state, new_state): + pass \ No newline at end of file diff --git a/src/RayCaster.gd b/src/RayCaster.gd new file mode 100644 index 0000000..22a6218 --- /dev/null +++ b/src/RayCaster.gd @@ -0,0 +1,57 @@ +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) + diff --git a/src/StateMachines/StateMachine.gd b/src/StateMachines/StateMachine.gd index afcc8ad..7733240 100644 --- a/src/StateMachines/StateMachine.gd +++ b/src/StateMachines/StateMachine.gd @@ -1,8 +1,8 @@ extends Node -class_name StateMachine - +class_name StateMachine + var state = null setget set_state -var previous_state = null +var previous_state = null var states = {} onready var parent = get_parent() @@ -36,4 +36,4 @@ func set_state(new_state): _enter_state(new_state, previous_state) func add_state(state_name): - states[states.size()] = state_name \ No newline at end of file + states[states.size()] = state_name