fix: code linting, duck walk state & sound

This commit is contained in:
Jakob Feldmann 2023-09-05 12:38:14 +02:00
parent 7d4e9346b0
commit cc75d5dc4a
43 changed files with 623 additions and 604 deletions

Binary file not shown.

View File

@ -12,4 +12,4 @@ dest_files=[ "res://.import/footsteps.ogg-db9696a28bb451faa0ab0d3414320fd1.oggst
[params] [params]
loop=true loop=true
loop_offset=0 loop_offset=0.0

View File

@ -1 +0,0 @@
soniss gdc pack, ryk-sound, no attribution needed

View File

@ -1,23 +0,0 @@
[remap]
importer="wav"
type="AudioStreamSample"
path="res://.import/grass 3 single step 3.wav-2f7d8073200559f99a8e0cf713050fbb.sample"
[deps]
source_file="res://assets/sounds/grass 3 single step 3.wav"
dest_files=[ "res://.import/grass 3 single step 3.wav-2f7d8073200559f99a8e0cf713050fbb.sample" ]
[params]
force/8_bit=false
force/mono=true
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=true
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=0

View File

@ -1,15 +1,15 @@
extends KinematicBody2D
class_name Actor class_name Actor
extends KinematicBody2D
#TODO Split the blobby specific parts up from this
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState")
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager")
const PhysicsConst = preload("res://src/Utilities/Physic/PhysicsConst.gd") const PhysicsConst = preload("res://src/Utilities/Physic/PhysicsConst.gd")
const FLOOR_NORMAL := Vector2.UP const FLOOR_NORMAL := Vector2.UP
# Mass of Blobby
# Kilograms
export var mass := 6.5
#TODO Split the blobby specific parts up from this
var stomp_feedback := 1400 * 30 var stomp_feedback := 1400 * 30
var stomp_time := 0.2 var stomp_time := 0.2
var init_stomp_time := 0.2 var init_stomp_time := 0.2
@ -20,32 +20,36 @@ var initial_velocity_dependence := 0.7
var floor_friction := base_floor_friction var floor_friction := base_floor_friction
# TODO Mixing Vectors and ints is questionable # TODO Mixing Vectors and ints is questionable
var max_velocity := { var max_velocity := {
"walk": 120, "run": 160, "jump": Vector2(120, 420), "fall": Vector2(120, 420), "walljump": 200, "idle": 12000, "duck": 160 "walk": 120,
"run": 160,
"jump": Vector2(120, 420),
"fall": Vector2(120, 420),
"walljump": 200,
"idle": 12000,
"duck": 160,
"duck_walk": 160
} }
var velocity_jump_boost_ratio := 10 var velocity_jump_boost_ratio := 10
# This is added to the acceleration force initially # This is added to the acceleration force initially
var init_acceleration_force := { var init_acceleration_force := {"": 0, "idle_walk": 4181, "idle_run": 5765, "walk_run": 1000}
"": 0, "idle_walk": 4181, "idle_run": 5765, "walk_run": 1000
}
# Oriented around deltas of 0.0166666...s # Oriented around deltas of 0.0166666...s
# newtonmeters is the unit # newtonmeters is the unit
var acceleration_force := { var acceleration_force := {
"walk": Vector2(1800, 1345), "walk": Vector2(1800, 1385),
"fall": Vector2(1800, 1050), "fall": Vector2(1800, 1050),
"jump": Vector2(1800, 0), "jump": Vector2(1800, 0),
"idle": Vector2(1800, 1233), "idle": Vector2(1800, 1233),
"duck": Vector2(500, 1300), "duck": Vector2(500, 1300),
"run": Vector2(2500, 1450), "duck_walk": Vector2(500, 1300),
"walljump": Vector2(600, 1050), "run": Vector2(2500, 1490),
"air_strafe": Vector2(333, 2000) "walljump": Vector2(600, 1050),
"air_strafe": Vector2(333, 2000)
} }
# Gravity as m/s^2
var _gravity: float = PhysicsConst.gravity
# Mass of Blobby
# Kilograms
export var mass := 6.5
var velocity := Vector2.ZERO var velocity := Vector2.ZERO
var max_air_strafe_charges := 0 var max_air_strafe_charges := 0
var air_strafe_charges := 0 var air_strafe_charges := 0
# Gravity as m/s^2
var _gravity: float = PhysicsConst.gravity
onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")

View File

@ -1,5 +1,10 @@
extends Actor extends Actor
const PhysicsFunc = preload("res://src/Utilities/Physic/PhysicsFunc.gd") const PhysicsFunc = preload("res://src/Utilities/Physic/PhysicsFunc.gd")
export var jump_buffer_filled := false
export(String, FILE) var death_sound_1 := "res://assets/sounds/Energy Escape.wav"
export(String, FILE) var death_sound_2 := "res://assets/sounds/MONSTER_Cry_mono.wav"
#TODO Switch to new unique node name method for referencing #TODO Switch to new unique node name method for referencing
onready var left_wall_raycasts = $WallRaycasts/LeftWallRaycast onready var left_wall_raycasts = $WallRaycasts/LeftWallRaycast
onready var right_wall_raycasts = $WallRaycasts/RightWallRaycast onready var right_wall_raycasts = $WallRaycasts/RightWallRaycast
@ -13,18 +18,17 @@ onready var player_state_machine = $BlobbyStateMachine
onready var init_boost = player_state_machine.init_boost onready var init_boost = player_state_machine.init_boost
onready var init_boost_type = player_state_machine.init_boost_type onready var init_boost_type = player_state_machine.init_boost_type
export var jump_buffer_filled := false
var wall_touch_direction = 1 var wall_touch_direction = 1
var stomping = false var stomping = false
var floor_angle = Vector2(0,0) var floor_angle = Vector2(0, 0)
var previous_rotation = 0 var previous_rotation = 0
var snap_possible = true var snap_possible = true
var shielded = false var shielded = false
func execute_movement() -> void: func execute_movement() -> void:
if(levelState.is_dead): if level_state.is_dead:
return return
var snap = Vector2.DOWN * 128 var snap = Vector2.DOWN * 128
var center_floor_rot = 0 var center_floor_rot = 0
@ -34,19 +38,22 @@ func execute_movement() -> void:
# get rotation of floor, compare collided floor with floor under center # get rotation of floor, compare collided floor with floor under center
if onfloor: if onfloor:
# TODO: Problem when correctly rotating? # TODO: Problem when correctly rotating?
center_floor_rot = $SlopeRaycast.get_collision_normal().rotated(PI/2).angle() center_floor_rot = $SlopeRaycast.get_collision_normal().rotated(PI / 2).angle()
floor_rot = get_floor_normal().rotated(PI/2).angle() floor_rot = get_floor_normal().rotated(PI / 2).angle()
if(abs(center_floor_rot) > PI/4+0.1): if abs(center_floor_rot) > PI / 4 + 0.1:
center_floor_rot = floor_rot center_floor_rot = floor_rot
# snap when on slopes # snap when on slopes
if((abs(floor_rot) > 0.1 || abs(center_floor_rot) > 0.1) && snap_possible): if (abs(floor_rot) > 0.1 || abs(center_floor_rot) > 0.1) && snap_possible:
velocity = move_and_slide_with_snap(velocity.rotated(floor_rot), velocity = move_and_slide_with_snap(velocity.rotated(floor_rot), snap, FLOOR_NORMAL, true)
snap, FLOOR_NORMAL, true)
# normal slide on flat floor # normal slide on flat floor
else: else:
velocity = move_and_slide(velocity.rotated(floor_rot),FLOOR_NORMAL) velocity = move_and_slide(velocity.rotated(floor_rot), FLOOR_NORMAL)
rotation = 0 rotation = 0
if($SlopeRaycastLeft.is_colliding() && $SlopeRaycastRight.is_colliding() && $SlopeRaycast.is_colliding()): if (
$SlopeRaycastLeft.is_colliding()
&& $SlopeRaycastRight.is_colliding()
&& $SlopeRaycast.is_colliding()
):
rotation = calculate_slope_rotation(onfloor) rotation = calculate_slope_rotation(onfloor)
# rotate related to floor slope # rotate related to floor slope
# Convert velocity back to local space. # Convert velocity back to local space.
@ -54,9 +61,7 @@ func execute_movement() -> void:
velocity = velocity.rotated(-floor_rot) if snap_possible else velocity velocity = velocity.rotated(-floor_rot) if snap_possible else velocity
func calculate_duck_velocity( func calculate_duck_velocity(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2:
linear_velocity: Vector2, delta: float, direction: Vector2
) -> Vector2:
var state = player_state_machine.state var state = player_state_machine.state
var out_vel := linear_velocity var out_vel := linear_velocity
var velocity_direction = 1.0 var velocity_direction = 1.0
@ -64,7 +69,7 @@ func calculate_duck_velocity(
velocity_direction = -1.0 velocity_direction = -1.0
# TODO Improve this to separate crawling(slow) and sliding # TODO Improve this to separate crawling(slow) and sliding
var deceleration_force = calculate_deceleration_force(_gravity, mass)*0.333 var deceleration_force = calculate_deceleration_force(_gravity, mass) * 0.333
# Slowing down movement when not controlling direction # Slowing down movement when not controlling direction
if is_equal_approx(direction.x, 0): if is_equal_approx(direction.x, 0):
@ -81,35 +86,21 @@ func calculate_duck_velocity(
if reverse_move: if reverse_move:
# TODO dont put constants in here # TODO dont put constants in here
out_vel.x = PhysicsFunc.two_step_euler( out_vel.x = PhysicsFunc.two_step_euler(
out_vel.x, out_vel.x, deceleration_force * -3.42 * velocity_direction, mass, delta
deceleration_force * -3.42 * velocity_direction,
mass,
delta
) )
# Normal movement # Normal movement
if abs(velocity.x) < max_velocity[state]: if abs(velocity.x) < max_velocity[state]:
out_vel.x = PhysicsFunc.two_step_euler( out_vel.x = PhysicsFunc.two_step_euler(
out_vel.x, out_vel.x, (acceleration_force[state].x) * direction.x, mass, delta
(
(
acceleration_force[state].x
)
* direction.x
),
mass,
delta
) )
elif !reverse_move: elif !reverse_move:
out_vel.x = max_velocity[state] * direction.x out_vel.x = max_velocity[state] * direction.x
# TODO is_on_dropThrough does the action, is that ok? yEs, MaAsTeR-ChAn # TODO is_on_dropThrough does the action, is that ok? yEs, MaAsTeR-ChAn
# TODO Drop Through coyote time? # TODO Drop Through coyote time?
if (Input.is_action_just_pressed("jump") && is_on_dropThrough()): if Input.is_action_just_pressed("jump") && is_on_dropThrough():
return Vector2(out_vel.x, _gravity*delta) return Vector2(out_vel.x, _gravity * delta)
# Jumping when grounded or jump is buffered # Jumping when grounded or jump is buffered
if ( if Input.is_action_just_pressed("jump") || (jump_buffer_filled && is_on_floor()):
Input.is_action_just_pressed("jump")
|| (jump_buffer_filled && is_on_floor())
):
snap_possible = false snap_possible = false
return calculate_jump_velocity(velocity, delta, direction) return calculate_jump_velocity(velocity, delta, direction)
@ -157,10 +148,7 @@ func calculate_grounded_velocity(
if reverse_move: if reverse_move:
# TODO dont put constants in here # TODO dont put constants in here
out_vel.x = PhysicsFunc.two_step_euler( out_vel.x = PhysicsFunc.two_step_euler(
out_vel.x, out_vel.x, deceleration_force * -3.42 * velocity_direction, mass, delta
deceleration_force * -3.42 * velocity_direction,
mass,
delta
) )
# Normal movement # Normal movement
if abs(velocity.x) < max_velocity[state]: if abs(velocity.x) < max_velocity[state]:
@ -169,10 +157,7 @@ func calculate_grounded_velocity(
( (
( (
acceleration_force[state].x acceleration_force[state].x
+ ( + (init_acceleration_force[init_boost_type] * int(init_boost))
init_acceleration_force[init_boost_type]
* int(init_boost)
)
) )
* direction.x * direction.x
), ),
@ -182,10 +167,7 @@ func calculate_grounded_velocity(
elif !reverse_move: elif !reverse_move:
out_vel.x = max_velocity[state] * direction.x out_vel.x = max_velocity[state] * direction.x
# Jumping when grounded or jump is buffered # Jumping when grounded or jump is buffered
if ( if Input.is_action_just_pressed("jump") || (jump_buffer_filled && is_on_floor()):
Input.is_action_just_pressed("jump")
|| (jump_buffer_filled && is_on_floor())
):
snap_possible = false snap_possible = false
return calculate_jump_velocity(velocity, delta, direction) return calculate_jump_velocity(velocity, delta, direction)
@ -201,10 +183,7 @@ func calculate_grounded_velocity(
# Determines if the player has reversed the steering direction # Determines if the player has reversed the steering direction
# in reference to the current movement direction # in reference to the current movement direction
func is_reversing_horizontal_movement(direction: Vector2) -> bool: func is_reversing_horizontal_movement(direction: Vector2) -> bool:
return ( return (direction.x > 0 && velocity.x < 0) || (direction.x < 0 && velocity.x > 0)
(direction.x > 0 && velocity.x < 0)
|| (direction.x < 0 && velocity.x > 0)
)
# Returns if the character is touching a wall with its whole body # Returns if the character is touching a wall with its whole body
@ -217,7 +196,8 @@ func is_touching_wall_completely() -> bool:
if !left_raycast.is_colliding(): if !left_raycast.is_colliding():
value = false value = false
continue continue
if value == true: return value if value == true:
return value
value = true value = true
for right_raycast in right_wall_raycasts.get_children(): for right_raycast in right_wall_raycasts.get_children():
@ -240,10 +220,7 @@ func is_correct_walljump_input(direction: Vector2) -> bool:
func is_correct_airstrafe_input() -> bool: func is_correct_airstrafe_input() -> bool:
return ( return (
air_strafe_charges > 0 air_strafe_charges > 0
&& ( && (Input.is_action_just_pressed("move_right") || Input.is_action_just_pressed("move_left"))
Input.is_action_just_pressed("move_right")
|| Input.is_action_just_pressed("move_left")
)
) )
@ -252,9 +229,7 @@ func calculate_deceleration_force(_gravity: float, mass: float) -> float:
return floor_friction * _gravity * mass return floor_friction * _gravity * mass
func calculate_jump_velocity( func calculate_jump_velocity(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2:
linear_velocity: Vector2, delta: float, direction: Vector2
) -> Vector2:
var state = player_state_machine.state var state = player_state_machine.state
var additive_jump_force = velocity_jump_boost_ratio * abs(velocity.x) * mass var additive_jump_force = velocity_jump_boost_ratio * abs(velocity.x) * mass
#TODO Single out stomping and make betta #TODO Single out stomping and make betta
@ -284,22 +259,22 @@ func calculate_jump_velocity(
if velocity.y > _gravity * delta * 10: if velocity.y > _gravity * delta * 10:
linear_velocity.y += _gravity * delta * 10 linear_velocity.y += _gravity * delta * 10
else: else:
linear_velocity.y += ( linear_velocity.y += (max(abs(linear_velocity.y), _gravity * delta) / 2)
max(abs(linear_velocity.y), _gravity * delta)
/ 2
)
else: else:
linear_velocity.y += _gravity * delta linear_velocity.y += _gravity * delta
# TODO This is poop too # TODO This is poop too
if -max_velocity["jump"].x < velocity.x and direction.x < 0 || \ if (
max_velocity["jump"].x > velocity.x and direction.x > 0: -max_velocity["jump"].x < velocity.x and direction.x < 0
|| max_velocity["jump"].x > velocity.x and direction.x > 0
):
var absolut = 1 - initial_velocity_dependence var absolut = 1 - initial_velocity_dependence
var divisor = 1/max(0.1, initial_velocity_dependence) var divisor = 1 / max(0.1, initial_velocity_dependence)
var movementFactor = (absolut + abs(velocity.x)/(max_velocity["fall"].x * divisor)) var movement_factor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor)
linear_velocity.x = PhysicsFunc.two_step_euler( linear_velocity.x = PhysicsFunc.two_step_euler(
linear_velocity.x, acceleration_force[state].x * movementFactor * direction.x, linear_velocity.x,
acceleration_force[state].x * movement_factor * direction.x,
mass, mass,
delta delta
) )
@ -312,9 +287,7 @@ func calculate_jump_velocity(
# Only applicable to downwards gravity # Only applicable to downwards gravity
# Can set the jump buffer # Can set the jump buffer
func calculate_fall_velocity( func calculate_fall_velocity(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2:
linear_velocity: Vector2, delta: float, direction: Vector2
) -> Vector2:
var state = player_state_machine.state var state = player_state_machine.state
if velocity.y < max_velocity["fall"].y: if velocity.y < max_velocity["fall"].y:
linear_velocity.y = PhysicsFunc.two_step_euler( linear_velocity.y = PhysicsFunc.two_step_euler(
@ -322,14 +295,17 @@ func calculate_fall_velocity(
) )
else: else:
linear_velocity.y = max_velocity["fall"].y linear_velocity.y = max_velocity["fall"].y
if -max_velocity["fall"].x < velocity.x and direction.x < 0 || \ if (
max_velocity["fall"].x > velocity.x and direction.x > 0: -max_velocity["fall"].x < velocity.x and direction.x < 0
|| max_velocity["fall"].x > velocity.x and direction.x > 0
):
# TODO This is poop # TODO This is poop
var absolut = 1 - initial_velocity_dependence var absolut = 1 - initial_velocity_dependence
var divisor = 1/max(0.1, initial_velocity_dependence) var divisor = 1 / max(0.1, initial_velocity_dependence)
var movementFactor = (absolut + abs(velocity.x)/(max_velocity["fall"].x * divisor)) var movementFactor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor)
linear_velocity.x = PhysicsFunc.two_step_euler( linear_velocity.x = PhysicsFunc.two_step_euler(
linear_velocity.x, acceleration_force[state].x * movementFactor * direction.x, linear_velocity.x,
acceleration_force[state].x * movementFactor * direction.x,
mass, mass,
delta delta
) )
@ -338,7 +314,7 @@ func calculate_fall_velocity(
if is_correct_airstrafe_input(): if is_correct_airstrafe_input():
linear_velocity = execute_airstrafe(linear_velocity, delta, direction) linear_velocity = execute_airstrafe(linear_velocity, delta, direction)
if stomping: if stomping:
linear_velocity = calculate_jump_velocity(Vector2(linear_velocity.x,0), delta, direction) linear_velocity = calculate_jump_velocity(Vector2(linear_velocity.x, 0), delta, direction)
return linear_velocity return linear_velocity
@ -348,10 +324,7 @@ func calculate_wallslide_velocity(
# Walljump mechanics # Walljump mechanics
if is_correct_walljump_input(direction): if is_correct_walljump_input(direction):
linear_velocity.x = PhysicsFunc.two_step_euler( linear_velocity.x = PhysicsFunc.two_step_euler(
0, 0, acceleration_force["walljump"].x / delta * direction.x, mass, delta
acceleration_force["walljump"].x / delta * direction.x,
mass,
delta
) )
linear_velocity.y = PhysicsFunc.two_step_euler( linear_velocity.y = PhysicsFunc.two_step_euler(
0, acceleration_force["walljump"].y / delta * -1, mass, delta 0, acceleration_force["walljump"].y / delta * -1, mass, delta
@ -362,15 +335,17 @@ func calculate_wallslide_velocity(
else: else:
# TODO dont put constants in here # TODO dont put constants in here
linear_velocity.y = PhysicsFunc.two_step_euler( linear_velocity.y = PhysicsFunc.two_step_euler(
linear_velocity.y*0.94, _gravity * mass, mass, delta linear_velocity.y * 0.94, _gravity * mass, mass, delta
) )
air_strafe_charges = air_strafe_charges + 1 if max_air_strafe_charges > air_strafe_charges else 0 air_strafe_charges = (
air_strafe_charges + 1
if max_air_strafe_charges > air_strafe_charges
else 0
)
return linear_velocity.rotated(rotation) return linear_velocity.rotated(rotation)
func execute_airstrafe( func execute_airstrafe(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2:
linear_velocity: Vector2, delta: float, direction: Vector2
) -> Vector2:
# var rev = 1 if !is_reversing_horizontal_movement(direction) else -1 # var rev = 1 if !is_reversing_horizontal_movement(direction) else -1
# TODO Consider adding a extra state for airstrafing # TODO Consider adding a extra state for airstrafing
# TODO Make airstrafing less instantaneous and moderate the impulse # TODO Make airstrafing less instantaneous and moderate the impulse
@ -381,10 +356,7 @@ func execute_airstrafe(
if is_reversing_horizontal_movement(direction): if is_reversing_horizontal_movement(direction):
linear_velocity.x = 0 linear_velocity.x = 0
linear_velocity.x = PhysicsFunc.two_step_euler( linear_velocity.x = PhysicsFunc.two_step_euler(
linear_velocity.x, linear_velocity.x, acceleration_force["air_strafe"].x / delta * direction.x, mass, delta
acceleration_force["air_strafe"].x / delta * direction.x,
mass,
delta
) )
if linear_velocity.y > 0: if linear_velocity.y > 0:
# TODO Put constant elsewhere # TODO Put constant elsewhere
@ -393,43 +365,61 @@ func execute_airstrafe(
return linear_velocity return linear_velocity
func calculate_slope_rotation(onfloor: bool) -> float: func calculate_slope_rotation(_onfloor: bool) -> float:
var angle = 0 var angle = 0
var slope_angle_left = $SlopeRaycastLeft.get_collision_normal().rotated(PI/2).angle() var slope_angle_left = $SlopeRaycastLeft.get_collision_normal().rotated(PI / 2).angle()
var slope_angle_right = $SlopeRaycastRight.get_collision_normal().rotated(PI/2).angle() var slope_angle_right = $SlopeRaycastRight.get_collision_normal().rotated(PI / 2).angle()
# avoid invalid angles and stay in rotation when touching ground completely # avoid invalid angles and stay in rotation when touching ground completely
if(!(-PI/2 <= slope_angle_left && slope_angle_left <= PI/2) if (
|| !(-PI/2 <= slope_angle_right && slope_angle_right <= PI/2) !(-PI / 2 <= slope_angle_left && slope_angle_left <= PI / 2)
|| (is_equal_approx(abs(slope_angle_left), abs(slope_angle_right)))): || !(-PI / 2 <= slope_angle_right && slope_angle_right <= PI / 2)
return previous_rotation if abs(rad2deg(previous_rotation)) > 1 && !is_equal_approx(slope_angle_left , 0) else 0.0 || (is_equal_approx(abs(slope_angle_left), abs(slope_angle_right)))
):
return (
previous_rotation
if abs(rad2deg(previous_rotation)) > 1 && !is_equal_approx(slope_angle_left, 0)
else 0.0
)
# downturn # downturn
if(abs(slope_angle_left) > abs(slope_angle_right) && velocity.x < -10|| if (
abs(slope_angle_right) > abs(slope_angle_left) && velocity.x > 10): abs(slope_angle_left) > abs(slope_angle_right) && velocity.x < -10
var length_vector: Vector2 = $SlopeRaycastRight.get_collision_point() - $SlopeRaycastLeft.get_collision_point() || abs(slope_angle_right) > abs(slope_angle_left) && velocity.x > 10
):
var length_vector: Vector2 = (
$SlopeRaycastRight.get_collision_point()
- $SlopeRaycastLeft.get_collision_point()
)
angle = length_vector.angle() angle = length_vector.angle()
# upturn # upturn
else: else:
var length_vector: Vector2 = $SlopeRaycastLeft.get_collision_point() - $SlopeRaycastRight.get_collision_point() var length_vector: Vector2 = (
$SlopeRaycastLeft.get_collision_point()
- $SlopeRaycastRight.get_collision_point()
)
angle = length_vector.angle() - PI angle = length_vector.angle() - PI
previous_rotation = angle previous_rotation = angle
if is_equal_approx(deg2rad(angle), 0): if is_equal_approx(deg2rad(angle), 0):
pass pass
return angle return angle
# TODO could be expanded with a parameter about what got stomped # TODO could be expanded with a parameter about what got stomped
func stomp() -> void: func stomp() -> void:
# print("stomping") # print("stomping")
stomping = true stomping = true
# TOD lose_power_up function # TOD lose_power_up function
func receive_power_up(kind: String) -> void: func receive_power_up(kind: String) -> void:
if kind == "shield": if kind == "shield":
$BubbleShieldViewport/IridescenceBall.visible = true $BubbleShieldViewport/IridescenceBall.visible = true
shielded = true shielded = true
# TODO Maybe this should be a state in itself? # TODO Maybe this should be a state in itself?
func die(animation_number: int = 0) -> void: func die(animation_number: int = 0) -> void:
if levelState.is_dead: return if level_state.is_dead:
return
if shielded: if shielded:
shielded = false shielded = false
$BubbleShieldViewport/IridescenceBall.visible = false $BubbleShieldViewport/IridescenceBall.visible = false
@ -440,11 +430,14 @@ func die(animation_number: int = 0) -> void:
return return
z_index = 1 z_index = 1
$BlobbySprite.material = death_shader $BlobbySprite.material = death_shader
signalManager.emit_signal("player_died", animation_number) signal_manager.emit_signal("player_died", animation_number)
$"%BlobbymationTree".active = false $"%BlobbymationTree".active = false
$"%BlobbymationPlayer".play("dying3") $"%BlobbymationPlayer".play("dying3")
if animation_number < 1: if animation_number < 1:
$"%BlobbymationPlayer".play("expandingDisolve") $"%BlobbymationPlayer".play("expandingDisolve")
scene_audio.play_parallel_sound(death_sound_1, -15)
scene_audio.play_parallel_sound(death_sound_2, -16)
func die_for_real(animation_number: int = 0) -> void: func die_for_real(animation_number: int = 0) -> void:
shielded = false shielded = false
@ -457,6 +450,7 @@ func respawn() -> void:
# Is tied to the death animation # Is tied to the death animation
get_tree().reload_current_scene() get_tree().reload_current_scene()
# When the Enemy stomp AREA enters the enemy collision area -> stomp # When the Enemy stomp AREA enters the enemy collision area -> stomp
func _on_BlobbySkin_area_entered(area: Area2D) -> void: func _on_BlobbySkin_area_entered(area: Area2D) -> void:
if area.is_in_group("harmful"): if area.is_in_group("harmful"):
@ -464,6 +458,7 @@ func _on_BlobbySkin_area_entered(area: Area2D) -> void:
if area.is_in_group("pit"): if area.is_in_group("pit"):
$PitfallTimer.start() $PitfallTimer.start()
# This problem stems from trying to decelerate a walk # This problem stems from trying to decelerate a walk
# that was caused by the moving environment and not by input # that was caused by the moving environment and not by input
# It is particularly usefull for moving floor physics # It is particularly usefull for moving floor physics
@ -477,12 +472,18 @@ func _on_Blobby_got_grounded() -> void:
floor_friction = floor_object.slide_friction floor_friction = floor_object.slide_friction
else: else:
floor_friction = base_floor_friction floor_friction = base_floor_friction
air_strafe_charges = air_strafe_charges + 1 if max_air_strafe_charges > air_strafe_charges else 0 air_strafe_charges = (
air_strafe_charges + 1
if max_air_strafe_charges > air_strafe_charges
else 0
)
func _on_BlobbySkin_body_exited(body: Node) -> void:
# This is for drop through platforms
if body.get_collision_mask_bit(7):
set_collision_mask_bit(7, true)
func _on_BlobbySkin_body_exited(body:Node) -> void:
# This is for drop through platforms
if body.get_collision_mask_bit(7):
set_collision_mask_bit(7, true)
func _on_InvincibilityTimer_timeout() -> void: func _on_InvincibilityTimer_timeout() -> void:
$BlobbySprite.material = null $BlobbySprite.material = null
@ -490,18 +491,22 @@ func _on_InvincibilityTimer_timeout() -> void:
if area.is_in_group("harmful"): if area.is_in_group("harmful"):
die() die()
func handle_grounded_movement(delta: float, direction: Vector2) -> Vector2: func handle_grounded_movement(delta: float, direction: Vector2) -> Vector2:
return calculate_grounded_velocity(velocity, delta, direction) return calculate_grounded_velocity(velocity, delta, direction)
func handle_jump_movement(delta: float, direction: Vector2) -> Vector2: func handle_jump_movement(delta: float, direction: Vector2) -> Vector2:
return calculate_jump_velocity(velocity, delta, direction) return calculate_jump_velocity(velocity, delta, direction)
func handle_duck_movement(delta: float, direction: Vector2) -> Vector2: func handle_duck_movement(delta: float, direction: Vector2) -> Vector2:
return calculate_duck_velocity(velocity, delta, direction) return calculate_duck_velocity(velocity, delta, direction)
func handle_fall_movement(delta: float, direction: Vector2) -> Vector2: func handle_fall_movement(delta: float, direction: Vector2) -> Vector2:
return calculate_fall_velocity(velocity, delta, direction) return calculate_fall_velocity(velocity, delta, direction)
func handle_wallslide_movement(delta: float, direction: Vector2) -> Vector2: func handle_wallslide_movement(delta: float, direction: Vector2) -> Vector2:
return calculate_wallslide_velocity(velocity, delta, direction) return calculate_wallslide_velocity(velocity, delta, direction)

View File

@ -7,8 +7,8 @@ export var offset_input_seconds := 0.618 * 2
export var alarm_light_shader: Material export var alarm_light_shader: Material
export var fixed_position : bool = false export var fixed_position : bool = false
onready var levelState := $"%LevelState" onready var level_state := $"%LevelState"
onready var signalManager := $"%SignalManager" onready var signal_manager := $"%SignalManager"
onready var shiftLeft = $CameraAnimationPlayer.get_animation("shiftingLeft") onready var shiftLeft = $CameraAnimationPlayer.get_animation("shiftingLeft")
onready var shiftRight = $CameraAnimationPlayer.get_animation("shiftingRight") onready var shiftRight = $CameraAnimationPlayer.get_animation("shiftingRight")
onready var shiftCenter = $CameraAnimationPlayer.get_animation("shiftingCenter") onready var shiftCenter = $CameraAnimationPlayer.get_animation("shiftingCenter")
@ -57,8 +57,8 @@ func _ready():
material.set_shader_param("light_data", null) material.set_shader_param("light_data", null)
_update_lighting_shader() _update_lighting_shader()
# TODO Trigger when needed # TODO Trigger when needed
signalManager.connect("terminal_activated", self, "_on_SignalManager_terminal_activated") signal_manager.connect("terminal_activated", self, "_on_SignalManager_terminal_activated")
signalManager.connect("player_died", self, "_death_cam") signal_manager.connect("player_died", self, "_death_cam")
func _on_SignalManager_terminal_activated(animation_number: int = 0): func _on_SignalManager_terminal_activated(animation_number: int = 0):
terminal_activated = true terminal_activated = true
@ -77,7 +77,7 @@ func _physics_process(delta: float) -> void:
screen_left = screen_center - Vector2(screen_rect.x/2, 0) screen_left = screen_center - Vector2(screen_rect.x/2, 0)
screen_right = screen_center + Vector2(screen_rect.x/2, 0) screen_right = screen_center + Vector2(screen_rect.x/2, 0)
var was_adjusted := false var was_adjusted := false
if(!levelState.is_dead): if(!level_state.is_dead):
was_adjusted = _adjust_offset(delta) was_adjusted = _adjust_offset(delta)
if(anim_player.is_playing() || was_adjusted): if(anim_player.is_playing() || was_adjusted):

View File

@ -14,7 +14,7 @@ func _on_StompDetector_body_entered(body: Node) -> void:
body.die() body.die()
player_entered_stomp = false player_entered_stomp = false
return return
signalManager.emit_signal("got_stomped") signal_manager.emit_signal("got_stomped")
remove_from_group("harmful") remove_from_group("harmful")
$StompDetector.remove_from_group("weakpoint") $StompDetector.remove_from_group("weakpoint")
get_node("EnemyBody").disabled = true get_node("EnemyBody").disabled = true

View File

@ -3,8 +3,8 @@ extends Node2D
# Is given in blocks # Is given in blocks
export var movement_radius = 6 export var movement_radius = 6
onready var tilemap: TileMap = $"%TileMap" onready var tilemap: TileMap = $"%TileMap"
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
var Rope = preload("res://src/Contraptions/Rope/Rope.tscn") var Rope = preload("res://src/Contraptions/Rope/Rope.tscn")
var RopeAnchor = preload("res://src/Contraptions/Rope/RopeAnchor.tscn") var RopeAnchor = preload("res://src/Contraptions/Rope/RopeAnchor.tscn")
@ -13,7 +13,7 @@ var rope
var is_first_signal = true var is_first_signal = true
func _ready() -> void: func _ready() -> void:
signalManager.connect("level_loaded", self, "_on_level_loaded") signal_manager.connect("level_loaded", self, "_on_level_loaded")
func _on_level_loaded() -> void: func _on_level_loaded() -> void:
rope = Rope.instance() rope = Rope.instance()
@ -59,6 +59,6 @@ func _on_FrogFreeButton_pushed() -> void:
$WhatAreFrog.is_bound = false $WhatAreFrog.is_bound = false
$WhatAreFrog/LeashAnchor.visible = false $WhatAreFrog/LeashAnchor.visible = false
$WhatAreFrog.remove_from_group("harmful") $WhatAreFrog.remove_from_group("harmful")
levelState.free_a_frog(frog_number) level_state.free_a_frog(frog_number)
disconnect_rope() disconnect_rope()
is_first_signal = false is_first_signal = false

View File

@ -69,8 +69,8 @@ func _ready():
if(get_parent().name.begins_with("Bound")): if(get_parent().name.begins_with("Bound")):
is_bound = true is_bound = true
else: else:
levelState.free_a_frog(frog_number) level_state.free_a_frog(frog_number)
levelState.register_frog(frog_number, !is_bound) level_state.register_frog(frog_number, !is_bound)
# TODO Stays harmless for now # TODO Stays harmless for now
#if(is_bound): add_to_group("harmful") #if(is_bound): add_to_group("harmful")
@ -143,7 +143,7 @@ func _on_StompDetector_body_entered(body: Node) -> void:
# if abs(incoming_vel_vector.angle_to(\Vector2.DOWN.rotated(rotation))) > deg2rad(60): # if abs(incoming_vel_vector.angle_to(\Vector2.DOWN.rotated(rotation))) > deg2rad(60):
# print("too shallow entry") # print("too shallow entry")
# return # return
signalManager.emit_signal("got_stomped") signal_manager.emit_signal("got_stomped")
remove_from_group("harmful") remove_from_group("harmful")
# TODO Weakpoint group is not needed per se # TODO Weakpoint group is not needed per se
$StompDetector.remove_from_group("weakpoint") $StompDetector.remove_from_group("weakpoint")

View File

@ -13,8 +13,8 @@ func load_initial_save() -> void:
GlobalState.reinstate() GlobalState.reinstate()
func save_default() -> void: func save_default() -> void:
var signalManager = get_tree().root.get_child(4).get_node("%SignalManager") var signal_manager = get_tree().root.get_child(4).get_node("%SignalManager")
for action in InputMap.get_actions(): for action in InputMap.get_actions():
GlobalState.gsr.input_map[action] = InputMap.get_action_list(action) GlobalState.gsr.input_map[action] = InputMap.get_action_list(action)
ResourceSaver.save(save_location, GlobalState.gsr) ResourceSaver.save(save_location, GlobalState.gsr)
signalManager.emit_signal("savemanager_saved") signal_manager.emit_signal("savemanager_saved")

View File

@ -1,14 +1,14 @@
extends Area2D extends Area2D
onready var anim_player: AnimationPlayer = get_node("AnimationPlayer") onready var anim_player: AnimationPlayer = get_node("AnimationPlayer")
onready var levelState := $"%LevelState" onready var level_state := $"%LevelState"
export var currencyValue: = 1 export var currencyValue: = 1
func _on_body_entered(_body: Node) -> void: func _on_body_entered(_body: Node) -> void:
if $AudioStreamPlayer.playing: if $AudioStreamPlayer.playing:
return return
levelState.currency += currencyValue level_state.currency += currencyValue
$CollisionShape2D.disabled = true $CollisionShape2D.disabled = true
set_deferred("monitoring", false) set_deferred("monitoring", false)
$AudioStreamPlayer.play() $AudioStreamPlayer.play()

View File

@ -1,9 +1,9 @@
extends Node2D extends Node2D
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
func _ready() -> void: func _ready() -> void:
if(GlobalState.get_savepoint(levelState.levelName) == global_position + Vector2(0,18)): if(GlobalState.get_savepoint(level_state.levelName) == global_position + Vector2(0,18)):
$Flag.material.set_shader_param("speed", 0.6) $Flag.material.set_shader_param("speed", 0.6)
$Flag.material.set_shader_param("amplitude", 1) $Flag.material.set_shader_param("amplitude", 1)
$Flag.material.set_shader_param("inclination", 1) $Flag.material.set_shader_param("inclination", 1)
@ -13,6 +13,6 @@ func _ready() -> void:
#TODO What should be saved when reaching a savepoint besides the position in the level #TODO What should be saved when reaching a savepoint besides the position in the level
func _on_SaveArea_area_entered(area: Area2D) -> void: func _on_SaveArea_area_entered(area: Area2D) -> void:
#TODO Spawnheight fixed #TODO Spawnheight fixed
if(!GlobalState.get_savepoint(levelState.levelName) == global_position + Vector2(0,18)): if(!GlobalState.get_savepoint(level_state.levelName) == global_position + Vector2(0,18)):
$AnimationPlayer.play("rolloutflag") $AnimationPlayer.play("rolloutflag")
GlobalState.set_savepoint(levelState.levelName, global_position + Vector2(0,18)) GlobalState.set_savepoint(level_state.levelName, global_position + Vector2(0,18))

View File

@ -1,13 +1,13 @@
extends StaticBody2D extends StaticBody2D
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
export var locked := true export var locked := true
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready() -> void: func _ready() -> void:
signalManager.connect("unlocked", self, "unlock") signal_manager.connect("unlocked", self, "unlock")
# if locked: # if locked:
# $CollisionShape2D.enabled = true # $CollisionShape2D.enabled = true
# visible = true # visible = true

View File

@ -2,8 +2,8 @@ tool
extends Area2D extends Area2D
onready var anim_player: AnimationPlayer = $AnimationPlayer onready var anim_player: AnimationPlayer = $AnimationPlayer
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
onready var levelName := get_tree().get_current_scene().get_name() onready var levelName := get_tree().get_current_scene().get_name()
export(String, FILE, "*.tscn") var next_scene export(String, FILE, "*.tscn") var next_scene
@ -14,7 +14,7 @@ func _get_configuration_warning() -> String:
func level_completion() -> void: func level_completion() -> void:
GlobalState.remove_savepoint(levelName) GlobalState.remove_savepoint(levelName)
signalManager.emit_signal("level_completed") signal_manager.emit_signal("level_completed")
func teleport() -> void: func teleport() -> void:

View File

@ -4,7 +4,7 @@ onready var buttonPlayer = $"%ButtonPlayer"
onready var activatorArea = $"%ActivatorArea" onready var activatorArea = $"%ActivatorArea"
onready var indicatorPlayer = $"%IndicatorPlayer" onready var indicatorPlayer = $"%IndicatorPlayer"
onready var elevator = get_node("./Portal") onready var elevator = get_node("./Portal")
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
onready var unactivatable_timer := $Timer onready var unactivatable_timer := $Timer
onready var get_back_timer := $GetBackTimer onready var get_back_timer := $GetBackTimer
@ -19,7 +19,7 @@ func _ready() -> void:
func _process(delta): func _process(delta):
if activatable && Input.is_action_just_released("interact"): if activatable && Input.is_action_just_released("interact"):
selfActivate() selfActivate()
signalManager.emit_signal("terminal_activated", elevator_time) signal_manager.emit_signal("terminal_activated", elevator_time)
get_back_timer.start() get_back_timer.start()
@ -49,4 +49,4 @@ func _on_Timer_timeout():
func _on_GetBackTimer_timeout() -> void: func _on_GetBackTimer_timeout() -> void:
signalManager.emit_signal("getback_timer_up") signal_manager.emit_signal("getback_timer_up")

View File

@ -4,7 +4,7 @@ signal button_pushed
onready var activatorArea = $"%ActivatorArea" onready var activatorArea = $"%ActivatorArea"
onready var indicatorPlayer = $"%IndicatorPlayer" onready var indicatorPlayer = $"%IndicatorPlayer"
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
onready var unactivatable_timer := $Timer onready var unactivatable_timer := $Timer
export(int) var frog_number := 0 export(int) var frog_number := 0

View File

@ -2,7 +2,7 @@ extends Node2D
onready var activatorArea = $"%ActivatorArea" onready var activatorArea = $"%ActivatorArea"
onready var indicatorPlayer = $"%IndicatorPlayer" onready var indicatorPlayer = $"%IndicatorPlayer"
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
onready var unactivatable_timer := $Timer onready var unactivatable_timer := $Timer
var activatable = false var activatable = false
@ -17,7 +17,7 @@ func selfActivate():
#TODO dis importante #TODO dis importante
activatorArea.set_deferred("monitoring", false) activatorArea.set_deferred("monitoring", false)
#TODO Close gate again? #TODO Close gate again?
signalManager.emit_signal("unlocked", "gateblock") signal_manager.emit_signal("unlocked", "gateblock")
activatable = false activatable = false

View File

@ -1,8 +1,8 @@
extends Node2D extends Node2D
onready var activatorArea = $"%ActivatorArea" onready var activatorArea = $"%ActivatorArea"
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
onready var blobby := $"../%Blobby" onready var blobby := $"../%Blobby"
onready var unactivatable_timer := $Timer onready var unactivatable_timer := $Timer
export var cost := 3 export var cost := 3
@ -13,14 +13,14 @@ var activatable = false
func _process(delta): func _process(delta):
# TODO Global currency count?? Maybe just level intern currency # TODO Global currency count?? Maybe just level intern currency
if activatable && Input.is_action_just_released("interact"): if activatable && Input.is_action_just_released("interact"):
if(levelState.spend_currency(cost)): if(level_state.spend_currency(cost)):
signalManager.emit_signal("currency_updated") signal_manager.emit_signal("currency_updated")
selfActivate() selfActivate()
func selfActivate(): func selfActivate():
#TODO Is a event for blobby himself #TODO Is a event for blobby himself
#blobby.get_node("BubbleShieldViewport/IridescenceBall").visible = true #blobby.get_node("BubbleShieldViewport/IridescenceBall").visible = true
signalManager.emit_signal("power_up_collected", "shield") signal_manager.emit_signal("power_up_collected", "shield")
#TODO dis importante #TODO dis importante
activatorArea.set_deferred("monitoring", false) activatorArea.set_deferred("monitoring", false)

View File

@ -123,12 +123,9 @@ wait_time = 20.0
unique_name_in_owner = true unique_name_in_owner = true
visible = false visible = false
[node name="AnimatedSprite2" parent="BlobbyCam/ParallaxBackground/ParallaxLayer5" index="5"]
frame = 13
[node name="Blobby" parent="." instance=ExtResource( 10 )] [node name="Blobby" parent="." instance=ExtResource( 10 )]
unique_name_in_owner = true unique_name_in_owner = true
position = Vector2( -180, 112 ) position = Vector2( -180, 113 )
scale = Vector2( 0.878906, 0.936025 ) scale = Vector2( 0.878906, 0.936025 )
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]

View File

@ -68,15 +68,9 @@ wait_time = 20.0
unique_name_in_owner = true unique_name_in_owner = true
drag_margin_bottom = 0.3 drag_margin_bottom = 0.3
[node name="AnimatedSprite" parent="BlobbyCam/ParallaxBackground/ParallaxLayer5" index="4"]
frame = 11
[node name="AnimatedSprite2" parent="BlobbyCam/ParallaxBackground/ParallaxLayer5" index="5"]
frame = 10
[node name="Blobby" parent="." instance=ExtResource( 8 )] [node name="Blobby" parent="." instance=ExtResource( 8 )]
unique_name_in_owner = true unique_name_in_owner = true
position = Vector2( -70, -1.90735e-06 ) position = Vector2( -70, 1 )
scale = Vector2( 0.878906, 0.936025 ) scale = Vector2( 0.878906, 0.936025 )
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]

View File

@ -66,15 +66,9 @@ wait_time = 20.0
unique_name_in_owner = true unique_name_in_owner = true
drag_margin_bottom = 0.3 drag_margin_bottom = 0.3
[node name="AnimatedSprite" parent="BlobbyCam/ParallaxBackground/ParallaxLayer5" index="4"]
frame = 7
[node name="AnimatedSprite2" parent="BlobbyCam/ParallaxBackground/ParallaxLayer5" index="5"]
frame = 6
[node name="Blobby" parent="." instance=ExtResource( 9 )] [node name="Blobby" parent="." instance=ExtResource( 9 )]
unique_name_in_owner = true unique_name_in_owner = true
position = Vector2( -186, 110 ) position = Vector2( -186, 113 )
scale = Vector2( 0.878906, 0.936025 ) scale = Vector2( 0.878906, 0.936025 )
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]

View File

@ -259,15 +259,9 @@ unique_name_in_owner = true
visible = false visible = false
drag_margin_bottom = 0.3 drag_margin_bottom = 0.3
[node name="AnimatedSprite" parent="BlobbyCam/ParallaxBackground/ParallaxLayer5" index="4"]
frame = 13
[node name="AnimatedSprite2" parent="BlobbyCam/ParallaxBackground/ParallaxLayer5" index="5"]
frame = 7
[node name="Blobby" parent="." instance=ExtResource( 9 )] [node name="Blobby" parent="." instance=ExtResource( 9 )]
unique_name_in_owner = true unique_name_in_owner = true
position = Vector2( -128, 16 ) position = Vector2( -142, 17 )
scale = Vector2( 0.878906, 0.936025 ) scale = Vector2( 0.878906, 0.936025 )
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]

View File

@ -7,15 +7,15 @@ func _ready() -> void:
self.add_child(t) self.add_child(t)
t.start() t.start()
yield(t, "timeout") yield(t, "timeout")
levelState.register_tutorial("move_right") level_state.register_tutorial("move_right")
spawn_tutorial_thingy("move_right") spawn_tutorial_thingy("move_right")
t.start() t.start()
yield(t, "timeout") yield(t, "timeout")
levelState.register_tutorial("move_left") level_state.register_tutorial("move_left")
spawn_tutorial_thingy("move_left") spawn_tutorial_thingy("move_left")
t.start() t.start()
yield(t, "timeout") yield(t, "timeout")
levelState.register_tutorial("jump") level_state.register_tutorial("jump")
spawn_tutorial_thingy("jump") spawn_tutorial_thingy("jump")
t.queue_free() t.queue_free()

View File

@ -1,12 +1,12 @@
extends Node2D extends Node2D
class_name LevelTemplate class_name LevelTemplate
onready var signalManager := $"%SignalManager" onready var signal_manager := $"%SignalManager"
onready var levelState := $"%LevelState" onready var level_state := $"%LevelState"
func _ready() -> void: func _ready() -> void:
# should spawn the tutorial thingies which are still remembered in the progress dictionary # should spawn the tutorial thingies which are still remembered in the progress dictionary
signalManager.emit_signal("level_loaded") signal_manager.emit_signal("level_loaded")
get_tree().paused = false get_tree().paused = false

View File

@ -41,12 +41,12 @@ resource_name = "LowPassFilter"
cutoff_hz = 3000.0 cutoff_hz = 3000.0
[resource] [resource]
bus/0/volume_db = -10.4576 bus/0/volume_db = -6.0206
bus/1/name = "Music" bus/1/name = "Music"
bus/1/solo = false bus/1/solo = false
bus/1/mute = false bus/1/mute = false
bus/1/bypass_fx = false bus/1/bypass_fx = false
bus/1/volume_db = -10.4576 bus/1/volume_db = -20.0
bus/1/send = "Master" bus/1/send = "Master"
bus/1/effect/0/effect = SubResource( 1 ) bus/1/effect/0/effect = SubResource( 1 )
bus/1/effect/0/enabled = false bus/1/effect/0/enabled = false

View File

@ -7,6 +7,11 @@ export var init_boost_type = ""
export(String, FILE) var footstep_sound := "res://assets/sounds/footsteps.ogg" export(String, FILE) var footstep_sound := "res://assets/sounds/footsteps.ogg"
var facing = 1
var did_turn
var coyote_hanging = false
var was_coyote_hanging = false
onready var anim_player = parent.get_node("%BlobbymationPlayer") onready var anim_player = parent.get_node("%BlobbymationPlayer")
onready var anim_state_playback = parent.get_node("%BlobbymationTree").get("parameters/playback") onready var anim_state_playback = parent.get_node("%BlobbymationTree").get("parameters/playback")
onready var anim_tree = parent.get_node("%BlobbymationTree") onready var anim_tree = parent.get_node("%BlobbymationTree")
@ -18,263 +23,267 @@ onready var run_dust_left_res = load("res://assets/effects/run-dusting-left.png"
onready var sprite = parent.get_node("BlobbySprite") onready var sprite = parent.get_node("BlobbySprite")
onready var slope_raycast = get_node("%SlopeRaycast") onready var slope_raycast = get_node("%SlopeRaycast")
var facing = 1
var didTurn
var coyote_hanging = false
var was_coyote_hanging = false
# Adds the intial states # Adds the intial states
func _ready(): func _ready():
signalManager.connect("getback_timer_up", parent, "die_for_real", [1]) signal_manager.connect("getback_timer_up", parent, "die_for_real", [1])
signalManager.connect("power_up_collected", parent, "receive_power_up") signal_manager.connect("power_up_collected", parent, "receive_power_up")
signalManager.connect("got_stomped", parent, "stomp") signal_manager.connect("got_stomped", parent, "stomp")
anim_player.play("RESET") anim_player.play("RESET")
add_state("idle") add_state("idle")
add_state("duck") add_state("duck")
add_state("run") add_state("duck_walk")
add_state("walk") add_state("run")
add_state("jump") add_state("walk")
add_state("fall") add_state("jump")
add_state("wallslide") add_state("fall")
state = states.idle add_state("wallslide")
levelState.is_dead = false state = states.idle
set_state(states.idle) level_state.is_dead = false
set_state(states.idle)
# Zero Vector is false # Zero Vector is false
if(GlobalState.get_savepoint(levelState.levelName)): if GlobalState.get_savepoint(level_state.levelName):
parent.global_position = GlobalState.get_savepoint(levelState.levelName) parent.global_position = GlobalState.get_savepoint(level_state.levelName)
# Calls the parent behaviours according to state # Calls the parent behaviours according to state
func _state_logic(delta): func _state_logic(delta):
# RayCasts for visual debugging # RayCasts for visual debugging
# TODO Global context switch for debug/build mode # TODO Global context switch for debug/build mode
# \ is for new line in multiline statements # \ is for new line in multiline statements
# parent.get_node("CollisionShape2D/RayCaster")._raycast( # parent.get_node("CollisionShape2D/RayCaster")._raycast(
# Vector2.DOWN, # Vector2.DOWN,
# parent.get_node("CollisionShape2D").get_shape(), # parent.get_node("CollisionShape2D").get_shape(),
# parent.collision_mask # parent.collision_mask
# ) # )
var handle_input_ref var handle_input_ref
match self.state: match self.state:
"idle": "idle":
handle_input_ref = funcref(self, "handle_idle_input") handle_input_ref = funcref(self, "handle_idle_input")
"duck": "duck":
handle_input_ref = funcref(self, "handle_duck_input") handle_input_ref = funcref(self, "handle_duck_input")
"walk": "duck_walk":
handle_input_ref = funcref(self, "handle_walk_input") handle_input_ref = funcref(self, "handle_duck_input")
"run": "walk":
handle_input_ref = funcref(self, "handle_run_input") handle_input_ref = funcref(self, "handle_walk_input")
"jump": "run":
handle_input_ref = funcref(self, "handle_jump_input") handle_input_ref = funcref(self, "handle_run_input")
"fall": "jump":
handle_input_ref = funcref(self, "handle_fall_input") handle_input_ref = funcref(self, "handle_jump_input")
"wallslide": "fall":
handle_input_ref = funcref(self, "handle_wallslide_input") handle_input_ref = funcref(self, "handle_fall_input")
_: "wallslide":
print("don't panik") handle_input_ref = funcref(self, "handle_wallslide_input")
var texture = $"%BubbleShieldViewport".get_texture() _:
$"%Blobby3DEffects".texture = texture print("don't panik")
var direction = get_horizontal_direction() var texture = $"%BubbleShieldViewport".get_texture()
didTurn = false $"%Blobby3DEffects".texture = texture
var direction = get_horizontal_direction()
did_turn = false
#TODO use blendspace value 0 for turn animations instead of this? #TODO use blendspace value 0 for turn animations instead of this?
# Can you make the blendspace animation play out till end? # Can you make the blendspace animation play out till end?
if direction.x < 0 && facing == 1: if direction.x < 0 && facing == 1:
didTurn = true did_turn = true
facing = -1 facing = -1
elif direction.x > 0 && facing == -1: elif direction.x > 0 && facing == -1:
didTurn = true did_turn = true
facing = 1 facing = 1
#TODO Yeah... deal with it #TODO Yeah... deal with it
if didTurn: if did_turn:
_set_blendspaces_direction(facing) _set_blendspaces_direction(facing)
_trigger_turn_animation() _trigger_turn_animation()
parent.velocity = handle_input_ref.call_func(delta, direction) parent.velocity = handle_input_ref.call_func(delta, direction)
parent.execute_movement() parent.execute_movement()
func handle_idle_input(delta, direction) -> Vector2: func handle_idle_input(delta, direction) -> Vector2:
return parent.handle_grounded_movement(delta, direction) return parent.handle_grounded_movement(delta, direction)
func handle_duck_input(delta, direction) -> Vector2: func handle_duck_input(delta, direction) -> Vector2:
return parent.handle_duck_movement(delta, direction) return parent.handle_duck_movement(delta, direction)
func handle_walk_input(delta, direction) -> Vector2: func handle_walk_input(delta, direction) -> Vector2:
return parent.handle_grounded_movement(delta, direction) return parent.handle_grounded_movement(delta, direction)
func handle_run_input(delta, direction) -> Vector2: func handle_run_input(delta, direction) -> Vector2:
return parent.handle_grounded_movement(delta, direction) return parent.handle_grounded_movement(delta, direction)
func handle_jump_input(delta, direction) -> Vector2: func handle_jump_input(delta, direction) -> Vector2:
return parent.handle_jump_movement(delta, direction) return parent.handle_jump_movement(delta, direction)
func handle_fall_input(delta, direction) -> Vector2: func handle_fall_input(delta, direction) -> Vector2:
return parent.handle_fall_movement(delta, direction) return parent.handle_fall_movement(delta, direction)
func handle_wallslide_input(delta, direction) -> Vector2: func handle_wallslide_input(delta, direction) -> Vector2:
return parent.handle_wallslide_movement(delta, direction) return parent.handle_wallslide_movement(delta, direction)
func get_horizontal_direction() -> Vector2: func get_horizontal_direction() -> Vector2:
#TODO Check if this is fixed yet -> Seems like it, idk what i meant by that lul xd roflcopter lmao wtfbbq1!!!11! #TODO Check if this is fixed yet -> Seems like it, idk what i meant by that lul xd roflcopter lmao wtfbbq1!!!11!
if Input.is_action_pressed("move_right"): if Input.is_action_pressed("move_right"):
return Vector2(1, 0) return Vector2(1, 0)
if Input.is_action_pressed("move_left"): if Input.is_action_pressed("move_left"):
return Vector2(-1, 0) return Vector2(-1, 0)
return Vector2(0,0); return Vector2(0, 0)
# Determines which state should be active at the moment # Determines which state should be active at the moment
func _get_transition(delta): func _get_transition(_delta):
parent.get_node("StateLabel").text = ( parent.get_node("StateLabel").text = (self.state + " x vel:" + String(round(parent.velocity.x)))
self.state # + " y vel/10:"
+ " x vel:" # + String(round(parent.velocity.y / 10))
+ String(round(parent.velocity.x)) var new_state
# + " y vel/10:" if !parent.is_on_floor():
# + String(round(parent.velocity.y / 10)) if parent.velocity.y < -1:
) was_coyote_hanging = false
var new_state parent.jump_buffer_filled = false
if !parent.is_on_floor(): new_state = states.jump
if parent.velocity.y < -1:
was_coyote_hanging = false
parent.jump_buffer_filled = false
new_state = states.jump
# TODO SOMETHING IS SETTING Y SLIGHTLY BELOW ZERO WHEN MOVING HORIZONTALLY??? # TODO SOMETHING IS SETTING Y SLIGHTLY BELOW ZERO WHEN MOVING HORIZONTALLY???
if parent.velocity.y >= -0.01: if parent.velocity.y >= -0.01:
new_state = states.fall new_state = states.fall
if parent.is_touching_wall_completely(): if parent.is_touching_wall_completely():
anim_tree.set("parameters/wallslideToJump/blend_position", parent.wall_touch_direction) anim_tree.set(
anim_tree.set("parameters/wallsliding/blend_position", parent.wall_touch_direction) "parameters/wallslideToJump/blend_position", parent.wall_touch_direction
new_state = states.wallslide )
# Begins coyote time only if walking from ledge anim_tree.set("parameters/wallsliding/blend_position", parent.wall_touch_direction)
elif [states.walk, states.run].has(self.state) && !was_coyote_hanging: new_state = states.wallslide
$CoyoteTimer.start() # Begins coyote time only if walking from ledge
coyote_hanging = true elif [states.walk, states.run].has(self.state) && !was_coyote_hanging:
was_coyote_hanging = true $CoyoteTimer.start()
coyote_hanging = true
was_coyote_hanging = true
if new_state == states.fall && $JumpBufferTimer.is_stopped(): if new_state == states.fall && $JumpBufferTimer.is_stopped():
$JumpBufferTimer.start() $JumpBufferTimer.start()
# It's important to check this here and not set by event (order) # It's important to check this here and not set by event (order)
if ( if $CoyoteTimer.is_stopped() || [states.idle, states.jump].has(self.state):
$CoyoteTimer.is_stopped() coyote_hanging = false
|| [states.idle, states.jump].has(self.state) if coyote_hanging:
): new_state = self.state
coyote_hanging = false
if coyote_hanging:
new_state = self.state
elif abs(parent.velocity.x) > 5: elif abs(parent.velocity.x) > 5:
was_coyote_hanging = false was_coyote_hanging = false
if Input.is_action_pressed("boost_move"): if Input.is_action_pressed("boost_move"):
new_state = states.run new_state = states.run
# TODO Walking when stopping and not pressing anything? # TODO Walking when stopping and not pressing anything?
else: else:
new_state = states.walk new_state = states.walk
if Input.is_action_pressed("duck"): if Input.is_action_pressed("duck"):
new_state = states.duck new_state = states.duck_walk
else: else:
was_coyote_hanging = false was_coyote_hanging = false
new_state = states.idle new_state = states.idle
if Input.is_action_pressed("duck"): if Input.is_action_pressed("duck"):
new_state = states.duck new_state = states.duck
if new_state != self.state: if new_state != self.state:
state_time = 0 state_time = 0
return new_state return new_state
init_boost = false init_boost = false
return null return null
func _enter_state(new_state, old_state): func _enter_state(new_state, old_state):
if old_state == "idle" && (new_state == "walk" || new_state == "run"): if old_state == "idle" && (new_state == "walk" || new_state == "run"):
init_boost = true init_boost = true
init_boost_type = old_state + "_" + new_state init_boost_type = old_state + "_" + new_state
else: else:
init_boost = false init_boost = false
init_boost_type = "" init_boost_type = ""
if(new_state == "run"): if new_state == "run":
running_particles.emitting = true running_particles.emitting = true
if(new_state == "jump"): if new_state == "jump":
jump_point_particles.position.x = 0 if facing == 1 else 24 jump_point_particles.position.x = 0 if facing == 1 else 24
jump_point_particles.emitting = true jump_point_particles.emitting = true
jump_point_particles.restart() jump_point_particles.restart()
if !["run", "walk", "idle", "duck"].has(old_state) && parent.is_on_floor():
emit_signal("got_grounded")
scene_audio.play_parallel_sound(
"res://assets/sounds/landingMedHard.ogg", -15.0, true, 1.0, 0.1
)
if !["run", "walk", "idle", "duck"].has(old_state) && parent.is_on_floor(): match new_state:
emit_signal("got_grounded") states.walk:
scene_audio.play_parallel_sound("res://assets/sounds/landingMedHard.ogg", # TODO I need this when there is a turn happening between two different states
-15.0, true, 1.0, 0.1) # TODO Queue animation and only play if state time is exceeded, to not play animation on too small jumps/short wallslides
if old_state == states.idle && did_turn:
anim_state_playback.travel("idleTurn")
match new_state: else:
states.walk: anim_state_playback.travel("walking")
# TODO I need this when there is a turn happening between two different states scene_audio.play_sound(footstep_sound, -5.0, true)
# TODO Queue animation and only play if state time is exceeded, to not play animation on too small jumps/short wallslides states.idle:
if old_state == states.idle && didTurn: anim_state_playback.travel("idling")
anim_state_playback.travel("idleTurn") states.duck:
else: anim_state_playback.travel("ducking")
anim_state_playback.travel("walking") states.duck_walk:
scene_audio.play_sound(footstep_sound, -3.0, true, 1.6) anim_state_playback.travel("ducking")
states.idle: scene_audio.play_sound(footstep_sound, -5.0, true)
anim_state_playback.travel("idling") states.jump:
states.duck: if parent.rotation == 0 || !parent.snap_possible:
anim_state_playback.travel("ducking") if old_state == states.run:
states.jump: anim_state_playback.travel("runToJump")
if parent.rotation == 0 || !parent.snap_possible: else:
if old_state == states.run: anim_state_playback.travel("jumping")
anim_state_playback.travel("runToJump") states.fall:
else: if parent.rotation == 0 || !parent.snap_possible:
anim_state_playback.travel("jumping") anim_state_playback.travel("falling")
states.fall: states.run:
if parent.rotation == 0 || !parent.snap_possible: anim_state_playback.travel("running")
anim_state_playback.travel("falling") scene_audio.play_sound(footstep_sound, -5.0, true, 1.5)
states.run: states.wallslide:
anim_state_playback.travel("running") # TODO When the hitbox transforms from wallslide to idle, blobby hangs in the air and that triggers the wallslide on landing
scene_audio.play_sound(footstep_sound, -3.0, true, 2.0) if old_state != states.idle:
states.wallslide: anim_state_playback.travel("wallsliding")
# TODO When the hitbox transforms from wallslide to idle, blobby hangs in the air and that triggers the wallslide on landing
if(old_state != states.idle):
anim_state_playback.travel("wallsliding")
func _exit_state(_old_state, _new_state): func _exit_state(_old_state, _new_state):
scene_audio.stop_sound() scene_audio.stop_sound()
if(_old_state == "run"): if _old_state == "run":
running_particles.emitting = false running_particles.emitting = false
func _set_blendspaces_direction(value): func _set_blendspaces_direction(value):
running_particles.texture = run_dust_res if facing == -1 else run_dust_left_res running_particles.texture = run_dust_res if facing == -1 else run_dust_left_res
running_particles.scale.x = facing running_particles.scale.x = facing
anim_tree.set("parameters/ducking/blend_position", value) anim_tree.set("parameters/ducking/blend_position", value)
anim_tree.set("parameters/falling/blend_position", value) anim_tree.set("parameters/falling/blend_position", value)
anim_tree.set("parameters/idling/blend_position", value) anim_tree.set("parameters/idling/blend_position", value)
anim_tree.set("parameters/jumpToFall/blend_position", value) anim_tree.set("parameters/jumpToFall/blend_position", value)
anim_tree.set("parameters/jumping/blend_position", value) anim_tree.set("parameters/jumping/blend_position", value)
anim_tree.set("parameters/runToJump/blend_position", value) anim_tree.set("parameters/runToJump/blend_position", value)
anim_tree.set("parameters/running/blend_position", value) anim_tree.set("parameters/running/blend_position", value)
anim_tree.set("parameters/turnToRun/blend_position", value) anim_tree.set("parameters/turnToRun/blend_position", value)
anim_tree.set("parameters/walking/blend_position", value) anim_tree.set("parameters/walking/blend_position", value)
func _trigger_turn_animation(): func _trigger_turn_animation():
match self.state: match self.state:
states.duck: states.duck:
anim_state_playback.travel("duckTurn") anim_state_playback.travel("duckTurn")
states.walk: states.walk:
anim_state_playback.travel("idleTurn") anim_state_playback.travel("idleTurn")
states.idle: states.idle:
anim_state_playback.travel("idleTurn") anim_state_playback.travel("idleTurn")
func _on_JumpBufferTimer_timeout() -> void: func _on_JumpBufferTimer_timeout() -> void:
parent.jump_buffer_filled = false parent.jump_buffer_filled = false

View File

@ -11,8 +11,8 @@ var states = {}
onready var parent = get_parent() onready var parent = get_parent()
# Scene Singletons # Scene Singletons
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
# Basic process flow for every SM # Basic process flow for every SM

View File

@ -1,6 +1,6 @@
extends AudibleButton extends AudibleButton
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
func _on_button_up() -> void: func _on_button_up() -> void:
get_tree().paused = false get_tree().paused = false

View File

@ -5,14 +5,14 @@ onready var current_scene := get_tree().get_current_scene()
onready var pause_overlay: ColorRect = $HUDOverlay onready var pause_overlay: ColorRect = $HUDOverlay
onready var timer: Label = $HUDOverlay/GetBackTimer onready var timer: Label = $HUDOverlay/GetBackTimer
onready var currency: Label = $HUDOverlay/Currency onready var currency: Label = $HUDOverlay/Currency
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
func _ready(): func _ready():
#TODO Connect what HOW? #TODO Connect what HOW?
signalManager.connect("currency_updated", self, "update_interface") signal_manager.connect("currency_updated", self, "update_interface")
signalManager.connect("terminal_activated", self, "start_timer") signal_manager.connect("terminal_activated", self, "start_timer")
update_interface() update_interface()
func _process(delta): func _process(delta):
@ -35,8 +35,8 @@ func _zoom_timer() -> void:
func update_interface() -> void: func update_interface() -> void:
var wallet = GlobalState.gsr.wallet var wallet = GlobalState.gsr.wallet
if levelState != null: if level_state != null:
wallet += levelState.currency wallet += level_state.currency
currency.text = "Orbs: %s" % wallet currency.text = "Orbs: %s" % wallet

View File

@ -1,7 +1,7 @@
extends AudibleButton extends AudibleButton
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
func _on_button_up() -> void: func _on_button_up() -> void:
signalManager.emit_signal("game_paused", false) signal_manager.emit_signal("game_paused", false)

View File

@ -1,8 +1,8 @@
extends Control extends Control
# Smart ist es die notwendigen Resourcen vor dem Skriptstart zu laden # Smart ist es die notwendigen Resourcen vor dem Skriptstart zu laden
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
onready var current_scene := get_tree().get_current_scene() onready var current_scene := get_tree().get_current_scene()
onready var pause_overlay: = get_node("PauseOverlay") onready var pause_overlay: = get_node("PauseOverlay")
onready var pause_title: Label = get_node("PauseOverlay/Title") onready var pause_title: Label = get_node("PauseOverlay/Title")
@ -11,11 +11,11 @@ var paused := false setget set_paused
var block_ui_cancel = false var block_ui_cancel = false
func _ready(): func _ready():
#signalManager.connect("player_died", self, "_on_GlobalState_player_died") #signal_manager.connect("player_died", self, "_on_GlobalState_player_died")
$ControlsMenu.visible = false $ControlsMenu.visible = false
$ControlsMenu.set_process_input(false) $ControlsMenu.set_process_input(false)
$AudioMenu.set_process_input(false) $AudioMenu.set_process_input(false)
signalManager.connect("game_paused", self, "set_paused") signal_manager.connect("game_paused", self, "set_paused")
pass pass
func open_audio_menu(): func open_audio_menu():

View File

@ -1,12 +1,12 @@
extends AudibleButton extends AudibleButton
onready var selected_screen_base_path: String = "res://src/UserInterface/Screens" onready var selected_screen_base_path: String = "res://src/UserInterface/Screens"
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
onready var mapper := $"%InputMapper" onready var mapper := $"%InputMapper"
export(String, FILE) var next_screen_path: = "" export(String, FILE) var next_screen_path: = ""
func _on_button_up() -> void: func _on_button_up() -> void:
signalManager.connect("savemanager_saved",self,"was_saved_now_quit") signal_manager.connect("savemanager_saved",self,"was_saved_now_quit")
mapper.commit_to_changes() mapper.commit_to_changes()
SaveManager.save_default() SaveManager.save_default()

View File

@ -1,12 +1,12 @@
extends AudibleButton extends AudibleButton
onready var selected_screen_base_path: String = "res://src/UserInterface/Screens" onready var selected_screen_base_path: String = "res://src/UserInterface/Screens"
onready var signalManager := $"%SignalManager" onready var signal_manager := $"%SignalManager"
onready var mapper := $"%InputMapper" onready var mapper := $"%InputMapper"
export(String, FILE) var next_screen_path: = "" export(String, FILE) var next_screen_path: = ""
func _on_button_up() -> void: func _on_button_up() -> void:
signalManager.connect("savemanager_saved",self,"was_saved_now_quit") signal_manager.connect("savemanager_saved",self,"was_saved_now_quit")
mapper.commit_to_changes() mapper.commit_to_changes()
SaveManager.save_default() SaveManager.save_default()

View File

@ -1,6 +1,6 @@
extends Label extends Label
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
func _ready(): func _ready():
var wallet = 0 var wallet = 0

View File

@ -7,7 +7,7 @@ export var velocity = Vector2(0.309,0.309)
export var press_limit = 3 export var press_limit = 3
export var initial_wait_time:float = 0.0 export var initial_wait_time:float = 0.0
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState") onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
onready var cam = null onready var cam = null
onready var blobby_state: AnimationNodeStateMachinePlayback = null onready var blobby_state: AnimationNodeStateMachinePlayback = null
onready var button1 = $Button1 onready var button1 = $Button1
@ -42,8 +42,8 @@ func check_goal_state() -> void:
func _ready() -> void: func _ready() -> void:
# Should save itself into the progress dictionary upon creation # Should save itself into the progress dictionary upon creation
if(!OS.is_debug_build()): if(!OS.is_debug_build()):
levelState.register_tutorial(tutorial_text) level_state.register_tutorial(tutorial_text)
if (!levelState.needs_tutorial(tutorial_text)): queue_free() if (!level_state.needs_tutorial(tutorial_text)): queue_free()
if initial_wait_time > 0.0: if initial_wait_time > 0.0:
var timer = Timer.new() var timer = Timer.new()
add_child(timer) add_child(timer)
@ -107,7 +107,7 @@ func _lesson_learned(animation_name: String) -> void:
if(animation_name != "cease_4_exist"): return if(animation_name != "cease_4_exist"): return
moving = false moving = false
if(!OS.is_debug_build()): if(!OS.is_debug_build()):
levelState.absolved_tutorial(tutorial_text) level_state.absolved_tutorial(tutorial_text)
blobby_state = null blobby_state = null
queue_free() queue_free()

View File

@ -267,7 +267,7 @@ shape = SubResource( 6 )
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
stream = ExtResource( 7 ) stream = ExtResource( 7 )
volume_db = -14.439 volume_db = -17.211
bus = "UI" bus = "UI"
[connection signal="area_entered" from="Area" to="." method="_on_Area_area_entered"] [connection signal="area_entered" from="Area" to="." method="_on_Area_area_entered"]

View File

@ -1,13 +1,9 @@
extends Node2D extends Node2D
export var action = "move_right" export var action = "move_right"
export var tutorial_text = "" export var tutorial_text = ""
export var velocity = Vector2(0.309,0.309) export var velocity = Vector2(0.309, 0.309)
export var press_limit = 3 export var press_limit = 3
export var initial_wait_time:float = 0.0 export var initial_wait_time: float = 0.0
onready var levelState := get_tree().root.get_child(4).get_node("%LevelState")
onready var cam = null
onready var button = $Button
var screen_size: Vector2 var screen_size: Vector2
var tex_size: Vector2 var tex_size: Vector2
@ -16,97 +12,124 @@ var moving = false
var tutorial_begun = false var tutorial_begun = false
var tutorial_area_entered = false var tutorial_area_entered = false
onready var level_state := get_tree().root.get_child(4).get_node("%LevelState")
onready var cam = null
onready var button = $Button
func _unhandled_input(event: InputEvent) -> void: func _unhandled_input(event: InputEvent) -> void:
if(event.is_action_pressed(action)): if event.is_action_pressed(action):
press_limit -= 1 press_limit -= 1
if press_limit == 0 : if press_limit == 0:
if visible: if visible:
$Label.visible = false $Label.visible = false
$TextureRect.visible = false $TextureRect.visible = false
$TextureRect2.visible = false $TextureRect2.visible = false
$AudioStreamPlayer.play() $AudioStreamPlayer.play()
$AnimationPlayer.play("cease_4_exist") $AnimationPlayer.play("cease_4_exist")
func _ready() -> void: func _ready() -> void:
# Should save itself into the progress dictionary upon creation # Should save itself into the progress dictionary upon creation
if(!OS.is_debug_build()): if !OS.is_debug_build():
levelState.register_tutorial(tutorial_text) level_state.register_tutorial(tutorial_text)
if (!levelState.needs_tutorial(tutorial_text)): queue_free() if !level_state.needs_tutorial(tutorial_text):
if initial_wait_time > 0.0: queue_free()
var timer = Timer.new() if initial_wait_time > 0.0:
add_child(timer) var timer = Timer.new()
timer.wait_time = initial_wait_time add_child(timer)
timer.one_shot = true timer.wait_time = initial_wait_time
timer.connect("timeout",self,"finished_waiting") timer.one_shot = true
timer.start() timer.connect("timeout", self, "finished_waiting")
$Button/ControllerButton.path = action timer.start()
$Label.text = tutorial_text $Button/ControllerButton.path = action
button.texture = $Button/ControllerButton.icon $Label.text = tutorial_text
button.scale.x = 0.5 button.texture = $Button/ControllerButton.icon
button.scale.y = 0.5 button.scale.x = 0.5
tex_size = Vector2(button.texture.get_width()/2, button.texture.get_height()/2) * button.scale * 0.75 button.scale.y = 0.5
$Area/CollisionShape2D.shape.extents = tex_size tex_size = (
Vector2(button.texture.get_width() / 2, button.texture.get_height() / 2)
* button.scale
* 0.75
)
$Area/CollisionShape2D.shape.extents = tex_size
func finished_waiting() -> void: func finished_waiting() -> void:
if(tutorial_area_entered): start_tutorial() if tutorial_area_entered:
start_tutorial()
func _physics_process(delta: float) -> void:
if(cam == null):
cam = get_tree().root.get_child(4).get_node("%BlobbyCam")
return
if(moving == false): return
button.texture = $Button/ControllerButton.icon
# TODO process less in each frame
var up_left_pos = cam.get_global_transform().affine_inverse() * (position - tex_size * self.scale)
var down_right_pos = cam.get_global_transform().affine_inverse() * (position + tex_size * self.scale)
if up_left_pos.x <= cam.screen_left.x: func _physics_process(_delta: float) -> void:
velocity.x = abs(velocity.x) if cam == null:
elif down_right_pos.x >= cam.screen_right.x: cam = get_tree().root.get_child(4).get_node("%BlobbyCam")
velocity.x = -abs(velocity.x) return
if up_left_pos.y <= cam.screen_top.y: # TODO process less in each frame
velocity.y = abs(velocity.y) if moving == false:
elif down_right_pos.y >= cam.screen_bottom.y: return
velocity.y = -abs(velocity.y)
self.position += velocity # TODO process less in each frame
button.texture = $Button/ControllerButton.icon
# TODO process less in each frame
var up_left_pos = (
cam.get_global_transform().affine_inverse()
* (position - tex_size * self.scale)
)
var down_right_pos = (
cam.get_global_transform().affine_inverse()
* (position + tex_size * self.scale)
)
if up_left_pos.x <= cam.screen_left.x:
velocity.x = abs(velocity.x)
elif down_right_pos.x >= cam.screen_right.x:
velocity.x = -abs(velocity.x)
if up_left_pos.y <= cam.screen_top.y:
velocity.y = abs(velocity.y)
elif down_right_pos.y >= cam.screen_bottom.y:
velocity.y = -abs(velocity.y)
self.position += velocity
func _on_Area_area_entered(area: Area2D) -> void: func _on_Area_area_entered(area: Area2D) -> void:
if !area.get_parent().visible: if !area.get_parent().visible:
return return
var d = area.global_position - position var d = area.global_position - position
print(d) print(d)
if(abs(d.y) > tex_size.y * 2 - 1): if abs(d.y) > tex_size.y * 2 - 1:
velocity.y *= -1 velocity.y *= -1
pass else:
else: velocity.x *= -1
velocity.x *=-1
func _lesson_learned(animation_name: String) -> void: func _lesson_learned(animation_name: String) -> void:
if(animation_name != "cease_4_exist"): return if animation_name != "cease_4_exist":
moving = false return
if(!OS.is_debug_build()): moving = false
levelState.absolved_tutorial(tutorial_text) if !OS.is_debug_build():
queue_free() level_state.absolved_tutorial(tutorial_text)
queue_free()
func start_tutorial(): func start_tutorial():
var rng = RandomNumberGenerator.new() var rng = RandomNumberGenerator.new()
rng.randomize() rng.randomize()
position.x += rng.randf_range(-50, 50) position.x += rng.randf_range(-50, 50)
position.y += rng.randf_range(-50, 50) position.y += rng.randf_range(-50, 50)
velocity.x = velocity.x * sign(rng.randf_range(-1,1)) velocity.x = velocity.x * sign(rng.randf_range(-1, 1))
velocity.y = velocity.y * sign(rng.randf_range(-1,1)) velocity.y = velocity.y * sign(rng.randf_range(-1, 1))
tutorial_begun = true tutorial_begun = true
visible = true visible = true
moving = true moving = true
func _on_StartTutorialArea_area_entered(area: Area2D) -> void:
tutorial_area_entered = true
if(tutorial_begun || initial_wait_time > 0): return
start_tutorial()
# Erkenne ob der Spieler die Aktion für die das Tutorial ist schon kann func _on_StartTutorialArea_area_entered(_area: Area2D) -> void:
# Wenn der Spieler den Tutorialbereich betritte spawne das Thingy random auf dem Screen tutorial_area_entered = true
# Füge zwei Inputs zusammen zu einem Thingy if tutorial_begun || initial_wait_time > 0:
return
start_tutorial()
# Erkenne ob der Spieler die Aktion für die das Tutorial ist schon kann
# Wenn der Spieler den Tutorialbereich betritte spawne das Thingy random auf dem Screen
# Füge zwei Inputs zusammen zu einem Thingy

View File

@ -222,7 +222,7 @@ shape = SubResource( 6 )
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
stream = ExtResource( 1 ) stream = ExtResource( 1 )
volume_db = -14.776 volume_db = -17.477
bus = "UI" bus = "UI"
[connection signal="area_entered" from="Area" to="." method="_on_Area_area_entered"] [connection signal="area_entered" from="Area" to="." method="_on_Area_area_entered"]

View File

@ -1,6 +1,6 @@
extends Node extends Node
onready var signalManager := get_tree().root.get_child(4).get_node("%SignalManager") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager")
onready var levelName := get_tree().current_scene.filename onready var levelName := get_tree().current_scene.filename
#TODO Easteregg pls #TODO Easteregg pls
@ -13,8 +13,8 @@ var is_dead: = false setget set_dead
func _ready() -> void: func _ready() -> void:
GlobalState.gsr.last_played_level = levelName GlobalState.gsr.last_played_level = levelName
SaveManager.save_default() SaveManager.save_default()
signalManager.connect("level_completed", self, "_on_level_completed") signal_manager.connect("level_completed", self, "_on_level_completed")
signalManager.connect("player_died", self, "player_dying") signal_manager.connect("player_died", self, "player_dying")
func reset() -> void: func reset() -> void:
deaths = 0 deaths = 0
@ -26,7 +26,7 @@ func reset() -> void:
func set_currency(value: int) -> void: func set_currency(value: int) -> void:
currency = value currency = value
signalManager.emit_signal("currency_updated") signal_manager.emit_signal("currency_updated")
func set_deaths(value: int) -> void: func set_deaths(value: int) -> void:
deaths = value deaths = value

View File

@ -1,58 +1,81 @@
extends Node extends Node
onready var players: Dictionary = {}
onready var static_player: AudioStreamPlayer = $StaticPlayer
var disposable_player: AudioStreamPlayer var disposable_player: AudioStreamPlayer
onready var players: Dictionary = {}
onready var static_player: AudioStreamPlayer = $StaticPlayer
# Plays sound with the static player, interrupting sounds if currently playing # Plays sound with the static player, interrupting sounds if currently playing
func play_sound(sound_name: String, attenuation: float = 0.0, random_pitch = false, func play_sound(
pitch = 1.0, start_time = 0.0, bus: String = "Effects", singleton = false) -> void: sound_name: String,
# TODO is it bad to grab the stream each time? attenuation: float = 0.0,
var stream = GlobalState.sound_library[sound_name] random_pitch = false,
if random_pitch: pitch = 1.0,
stream = AudioStreamRandomPitch.new() start_time = 0.0,
stream.audio_stream = GlobalState.sound_library[sound_name] bus: String = "Effects"
static_player.stream = stream ) -> void:
static_player.volume_db = attenuation # TODO is it bad to grab the stream each time?
static_player.bus = bus var stream = GlobalState.sound_library[sound_name]
static_player.pitch_scale = pitch if random_pitch:
static_player.play(start_time) stream = AudioStreamRandomPitch.new()
stream.audio_stream = GlobalState.sound_library[sound_name]
static_player.stream = stream
static_player.volume_db = attenuation
static_player.bus = bus
static_player.pitch_scale = pitch
static_player.stream_paused = false
static_player.play(start_time)
func stop_sound(): func stop_sound():
static_player.stop() static_player.stream_paused = true
# Mirrors the GlobalAudio Method which can play sounds across scenes # Mirrors the GlobalAudio Method which can play sounds across scenes
func play_parallel_sound(sound_name: String, attenuation: float = 0.0, random_pitch = false, func play_parallel_sound(
pitch = 1.0, start_time = 0.0, bus: String = "Effects", singleton = false) -> void: sound_name: String,
if singleton && players.has(sound_name): attenuation: float = 0.0,
return random_pitch = false,
var disposable_player = AudioStreamPlayer.new() pitch = 1.0,
add_child(disposable_player) start_time = 0.0,
var stream = GlobalState.sound_library[sound_name] bus: String = "Effects",
if random_pitch: singleton = false
stream = AudioStreamRandomPitch.new() ) -> void:
stream.audio_stream = GlobalState.sound_library[sound_name] if singleton && players.has(sound_name):
disposable_player.stream = stream return
disposable_player.volume_db = attenuation var disposable_player = AudioStreamPlayer.new()
disposable_player.bus = bus add_child(disposable_player)
disposable_player.pitch_scale = pitch var stream = GlobalState.sound_library[sound_name]
disposable_player.play(start_time) if random_pitch:
disposable_player.connect("finished", self, "dispose_player", [weakref(disposable_player)]) stream = AudioStreamRandomPitch.new()
players[sound_name] = weakref(disposable_player) stream.audio_stream = GlobalState.sound_library[sound_name]
disposable_player.stream = stream
disposable_player.volume_db = attenuation
disposable_player.bus = bus
disposable_player.pitch_scale = pitch
disposable_player.play(start_time)
disposable_player.connect("finished", self, "dispose_player", [weakref(disposable_player)])
players[sound_name] = weakref(disposable_player)
func dispose_parallel_player(player: WeakRef) -> void: func dispose_parallel_player(player: WeakRef) -> void:
if !player.get_ref(): return if !player.get_ref():
player.get_ref().queue_free() return
player.get_ref().queue_free()
func pause_parallel_sound(sound_name: String): func pause_parallel_sound(sound_name: String):
if players.has(sound_name) && players[sound_name].get_ref(): if players.has(sound_name) && players[sound_name].get_ref():
players[sound_name].set_stream_paused(true) players[sound_name].set_stream_paused(true)
func continue_parallel_sound(sound_name: String): func continue_parallel_sound(sound_name: String):
if players.has(sound_name) && players[sound_name].get_ref(): if players.has(sound_name) && players[sound_name].get_ref():
players[sound_name].set_stream_paused(false) players[sound_name].set_stream_paused(false)
func stop_parallel_sound(sound_name: String): func stop_parallel_sound(sound_name: String):
if players.has(sound_name) && players[sound_name].get_ref(): if players.has(sound_name) && players[sound_name].get_ref():
dispose_parallel_player(players[sound_name]) dispose_parallel_player(players[sound_name])
players.erase(sound_name) players.erase(sound_name)

View File

@ -1,12 +1,12 @@
[gd_scene load_steps=3 format=2] [gd_scene load_steps=3 format=2]
[ext_resource path="res://src/Utilities/SceneAudio.gd" type="Script" id=1] [ext_resource path="res://src/Utilities/SceneAudio.gd" type="Script" id=1]
[ext_resource path="res://assets/sounds/footsteps.ogg" type="AudioStream" id=2] [ext_resource path="res://assets/sounds/MONSTER_Cry_mono.wav" type="AudioStream" id=2]
[node name="SceneAudio" type="Node"] [node name="SceneAudio" type="Node2D"]
pause_mode = 2 pause_mode = 1
script = ExtResource( 1 ) script = ExtResource( 1 )
[node name="StaticPlayer" type="AudioStreamPlayer" parent="."] [node name="StaticPlayer" type="AudioStreamPlayer" parent="."]
stream = ExtResource( 2 ) stream = ExtResource( 2 )
pitch_scale = 1.62 volume_db = -16.455