feat: caterpillar sprite, vacuum sprite fix, level balance
This commit is contained in:
parent
5fe48cdf90
commit
522e472c4d
BIN
assets/enemy/Caterpilllar.aseprite
Normal file
BIN
assets/enemy/Caterpilllar.aseprite
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 586 B After Width: | Height: | Size: 604 B |
@ -9,11 +9,6 @@
|
||||
config_version=4
|
||||
|
||||
_global_script_classes=[ {
|
||||
"base": "AudioStreamPlayer",
|
||||
"class": "ACVoiceBox",
|
||||
"language": "GDScript",
|
||||
"path": "res://addons/ACVoicebox/ACVoicebox.gd"
|
||||
}, {
|
||||
"base": "KinematicBody2D",
|
||||
"class": "Actor",
|
||||
"language": "GDScript",
|
||||
@ -95,7 +90,6 @@ _global_script_classes=[ {
|
||||
"path": "res://src/StateMachines/StateMachine.gd"
|
||||
} ]
|
||||
_global_script_class_icons={
|
||||
"ACVoiceBox": "",
|
||||
"Actor": "",
|
||||
"AudibleButton": "",
|
||||
"AudibleCheckbox": "",
|
||||
|
||||
@ -20,14 +20,14 @@ var initial_velocity_dependence := 0.7
|
||||
var floor_friction := base_floor_friction
|
||||
# TODO Mixing Vectors and ints is questionable
|
||||
var max_velocity := {
|
||||
"walk": 120,
|
||||
"run": 160,
|
||||
"jump": Vector2(120, 420),
|
||||
"fall": Vector2(120, 420),
|
||||
"walljump": 200,
|
||||
"idle": 12000,
|
||||
"duck": 165,
|
||||
"duck_walk": 165
|
||||
"walk": 120,
|
||||
"run": 160,
|
||||
"jump": Vector2(120, 420),
|
||||
"fall": Vector2(120, 420),
|
||||
"walljump": 200,
|
||||
"idle": 12000,
|
||||
"duck": 165,
|
||||
"duck_walk": 165
|
||||
}
|
||||
# x is applied directly to velocity and y is multiplied with acceleration
|
||||
var duck_boost = Vector2(2, 0.75)
|
||||
@ -37,15 +37,15 @@ var init_acceleration_force := {"": 0, "idle_walk": 4181, "idle_run": 5765, "wal
|
||||
# Oriented around deltas of 0.0166666...s
|
||||
# newtonmeters is the unit
|
||||
var acceleration_force := {
|
||||
"walk": Vector2(1800, 1300),
|
||||
"fall": Vector2(1800, 1050),
|
||||
"jump": Vector2(1800, 0),
|
||||
"idle": Vector2(1800, 1233),
|
||||
"duck": Vector2(500, 1300),
|
||||
"duck_walk": Vector2(500, 1300),
|
||||
"run": Vector2(2500, 1400),
|
||||
"walljump": Vector2(600, 1050),
|
||||
"air_strafe": Vector2(333, 2000)
|
||||
"walk": Vector2(1800, 1300),
|
||||
"fall": Vector2(1800, 1050),
|
||||
"jump": Vector2(1800, 0),
|
||||
"idle": Vector2(1800, 1300),
|
||||
"duck": Vector2(500, 1300),
|
||||
"duck_walk": Vector2(500, 1300),
|
||||
"run": Vector2(2500, 1400),
|
||||
"walljump": Vector2(600, 1050),
|
||||
"air_strafe": Vector2(333, 2000)
|
||||
}
|
||||
var velocity := Vector2.ZERO
|
||||
var max_air_strafe_charges := 0
|
||||
|
||||
@ -28,489 +28,489 @@ var shielded = false
|
||||
|
||||
|
||||
func execute_movement() -> void:
|
||||
if level_state.is_dead:
|
||||
return
|
||||
var snap = Vector2.DOWN * 128
|
||||
var center_floor_rot = 0
|
||||
var floor_rot = 0
|
||||
var onfloor = is_on_floor()
|
||||
if level_state.is_dead:
|
||||
return
|
||||
var snap = Vector2.DOWN * 128
|
||||
var center_floor_rot = 0
|
||||
var floor_rot = 0
|
||||
var onfloor = is_on_floor()
|
||||
|
||||
# get rotation of floor, compare collided floor with floor under center
|
||||
if onfloor:
|
||||
# TODO: Problem when correctly rotating?
|
||||
center_floor_rot = $SlopeRaycast.get_collision_normal().rotated(PI / 2).angle()
|
||||
floor_rot = get_floor_normal().rotated(PI / 2).angle()
|
||||
if abs(center_floor_rot) > PI / 4 + 0.1:
|
||||
center_floor_rot = floor_rot
|
||||
# snap when on slopes
|
||||
if (abs(floor_rot) > 0.1 || abs(center_floor_rot) > 0.1) && snap_possible:
|
||||
velocity = move_and_slide_with_snap(velocity.rotated(floor_rot), snap, FLOOR_NORMAL, true)
|
||||
# normal slide on flat floor
|
||||
else:
|
||||
velocity = move_and_slide(velocity.rotated(floor_rot), FLOOR_NORMAL)
|
||||
rotation = 0
|
||||
if (
|
||||
$SlopeRaycastLeft.is_colliding()
|
||||
&& $SlopeRaycastRight.is_colliding()
|
||||
&& $SlopeRaycast.is_colliding()
|
||||
):
|
||||
rotation = calculate_slope_rotation(onfloor)
|
||||
# rotate related to floor slope
|
||||
# Convert velocity back to local space.
|
||||
# TODO: Downward velocity should be increased by gravity
|
||||
velocity = velocity.rotated(-floor_rot) if snap_possible else velocity
|
||||
# get rotation of floor, compare collided floor with floor under center
|
||||
if onfloor:
|
||||
# TODO: Problem when correctly rotating?
|
||||
center_floor_rot = $SlopeRaycast.get_collision_normal().rotated(PI / 2).angle()
|
||||
floor_rot = get_floor_normal().rotated(PI / 2).angle()
|
||||
if abs(center_floor_rot) > PI / 4 + 0.1:
|
||||
center_floor_rot = floor_rot
|
||||
# snap when on slopes
|
||||
if (abs(floor_rot) > 0.1 || abs(center_floor_rot) > 0.1) && snap_possible:
|
||||
velocity = move_and_slide_with_snap(velocity.rotated(floor_rot), snap, FLOOR_NORMAL, true)
|
||||
# normal slide on flat floor
|
||||
else:
|
||||
velocity = move_and_slide(velocity.rotated(floor_rot), FLOOR_NORMAL)
|
||||
rotation = 0
|
||||
if (
|
||||
$SlopeRaycastLeft.is_colliding()
|
||||
&& $SlopeRaycastRight.is_colliding()
|
||||
&& $SlopeRaycast.is_colliding()
|
||||
):
|
||||
rotation = calculate_slope_rotation(onfloor)
|
||||
# rotate related to floor slope
|
||||
# Convert velocity back to local space.
|
||||
# TODO: Downward velocity should be increased by gravity
|
||||
velocity = velocity.rotated(-floor_rot) if snap_possible else velocity
|
||||
|
||||
|
||||
func calculate_duck_velocity(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2:
|
||||
var state = player_state_machine.state
|
||||
var out_vel := linear_velocity
|
||||
var velocity_direction = 1.0
|
||||
if velocity.x < 0:
|
||||
velocity_direction = -1.0
|
||||
var state = player_state_machine.state
|
||||
var out_vel := linear_velocity
|
||||
var velocity_direction = 1.0
|
||||
if velocity.x < 0:
|
||||
velocity_direction = -1.0
|
||||
|
||||
# TODO Improve this to separate crawling(slow) and sliding
|
||||
var deceleration_force = calculate_deceleration_force(_gravity, mass) * 0.333
|
||||
# TODO Improve this to separate crawling(slow) and sliding
|
||||
var deceleration_force = calculate_deceleration_force(_gravity, mass) * 0.333
|
||||
|
||||
# Slowing down movement when not controlling direction
|
||||
if is_equal_approx(direction.x, 0):
|
||||
# TODO Handle Deadzones
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x, deceleration_force * -1 * velocity_direction, mass, delta
|
||||
)
|
||||
if abs(out_vel.x) > abs(velocity.x):
|
||||
out_vel.x = 0
|
||||
else:
|
||||
# Reversing movement
|
||||
# When turning the opposite direction, friction is added to the opposite acceleration movement
|
||||
var reverse_move = is_reversing_horizontal_movement(direction)
|
||||
if reverse_move:
|
||||
# TODO dont put constants in here
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x, deceleration_force * -3.42 * velocity_direction, mass, delta
|
||||
)
|
||||
# Normal movement
|
||||
if abs(velocity.x) < max_velocity[state]:
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x, (acceleration_force[state].x) * direction.x, mass, delta
|
||||
)
|
||||
elif !reverse_move:
|
||||
out_vel.x = max_velocity[state] * direction.x
|
||||
# TODO is_on_dropThrough does the action, is that ok? yEs, MaAsTeR-ChAn
|
||||
# TODO Drop Through coyote time?
|
||||
if Input.is_action_just_pressed("jump") && is_on_dropThrough():
|
||||
return Vector2(out_vel.x, _gravity * delta)
|
||||
# Jumping when grounded or jump is buffered
|
||||
if Input.is_action_just_pressed("jump") || (jump_buffer_filled && is_on_floor()) || stomping:
|
||||
snap_possible = false
|
||||
return calculate_jump_velocity(velocity, delta, direction)
|
||||
# Slowing down movement when not controlling direction
|
||||
if is_equal_approx(direction.x, 0):
|
||||
# TODO Handle Deadzones
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x, deceleration_force * -1 * velocity_direction, mass, delta
|
||||
)
|
||||
if abs(out_vel.x) > abs(velocity.x):
|
||||
out_vel.x = 0
|
||||
else:
|
||||
# Reversing movement
|
||||
# When turning the opposite direction, friction is added to the opposite acceleration movement
|
||||
var reverse_move = is_reversing_horizontal_movement(direction)
|
||||
if reverse_move:
|
||||
# TODO dont put constants in here
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x, deceleration_force * -3.42 * velocity_direction, mass, delta
|
||||
)
|
||||
# Normal movement
|
||||
if abs(velocity.x) < max_velocity[state]:
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x, (acceleration_force[state].x) * direction.x, mass, delta
|
||||
)
|
||||
elif !reverse_move:
|
||||
out_vel.x = max_velocity[state] * direction.x
|
||||
# TODO is_on_dropThrough does the action, is that ok? yEs, MaAsTeR-ChAn
|
||||
# TODO Drop Through coyote time?
|
||||
if Input.is_action_just_pressed("jump") && is_on_dropThrough():
|
||||
return Vector2(out_vel.x, _gravity * delta)
|
||||
# Jumping when grounded or jump is buffered
|
||||
if Input.is_action_just_pressed("jump") || (jump_buffer_filled && is_on_floor()) || stomping:
|
||||
snap_possible = false
|
||||
return calculate_jump_velocity(velocity, delta, direction)
|
||||
|
||||
elif player_state_machine.coyote_hanging:
|
||||
out_vel.y = 0
|
||||
elif player_state_machine.coyote_hanging:
|
||||
out_vel.y = 0
|
||||
|
||||
else:
|
||||
out_vel.y = _gravity * delta
|
||||
else:
|
||||
out_vel.y = _gravity * delta
|
||||
|
||||
return out_vel
|
||||
return out_vel
|
||||
|
||||
|
||||
func is_on_dropThrough():
|
||||
var bodies: Array = $BlobbySkin.get_overlapping_bodies()
|
||||
for i in range(0, bodies.size()):
|
||||
if bodies[i].get_collision_mask_bit(7):
|
||||
set_collision_mask_bit(7, false)
|
||||
return true
|
||||
return false
|
||||
var bodies: Array = $BlobbySkin.get_overlapping_bodies()
|
||||
for i in range(0, bodies.size()):
|
||||
if bodies[i].get_collision_mask_bit(7):
|
||||
set_collision_mask_bit(7, false)
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func calculate_grounded_velocity(
|
||||
linear_velocity: Vector2, delta: float, direction: Vector2
|
||||
linear_velocity: Vector2, delta: float, direction: Vector2
|
||||
) -> Vector2:
|
||||
var state = player_state_machine.state
|
||||
var out_vel := linear_velocity
|
||||
var velocity_direction = 1.0
|
||||
if velocity.x < 0:
|
||||
velocity_direction = -1.0
|
||||
var state = player_state_machine.state
|
||||
var out_vel := linear_velocity
|
||||
var velocity_direction = 1.0
|
||||
if velocity.x < 0:
|
||||
velocity_direction = -1.0
|
||||
|
||||
var deceleration_force = calculate_deceleration_force(_gravity, mass)
|
||||
var deceleration_force = calculate_deceleration_force(_gravity, mass)
|
||||
|
||||
# Slowing down movement when not controlling direction
|
||||
if is_equal_approx(direction.x, 0):
|
||||
# TODO Handle Deadzones
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x, deceleration_force * -1 * velocity_direction, mass, delta
|
||||
)
|
||||
if abs(out_vel.x) > abs(velocity.x):
|
||||
out_vel.x = 0
|
||||
else:
|
||||
# Reversing movement
|
||||
# When turning the opposite direction, friction is added to the opposite acceleration movement
|
||||
var reverse_move = is_reversing_horizontal_movement(direction)
|
||||
if reverse_move:
|
||||
# TODO dont put constants in here
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x, deceleration_force * -3.42 * velocity_direction, mass, delta
|
||||
)
|
||||
# Normal movement
|
||||
if abs(velocity.x) < max_velocity[state]:
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x,
|
||||
(
|
||||
(
|
||||
acceleration_force[state].x
|
||||
+ (init_acceleration_force[init_boost_type] * int(init_boost))
|
||||
)
|
||||
* direction.x
|
||||
),
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
elif !reverse_move:
|
||||
out_vel.x = max_velocity[state] * direction.x
|
||||
# Jumping when grounded or jump is buffered
|
||||
if Input.is_action_just_pressed("jump") || (jump_buffer_filled && is_on_floor()) || stomping:
|
||||
snap_possible = false
|
||||
#velocity += get_floor_velocity() * 0.5
|
||||
return calculate_jump_velocity(velocity, delta, direction)
|
||||
# Slowing down movement when not controlling direction
|
||||
if is_equal_approx(direction.x, 0):
|
||||
# TODO Handle Deadzones
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x, deceleration_force * -1 * velocity_direction, mass, delta
|
||||
)
|
||||
if abs(out_vel.x) > abs(velocity.x):
|
||||
out_vel.x = 0
|
||||
else:
|
||||
# Reversing movement
|
||||
# When turning the opposite direction, friction is added to the opposite acceleration movement
|
||||
var reverse_move = is_reversing_horizontal_movement(direction)
|
||||
if reverse_move:
|
||||
# TODO dont put constants in here
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x, deceleration_force * -3.42 * velocity_direction, mass, delta
|
||||
)
|
||||
# Normal movement
|
||||
if abs(velocity.x) < max_velocity[state]:
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x,
|
||||
(
|
||||
(
|
||||
acceleration_force[state].x
|
||||
+ (init_acceleration_force[init_boost_type] * int(init_boost))
|
||||
)
|
||||
* direction.x
|
||||
),
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
elif !reverse_move:
|
||||
out_vel.x = max_velocity[state] * direction.x
|
||||
# Jumping when grounded or jump is buffered
|
||||
if Input.is_action_just_pressed("jump") || (jump_buffer_filled && is_on_floor()) || stomping:
|
||||
snap_possible = false
|
||||
#velocity += get_floor_velocity() * 0.5
|
||||
return calculate_jump_velocity(velocity, delta, direction)
|
||||
|
||||
elif player_state_machine.coyote_hanging:
|
||||
out_vel.y = 0
|
||||
elif player_state_machine.coyote_hanging:
|
||||
out_vel.y = 0
|
||||
|
||||
else:
|
||||
out_vel.y = _gravity * delta
|
||||
else:
|
||||
out_vel.y = _gravity * delta
|
||||
|
||||
return out_vel
|
||||
return out_vel
|
||||
|
||||
|
||||
# Determines if the player has reversed the steering direction
|
||||
# in reference to the current movement direction
|
||||
func is_reversing_horizontal_movement(direction: Vector2) -> bool:
|
||||
return (direction.x > 0 && velocity.x < 0) || (direction.x < 0 && velocity.x > 0)
|
||||
return (direction.x > 0 && velocity.x < 0) || (direction.x < 0 && velocity.x > 0)
|
||||
|
||||
|
||||
# Returns if the character is touching a wall with its whole body
|
||||
# Being able to touch a vertical surface over this length also makes it a qualified "wall"
|
||||
# Also sets wall_touch_direction
|
||||
func is_touching_wall_completely() -> bool:
|
||||
var value = true
|
||||
for left_raycast in left_wall_raycasts.get_children():
|
||||
wall_touch_direction = -1
|
||||
if !left_raycast.is_colliding():
|
||||
value = false
|
||||
continue
|
||||
if value == true:
|
||||
return value
|
||||
var value = true
|
||||
for left_raycast in left_wall_raycasts.get_children():
|
||||
wall_touch_direction = -1
|
||||
if !left_raycast.is_colliding():
|
||||
value = false
|
||||
continue
|
||||
if value == true:
|
||||
return value
|
||||
|
||||
value = true
|
||||
for right_raycast in right_wall_raycasts.get_children():
|
||||
wall_touch_direction = 1
|
||||
if !right_raycast.is_colliding():
|
||||
value = false
|
||||
continue
|
||||
return value
|
||||
value = true
|
||||
for right_raycast in right_wall_raycasts.get_children():
|
||||
wall_touch_direction = 1
|
||||
if !right_raycast.is_colliding():
|
||||
value = false
|
||||
continue
|
||||
return value
|
||||
|
||||
|
||||
func is_crushed() -> bool:
|
||||
var touching_left = false
|
||||
for left_raycast in left_wall_raycasts.get_children():
|
||||
if left_raycast.is_colliding():
|
||||
touching_left = true
|
||||
var touching_right = false
|
||||
for right_raycast in right_wall_raycasts.get_children():
|
||||
if right_raycast.is_colliding():
|
||||
touching_right = true
|
||||
return touching_left && touching_right
|
||||
var touching_left = false
|
||||
for left_raycast in left_wall_raycasts.get_children():
|
||||
if left_raycast.is_colliding():
|
||||
touching_left = true
|
||||
var touching_right = false
|
||||
for right_raycast in right_wall_raycasts.get_children():
|
||||
if right_raycast.is_colliding():
|
||||
touching_right = true
|
||||
return touching_left && touching_right
|
||||
|
||||
|
||||
# Attached to wall state is in the PlayerStateMachine
|
||||
func is_correct_walljump_input(direction: Vector2) -> bool:
|
||||
if is_touching_wall_completely():
|
||||
return (
|
||||
Input.is_action_pressed("jump")
|
||||
&& abs(direction.x + wall_touch_direction) < 1
|
||||
&& abs(direction.x + wall_touch_direction) >= 0
|
||||
)
|
||||
return false
|
||||
if is_touching_wall_completely():
|
||||
return (
|
||||
Input.is_action_pressed("jump")
|
||||
&& abs(direction.x + wall_touch_direction) < 1
|
||||
&& abs(direction.x + wall_touch_direction) >= 0
|
||||
)
|
||||
return false
|
||||
|
||||
|
||||
func is_correct_airstrafe_input() -> bool:
|
||||
return (
|
||||
air_strafe_charges > 0
|
||||
&& (Input.is_action_just_pressed("move_right") || Input.is_action_just_pressed("move_left"))
|
||||
)
|
||||
return (
|
||||
air_strafe_charges > 0
|
||||
&& (Input.is_action_just_pressed("move_right") || Input.is_action_just_pressed("move_left"))
|
||||
)
|
||||
|
||||
|
||||
# Calculates the force of the ground friction
|
||||
func calculate_deceleration_force(_gravity: float, mass: float) -> float:
|
||||
return floor_friction * _gravity * mass
|
||||
return floor_friction * _gravity * mass
|
||||
|
||||
|
||||
func calculate_stomp_velocity(delta: float) -> float:
|
||||
var v = 0
|
||||
if Input.is_action_pressed("jump"):
|
||||
v += stomp_feedback
|
||||
# print(stomp_time)
|
||||
stomp_time -= delta
|
||||
# print(stomp_time)
|
||||
if stomp_time <= 0:
|
||||
# print("stomping over")
|
||||
stomping = false
|
||||
stomp_time = init_stomp_time
|
||||
return v
|
||||
var v = 0
|
||||
if Input.is_action_pressed("jump"):
|
||||
v += stomp_feedback
|
||||
# print(stomp_time)
|
||||
stomp_time -= delta
|
||||
# print(stomp_time)
|
||||
if stomp_time <= 0:
|
||||
# print("stomping over")
|
||||
stomping = false
|
||||
stomp_time = init_stomp_time
|
||||
return v
|
||||
|
||||
|
||||
func calculate_jump_velocity(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2:
|
||||
var state = player_state_machine.state
|
||||
var additive_jump_force = velocity_jump_boost_ratio * abs(velocity.x) * mass
|
||||
#TODO Single out stomping and make betta
|
||||
#TODO too much force intially and too high with frog jump
|
||||
if stomping:
|
||||
additive_jump_force += calculate_stomp_velocity(delta)
|
||||
var state = player_state_machine.state
|
||||
var additive_jump_force = velocity_jump_boost_ratio * abs(velocity.x) * mass
|
||||
#TODO Single out stomping and make betta
|
||||
#TODO too much force intially and too high with frog jump
|
||||
if stomping:
|
||||
additive_jump_force += calculate_stomp_velocity(delta)
|
||||
|
||||
var y_acceleration_force = acceleration_force[state].y
|
||||
var x_acceleration_force = acceleration_force[state].x
|
||||
var y_acceleration_force = acceleration_force[state].y
|
||||
var x_acceleration_force = acceleration_force[state].x
|
||||
|
||||
if duck_jumping:
|
||||
y_acceleration_force *= duck_boost.y
|
||||
linear_velocity.x += duck_boost.x * direction.x
|
||||
if duck_jumping:
|
||||
y_acceleration_force *= duck_boost.y
|
||||
linear_velocity.x += duck_boost.x * direction.x
|
||||
|
||||
if state != "jump":
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.y,
|
||||
(y_acceleration_force / delta + additive_jump_force) * -1,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
if state != "jump":
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.y,
|
||||
(y_acceleration_force / delta + additive_jump_force) * -1,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
# print(acceleration_force[state].y)
|
||||
# print(linear_velocity.y)
|
||||
|
||||
var y_velocity = 0
|
||||
if !Input.is_action_pressed("jump") && !stomping:
|
||||
# Smooth transition from jumping to falling
|
||||
if velocity.y > _gravity * delta * 10:
|
||||
y_velocity += _gravity * delta * 10
|
||||
else:
|
||||
y_velocity += (max(abs(linear_velocity.y), _gravity * delta) / 2)
|
||||
var y_velocity = 0
|
||||
if !Input.is_action_pressed("jump") && !stomping:
|
||||
# Smooth transition from jumping to falling
|
||||
if velocity.y > _gravity * delta * 10:
|
||||
y_velocity += _gravity * delta * 10
|
||||
else:
|
||||
y_velocity += (max(abs(linear_velocity.y), _gravity * delta) / 2)
|
||||
|
||||
else:
|
||||
y_velocity += _gravity * delta
|
||||
|
||||
#if linear_velocity.y < max_velocity["jump"].y:
|
||||
linear_velocity.y += y_velocity
|
||||
else:
|
||||
y_velocity += _gravity * delta
|
||||
|
||||
#if linear_velocity.y < max_velocity["jump"].y:
|
||||
linear_velocity.y += y_velocity
|
||||
|
||||
# TODO This is poop too
|
||||
if (
|
||||
-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 divisor = 1 / max(0.1, initial_velocity_dependence)
|
||||
var movement_factor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor)
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.x, x_acceleration_force * movement_factor * direction.x, mass, delta
|
||||
)
|
||||
# TODO This is poop too
|
||||
if (
|
||||
-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 divisor = 1 / max(0.1, initial_velocity_dependence)
|
||||
var movement_factor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor)
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.x, x_acceleration_force * movement_factor * direction.x, mass, delta
|
||||
)
|
||||
|
||||
if is_correct_airstrafe_input():
|
||||
linear_velocity = execute_airstrafe(linear_velocity, delta, direction)
|
||||
if is_correct_airstrafe_input():
|
||||
linear_velocity = execute_airstrafe(linear_velocity, delta, direction)
|
||||
# print(linear_velocity.y)
|
||||
return linear_velocity
|
||||
return linear_velocity
|
||||
|
||||
|
||||
# Only applicable to downwards gravity
|
||||
# Can set the jump buffer
|
||||
func calculate_fall_velocity(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2:
|
||||
var state = player_state_machine.state
|
||||
if velocity.y < max_velocity["fall"].y:
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.y, _gravity * mass, mass, delta
|
||||
)
|
||||
else:
|
||||
linear_velocity.y = max_velocity["fall"].y
|
||||
if (
|
||||
-max_velocity["fall"].x < velocity.x and direction.x < 0
|
||||
|| max_velocity["fall"].x > velocity.x and direction.x > 0
|
||||
):
|
||||
# TODO This is poop
|
||||
var absolut = 1 - initial_velocity_dependence
|
||||
var divisor = 1 / max(0.1, initial_velocity_dependence)
|
||||
var movementFactor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor)
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.x,
|
||||
acceleration_force[state].x * movementFactor * direction.x,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
if Input.is_action_just_pressed("jump"):
|
||||
jump_buffer_filled = true
|
||||
if is_correct_airstrafe_input():
|
||||
linear_velocity = execute_airstrafe(linear_velocity, delta, direction)
|
||||
if stomping:
|
||||
linear_velocity = calculate_jump_velocity(Vector2(linear_velocity.x, 0), delta, direction)
|
||||
return linear_velocity
|
||||
var state = player_state_machine.state
|
||||
if velocity.y < max_velocity["fall"].y:
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.y, _gravity * mass, mass, delta
|
||||
)
|
||||
else:
|
||||
linear_velocity.y = max_velocity["fall"].y
|
||||
if (
|
||||
-max_velocity["fall"].x < velocity.x and direction.x < 0
|
||||
|| max_velocity["fall"].x > velocity.x and direction.x > 0
|
||||
):
|
||||
# TODO This is poop
|
||||
var absolut = 1 - initial_velocity_dependence
|
||||
var divisor = 1 / max(0.1, initial_velocity_dependence)
|
||||
var movementFactor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor)
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.x,
|
||||
acceleration_force[state].x * movementFactor * direction.x,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
if Input.is_action_just_pressed("jump"):
|
||||
jump_buffer_filled = true
|
||||
if is_correct_airstrafe_input():
|
||||
linear_velocity = execute_airstrafe(linear_velocity, delta, direction)
|
||||
if stomping:
|
||||
linear_velocity = calculate_jump_velocity(Vector2(linear_velocity.x, 0), delta, direction)
|
||||
return linear_velocity
|
||||
|
||||
|
||||
func calculate_wallslide_velocity(
|
||||
linear_velocity: Vector2, delta: float, direction: Vector2
|
||||
linear_velocity: Vector2, delta: float, direction: Vector2
|
||||
) -> Vector2:
|
||||
# Walljump mechanics
|
||||
if is_correct_walljump_input(direction):
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
0, acceleration_force["walljump"].x / delta * direction.x, mass, delta
|
||||
)
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
0, acceleration_force["walljump"].y / delta * -1, mass, delta
|
||||
)
|
||||
elif is_correct_airstrafe_input():
|
||||
# var rev = 1 if !is_reversing_horizontal_movement(direction) else -1
|
||||
linear_velocity = execute_airstrafe(linear_velocity, delta, direction)
|
||||
elif (
|
||||
abs(direction.x + wall_touch_direction) < 1
|
||||
&& abs(direction.x + wall_touch_direction) >= 0
|
||||
):
|
||||
var absolut = 1 - initial_velocity_dependence
|
||||
var divisor = 1 / max(0.1, initial_velocity_dependence)
|
||||
var movementFactor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor)
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.x,
|
||||
acceleration_force["fall"].x * movementFactor * direction.x,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
else:
|
||||
# TODO dont put constants in here
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.y * 0.94, _gravity * mass, mass, delta
|
||||
)
|
||||
# TODO single out to function
|
||||
air_strafe_charges = (
|
||||
air_strafe_charges + 1
|
||||
if max_air_strafe_charges > air_strafe_charges
|
||||
else 0
|
||||
)
|
||||
return linear_velocity.rotated(rotation)
|
||||
# Walljump mechanics
|
||||
if is_correct_walljump_input(direction):
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
0, acceleration_force["walljump"].x / delta * direction.x, mass, delta
|
||||
)
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
0, acceleration_force["walljump"].y / delta * -1, mass, delta
|
||||
)
|
||||
elif is_correct_airstrafe_input():
|
||||
# var rev = 1 if !is_reversing_horizontal_movement(direction) else -1
|
||||
linear_velocity = execute_airstrafe(linear_velocity, delta, direction)
|
||||
elif (
|
||||
abs(direction.x + wall_touch_direction) < 1
|
||||
&& abs(direction.x + wall_touch_direction) >= 0
|
||||
):
|
||||
var absolut = 1 - initial_velocity_dependence
|
||||
var divisor = 1 / max(0.1, initial_velocity_dependence)
|
||||
var movementFactor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor)
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.x,
|
||||
acceleration_force["fall"].x * movementFactor * direction.x,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
else:
|
||||
# TODO dont put constants in here
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.y * 0.94, _gravity * mass, mass, delta
|
||||
)
|
||||
# TODO single out to function
|
||||
air_strafe_charges = (
|
||||
air_strafe_charges + 1
|
||||
if max_air_strafe_charges > air_strafe_charges
|
||||
else 0
|
||||
)
|
||||
return linear_velocity.rotated(rotation)
|
||||
|
||||
|
||||
func execute_airstrafe(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2:
|
||||
# var rev = 1 if !is_reversing_horizontal_movement(direction) else -1
|
||||
# TODO Consider adding a extra state for airstrafing
|
||||
# TODO Make airstrafing less instantaneous and moderate the impulse
|
||||
if direction.x > 0:
|
||||
effect_player.play("airstrafing")
|
||||
else:
|
||||
effect_player.play("airstrafingLeft")
|
||||
if is_reversing_horizontal_movement(direction):
|
||||
linear_velocity.x = 0
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.x, acceleration_force["air_strafe"].x / delta * direction.x, mass, delta
|
||||
)
|
||||
if linear_velocity.y > 0:
|
||||
# TODO Put constant elsewhere
|
||||
linear_velocity.y = linear_velocity.y * 0.33
|
||||
air_strafe_charges -= 1
|
||||
return linear_velocity
|
||||
# var rev = 1 if !is_reversing_horizontal_movement(direction) else -1
|
||||
# TODO Consider adding a extra state for airstrafing
|
||||
# TODO Make airstrafing less instantaneous and moderate the impulse
|
||||
if direction.x > 0:
|
||||
effect_player.play("airstrafing")
|
||||
else:
|
||||
effect_player.play("airstrafingLeft")
|
||||
if is_reversing_horizontal_movement(direction):
|
||||
linear_velocity.x = 0
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.x, acceleration_force["air_strafe"].x / delta * direction.x, mass, delta
|
||||
)
|
||||
if linear_velocity.y > 0:
|
||||
# TODO Put constant elsewhere
|
||||
linear_velocity.y = linear_velocity.y * 0.33
|
||||
air_strafe_charges -= 1
|
||||
return linear_velocity
|
||||
|
||||
|
||||
func calculate_slope_rotation(_onfloor: bool) -> float:
|
||||
var angle = 0
|
||||
var slope_angle_left = $SlopeRaycastLeft.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
|
||||
if (
|
||||
!(-PI / 2 <= slope_angle_left && slope_angle_left <= PI / 2)
|
||||
|| !(-PI / 2 <= slope_angle_right && slope_angle_right <= PI / 2)
|
||||
|| (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
|
||||
if (
|
||||
abs(slope_angle_left) > abs(slope_angle_right) && velocity.x < -10
|
||||
|| 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()
|
||||
# upturn
|
||||
else:
|
||||
var length_vector: Vector2 = (
|
||||
$SlopeRaycastLeft.get_collision_point()
|
||||
- $SlopeRaycastRight.get_collision_point()
|
||||
)
|
||||
angle = length_vector.angle() - PI
|
||||
previous_rotation = angle
|
||||
if is_equal_approx(deg2rad(angle), 0):
|
||||
pass
|
||||
return angle
|
||||
var angle = 0
|
||||
var slope_angle_left = $SlopeRaycastLeft.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
|
||||
if (
|
||||
!(-PI / 2 <= slope_angle_left && slope_angle_left <= PI / 2)
|
||||
|| !(-PI / 2 <= slope_angle_right && slope_angle_right <= PI / 2)
|
||||
|| (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
|
||||
if (
|
||||
abs(slope_angle_left) > abs(slope_angle_right) && velocity.x < -10
|
||||
|| 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()
|
||||
# upturn
|
||||
else:
|
||||
var length_vector: Vector2 = (
|
||||
$SlopeRaycastLeft.get_collision_point()
|
||||
- $SlopeRaycastRight.get_collision_point()
|
||||
)
|
||||
angle = length_vector.angle() - PI
|
||||
previous_rotation = angle
|
||||
if is_equal_approx(deg2rad(angle), 0):
|
||||
pass
|
||||
return angle
|
||||
|
||||
|
||||
# TODO could be expanded with a parameter about what got stomped
|
||||
func stomp() -> void:
|
||||
#print("stomping")
|
||||
#print(player_state_machine.state)
|
||||
scene_audio.play_parallel_sound(
|
||||
"res://assets/sounds/FABRIC_Flap_03_mono.wav", -15, false, 1.5, 0.2
|
||||
)
|
||||
scene_audio.play_parallel_sound("res://assets/sounds/CLASP_Plastic_Open_stereo.wav", -12)
|
||||
stomping = true
|
||||
#print("stomping")
|
||||
#print(player_state_machine.state)
|
||||
scene_audio.play_parallel_sound(
|
||||
"res://assets/sounds/FABRIC_Flap_03_mono.wav", -15, false, 1.5, 0.2
|
||||
)
|
||||
scene_audio.play_parallel_sound("res://assets/sounds/CLASP_Plastic_Open_stereo.wav", -12)
|
||||
stomping = true
|
||||
|
||||
|
||||
# TOD lose_power_up function
|
||||
func receive_power_up(kind: String) -> void:
|
||||
if kind == "shield":
|
||||
$BubbleShieldViewport/IridescenceBall.visible = true
|
||||
shielded = true
|
||||
if kind == "shield":
|
||||
$BubbleShieldViewport/IridescenceBall.visible = true
|
||||
shielded = true
|
||||
|
||||
|
||||
# TODO Maybe this should be a state in itself?
|
||||
func die(animation_number: int = 0) -> void:
|
||||
if level_state.is_dead:
|
||||
return
|
||||
if shielded:
|
||||
shielded = false
|
||||
$BubbleShieldViewport/IridescenceBall.visible = false
|
||||
$InvincibilityTimer.start()
|
||||
$BlobbySprite.material = invincible_shader
|
||||
return
|
||||
elif !$InvincibilityTimer.is_stopped():
|
||||
return
|
||||
z_index = 1
|
||||
$BlobbySprite.material = death_shader
|
||||
signal_manager.emit_signal("player_died", animation_number)
|
||||
$"%BlobbymationTree".active = false
|
||||
$"%BlobbymationPlayer".play("dying3")
|
||||
if animation_number == 0:
|
||||
$"%BlobbymationPlayer".play("expandingDisolve")
|
||||
if animation_number == -1:
|
||||
respawn()
|
||||
return
|
||||
scene_audio.play_parallel_sound(death_sound_1, -15)
|
||||
scene_audio.play_parallel_sound(death_sound_2, -16)
|
||||
if level_state.is_dead:
|
||||
return
|
||||
if shielded:
|
||||
shielded = false
|
||||
$BubbleShieldViewport/IridescenceBall.visible = false
|
||||
$InvincibilityTimer.start()
|
||||
$BlobbySprite.material = invincible_shader
|
||||
return
|
||||
elif !$InvincibilityTimer.is_stopped():
|
||||
return
|
||||
z_index = 1
|
||||
$BlobbySprite.material = death_shader
|
||||
signal_manager.emit_signal("player_died", animation_number)
|
||||
$"%BlobbymationTree".active = false
|
||||
$"%BlobbymationPlayer".play("dying3")
|
||||
if animation_number == 0:
|
||||
$"%BlobbymationPlayer".play("expandingDisolve")
|
||||
if animation_number == -1:
|
||||
respawn()
|
||||
return
|
||||
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:
|
||||
shielded = false
|
||||
$BubbleShieldViewport/IridescenceBall.visible = false
|
||||
die(animation_number)
|
||||
shielded = false
|
||||
$BubbleShieldViewport/IridescenceBall.visible = false
|
||||
die(animation_number)
|
||||
|
||||
|
||||
# TODO Checkpoint system
|
||||
func respawn() -> void:
|
||||
# Is tied to the death animation
|
||||
get_tree().reload_current_scene()
|
||||
# Is tied to the death animation
|
||||
get_tree().reload_current_scene()
|
||||
|
||||
|
||||
# When the Enemy stomp AREA enters the enemy collision area -> stomp
|
||||
func _on_BlobbySkin_area_entered(area: Area2D) -> void:
|
||||
if area.is_in_group("harmful"):
|
||||
die()
|
||||
if area.is_in_group("pit"):
|
||||
#scene_audio.play_parallel_sound(death_sound_1, -15)
|
||||
scene_audio.play_parallel_sound(death_sound_2, -16)
|
||||
$PitfallTimer.start()
|
||||
if area.is_in_group("harmful"):
|
||||
die()
|
||||
if area.is_in_group("pit"):
|
||||
#scene_audio.play_parallel_sound(death_sound_1, -15)
|
||||
scene_audio.play_parallel_sound(death_sound_2, -16)
|
||||
$PitfallTimer.start()
|
||||
|
||||
|
||||
# This problem stems from trying to decelerate a walk
|
||||
@ -518,54 +518,54 @@ func _on_BlobbySkin_area_entered(area: Area2D) -> void:
|
||||
# It is particularly usefull for moving floor physics
|
||||
# TODO Setting y velocity this way stopped is_on_floor() from working correctly
|
||||
func _on_Blobby_got_grounded() -> void:
|
||||
velocity.x -= get_floor_velocity().x
|
||||
snap_possible = true
|
||||
var floor_object = get_last_slide_collision().collider.get_parent()
|
||||
#TODO There is already a friction property in engine
|
||||
if "slide_friction" in floor_object:
|
||||
floor_friction = floor_object.slide_friction
|
||||
else:
|
||||
floor_friction = base_floor_friction
|
||||
air_strafe_charges = (
|
||||
air_strafe_charges + 1
|
||||
if max_air_strafe_charges > air_strafe_charges
|
||||
else 0
|
||||
)
|
||||
velocity.x -= get_floor_velocity().x
|
||||
snap_possible = true
|
||||
var floor_object = get_last_slide_collision().collider.get_parent()
|
||||
#TODO There is already a friction property in engine
|
||||
if "slide_friction" in floor_object:
|
||||
floor_friction = floor_object.slide_friction
|
||||
else:
|
||||
floor_friction = base_floor_friction
|
||||
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)
|
||||
# This is for drop through platforms
|
||||
if body.get_collision_mask_bit(7):
|
||||
set_collision_mask_bit(7, true)
|
||||
|
||||
|
||||
func _on_InvincibilityTimer_timeout() -> void:
|
||||
$BlobbySprite.material = null
|
||||
for area in $BlobbySkin.get_overlapping_areas():
|
||||
if area.is_in_group("harmful"):
|
||||
die()
|
||||
$BlobbySprite.material = null
|
||||
for area in $BlobbySkin.get_overlapping_areas():
|
||||
if area.is_in_group("harmful"):
|
||||
die()
|
||||
|
||||
|
||||
func _on_CrushTimer_timeout() -> void:
|
||||
if is_crushed():
|
||||
die_for_real()
|
||||
if is_crushed():
|
||||
die_for_real()
|
||||
|
||||
|
||||
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:
|
||||
return calculate_jump_velocity(velocity, delta, direction)
|
||||
return calculate_jump_velocity(velocity, delta, direction)
|
||||
|
||||
|
||||
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:
|
||||
return calculate_fall_velocity(velocity, delta, direction)
|
||||
return calculate_fall_velocity(velocity, delta, direction)
|
||||
|
||||
|
||||
func handle_wallslide_movement(delta: float, direction: Vector2) -> Vector2:
|
||||
return calculate_wallslide_velocity(velocity, delta, direction)
|
||||
return calculate_wallslide_velocity(velocity, delta, direction)
|
||||
|
||||
@ -10,33 +10,33 @@ export(String, FILE, "*.tscn") var next_scene
|
||||
export(bool) var is_active
|
||||
|
||||
func _ready() -> void:
|
||||
if(!is_active):
|
||||
monitoring = false
|
||||
signal_manager.connect("terminal_activated", self, "activate_portal")
|
||||
else:
|
||||
$portal.frame = 0
|
||||
if(!is_active):
|
||||
monitoring = false
|
||||
signal_manager.connect("terminal_activated", self, "activate_portal")
|
||||
else:
|
||||
$portal.frame = 0
|
||||
|
||||
func _get_configuration_warning() -> String:
|
||||
return "The next scene property can't be empty" if not next_scene else ""
|
||||
return "The next scene property can't be empty" if not next_scene else ""
|
||||
|
||||
func level_completion() -> void:
|
||||
GlobalState.remove_savepoint(levelName)
|
||||
signal_manager.emit_signal("level_completed")
|
||||
GlobalState.remove_savepoint(levelName)
|
||||
signal_manager.emit_signal("level_completed")
|
||||
|
||||
func activate_portal(_time: float) -> void:
|
||||
$AnimationPlayer.play("activatePortal")
|
||||
monitoring = true
|
||||
$AnimationPlayer.play("activatePortal")
|
||||
monitoring = true
|
||||
|
||||
func teleport() -> void:
|
||||
GlobalAudio.play_scene_independent("res://assets/sounds/MAGIC_SPELL_Morphing_Synth_Harp_Scales_stereo.wav", "Music", -15)
|
||||
get_tree().paused = true
|
||||
anim_player.play("fade_in")
|
||||
# TODO This doesn't pause the game but should
|
||||
yield(anim_player, "animation_finished")
|
||||
if ResourceLoader.exists(next_scene):
|
||||
get_tree().change_scene(next_scene)
|
||||
GlobalAudio.play_scene_independent("res://assets/sounds/MAGIC_SPELL_Morphing_Synth_Harp_Scales_stereo.wav", "Music", -15)
|
||||
get_tree().paused = true
|
||||
anim_player.play("fade_in")
|
||||
# TODO This doesn't pause the game but should
|
||||
yield(anim_player, "animation_finished")
|
||||
if ResourceLoader.exists(next_scene):
|
||||
get_tree().change_scene(next_scene)
|
||||
|
||||
|
||||
func _on_body_entered(_body: Node) -> void:
|
||||
level_completion()
|
||||
teleport()
|
||||
level_completion()
|
||||
teleport()
|
||||
|
||||
@ -57,7 +57,6 @@
|
||||
[ext_resource path="res://assets/environment/decor/longductor/Longductor9.png" type="Texture" id=55]
|
||||
[ext_resource path="res://assets/environment/decor/screen/Screen1.png" type="Texture" id=56]
|
||||
[ext_resource path="res://assets/environment/decor/Ceiling-Struct.png" type="Texture" id=57]
|
||||
[ext_resource path="res://addons/ACVoicebox/ACVoicebox.tscn" type="PackedScene" id=58]
|
||||
|
||||
[sub_resource type="Shader" id=15]
|
||||
code = "shader_type canvas_item;
|
||||
@ -1078,10 +1077,6 @@ __meta__ = {
|
||||
"_edit_vertical_guides_": [ 2880.0 ]
|
||||
}
|
||||
|
||||
[node name="ACVoicebox" parent="." instance=ExtResource( 58 )]
|
||||
volume_db = -23.016
|
||||
base_pitch = 2.5
|
||||
|
||||
[node name="SceneAudio" parent="." instance=ExtResource( 14 )]
|
||||
visible = false
|
||||
|
||||
|
||||
@ -235,10 +235,6 @@ visible = false
|
||||
unique_name_in_owner = true
|
||||
position = Vector2( -180, 113 )
|
||||
scale = Vector2( 0.878906, 0.936025 )
|
||||
mass = null
|
||||
jump_buffer_filled = null
|
||||
death_sound_1 = null
|
||||
death_sound_2 = null
|
||||
|
||||
[node name="BlobbySprite" parent="Blobby" index="5"]
|
||||
frame = 7
|
||||
|
||||
@ -124,13 +124,9 @@ drag_margin_bottom = 0.3
|
||||
unique_name_in_owner = true
|
||||
position = Vector2( -70, 1 )
|
||||
scale = Vector2( 0.878906, 0.936025 )
|
||||
mass = null
|
||||
jump_buffer_filled = null
|
||||
death_sound_1 = null
|
||||
death_sound_2 = null
|
||||
|
||||
[node name="BlobbySprite" parent="Blobby" index="5"]
|
||||
frame = 9
|
||||
frame = 8
|
||||
|
||||
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]
|
||||
parameters/playback = SubResource( 6 )
|
||||
|
||||
@ -131,6 +131,9 @@ unique_name_in_owner = true
|
||||
position = Vector2( -64, -1.90735e-06 )
|
||||
scale = Vector2( 0.878906, 0.936025 )
|
||||
|
||||
[node name="BlobbySprite" parent="Blobby" index="5"]
|
||||
frame = 10
|
||||
|
||||
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]
|
||||
parameters/playback = SubResource( 6 )
|
||||
|
||||
|
||||
@ -1010,7 +1010,7 @@ position = Vector2( -88, 96 )
|
||||
scale = Vector2( 0.878906, 0.936025 )
|
||||
|
||||
[node name="BlobbySprite" parent="Blobby" index="5"]
|
||||
frame = 8
|
||||
frame = 7
|
||||
|
||||
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]
|
||||
parameters/playback = SubResource( 6 )
|
||||
|
||||
@ -119,7 +119,7 @@ position = Vector2( -183, 111 )
|
||||
scale = Vector2( 0.878906, 0.936025 )
|
||||
|
||||
[node name="BlobbySprite" parent="Blobby" index="5"]
|
||||
frame = 7
|
||||
frame = 6
|
||||
|
||||
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]
|
||||
parameters/playback = SubResource( 6 )
|
||||
@ -185,7 +185,7 @@ position = Vector2( -112, -748 )
|
||||
rotation = -3.14159
|
||||
|
||||
[node name="FlyingLaserCutter7" parent="." instance=ExtResource( 13 )]
|
||||
position = Vector2( -58, -808 )
|
||||
position = Vector2( -48, -799 )
|
||||
rotation = -3.14159
|
||||
|
||||
[node name="FlyingLaserCutter8" parent="." instance=ExtResource( 13 )]
|
||||
|
||||
@ -194,7 +194,7 @@ position = Vector2( -45, -5.96046e-08 )
|
||||
scale = Vector2( 0.878906, 0.936025 )
|
||||
|
||||
[node name="BlobbySprite" parent="Blobby" index="5"]
|
||||
frame = 8
|
||||
frame = 5
|
||||
|
||||
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]
|
||||
parameters/playback = SubResource( 6 )
|
||||
|
||||
@ -11,19 +11,19 @@ onready var level_state := $"%LevelState"
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
$TransitionLayer.visible = true
|
||||
var transition_tween = Tween.new()
|
||||
add_child(transition_tween)
|
||||
var property = "shader_param/position"
|
||||
var node = $TransitionLayer/SceneTransition
|
||||
transition_tween.interpolate_property(node.material, property,-1.5, 1.0, 0.94, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
|
||||
transition_tween.start()
|
||||
# should spawn the tutorial thingies which are still remembered in the progress dictionary
|
||||
signal_manager.connect("terminal_activated", self, "stop_level_music")
|
||||
signal_manager.emit_signal("level_loaded")
|
||||
get_tree().paused = false
|
||||
$SceneAudio.play_parallel_sound(level_music, level_music_attenuation, false, 1.0, 0, "Music")
|
||||
$SceneAudio.play_parallel_sound(level_ambiance, level_ambiance_attenuation)
|
||||
$TransitionLayer.visible = true
|
||||
var transition_tween = Tween.new()
|
||||
add_child(transition_tween)
|
||||
var property = "shader_param/position"
|
||||
var node = $TransitionLayer/SceneTransition
|
||||
transition_tween.interpolate_property(node.material, property,-1.5, 1.0, 0.94, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
|
||||
transition_tween.start()
|
||||
# should spawn the tutorial thingies which are still remembered in the progress dictionary
|
||||
signal_manager.connect("terminal_activated", self, "stop_level_music")
|
||||
signal_manager.emit_signal("level_loaded")
|
||||
get_tree().paused = false
|
||||
$SceneAudio.play_parallel_sound(level_music, level_music_attenuation, false, 1.0, 0, "Music")
|
||||
$SceneAudio.play_parallel_sound(level_ambiance, level_ambiance_attenuation)
|
||||
|
||||
func stop_level_music(_unused: float) -> void:
|
||||
$SceneAudio.stop_parallel_sound(level_music)
|
||||
$SceneAudio.stop_parallel_sound(level_music)
|
||||
|
||||
@ -41,7 +41,7 @@ resource_name = "LowPassFilter"
|
||||
cutoff_hz = 3000.0
|
||||
|
||||
[resource]
|
||||
bus/0/volume_db = inf_neg
|
||||
bus/0/volume_db = -20.0
|
||||
bus/1/name = "Music"
|
||||
bus/1/solo = false
|
||||
bus/1/mute = false
|
||||
|
||||
@ -11,58 +11,58 @@ var paused := false setget set_paused
|
||||
var block_ui_cancel = false
|
||||
|
||||
func _ready():
|
||||
#signal_manager.connect("player_died", self, "_on_GlobalState_player_died")
|
||||
$ControlsMenu.visible = false
|
||||
$ControlsMenu.set_process_input(false)
|
||||
$AudioMenu.set_process_input(false)
|
||||
signal_manager.connect("game_paused", self, "set_paused")
|
||||
pass
|
||||
#signal_manager.connect("player_died", self, "_on_GlobalState_player_died")
|
||||
$ControlsMenu.visible = false
|
||||
$ControlsMenu.set_process_input(false)
|
||||
$AudioMenu.set_process_input(false)
|
||||
signal_manager.connect("game_paused", self, "set_paused")
|
||||
pass
|
||||
|
||||
func open_audio_menu():
|
||||
block_ui_cancel = true
|
||||
pause_overlay.visible = false
|
||||
$AudioMenu.visible = true
|
||||
$AudioMenu.set_process_input(true)
|
||||
$"%MasterSlider".grab_focus()
|
||||
block_ui_cancel = true
|
||||
pause_overlay.visible = false
|
||||
$AudioMenu.visible = true
|
||||
$AudioMenu.set_process_input(true)
|
||||
$"%MasterSlider".grab_focus()
|
||||
|
||||
func close_audio_menu():
|
||||
$AudioMenu.visible = false
|
||||
pause_overlay.visible = true
|
||||
$AudioMenu.set_process_input(false)
|
||||
$"%Continue".grab_focus()
|
||||
get_tree().set_input_as_handled()
|
||||
$AudioMenu.visible = false
|
||||
pause_overlay.visible = true
|
||||
$AudioMenu.set_process_input(false)
|
||||
$"%Continue".grab_focus()
|
||||
get_tree().set_input_as_handled()
|
||||
|
||||
|
||||
func _on_GlobalState_player_died() -> void:
|
||||
self.paused = true
|
||||
pause_title.text = "You lost"
|
||||
self.paused = true
|
||||
pause_title.text = "You lost"
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if !event.is_action("pause"):
|
||||
return
|
||||
if block_ui_cancel || $"%ControlsMenu".visible:
|
||||
block_ui_cancel = false
|
||||
get_tree().set_input_as_handled()
|
||||
return
|
||||
#not oder ! schaltet einen boolean um
|
||||
#Ist self hier notwendig?
|
||||
|
||||
self.paused = not paused
|
||||
block_ui_cancel = true
|
||||
if !event.is_action("pause"):
|
||||
return
|
||||
if block_ui_cancel || $"%ControlsMenu".visible:
|
||||
block_ui_cancel = false
|
||||
get_tree().set_input_as_handled()
|
||||
return
|
||||
#not oder ! schaltet einen boolean um
|
||||
#Ist self hier notwendig?
|
||||
|
||||
self.paused = not paused
|
||||
block_ui_cancel = true
|
||||
|
||||
|
||||
func set_paused(value: bool) -> void:
|
||||
paused = value
|
||||
get_tree().paused = value
|
||||
pause_overlay.visible = value
|
||||
if value == true:
|
||||
$"%Continue".grab_focus()
|
||||
paused = value
|
||||
get_tree().paused = value
|
||||
pause_overlay.visible = value
|
||||
if value == true:
|
||||
$"%Continue".grab_focus()
|
||||
|
||||
|
||||
func _on_Controls_button_up() -> void:
|
||||
$ControlsMenu.visible = true
|
||||
$ControlsMenu.set_process_input(true)
|
||||
block_ui_cancel = true
|
||||
pause_overlay.visible = false
|
||||
$"%ProfilesMenu".grab_focus()
|
||||
$ControlsMenu.visible = true
|
||||
$ControlsMenu.set_process_input(true)
|
||||
block_ui_cancel = true
|
||||
pause_overlay.visible = false
|
||||
$"%ProfilesMenu".grab_focus()
|
||||
|
||||
@ -2,5 +2,5 @@ extends Control
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
$"%PlayButton".grab_focus()
|
||||
GlobalAudio.play_scene_independent("res://assets/music/Shopping For The Future (LOOP).wav","Music", -17, true)
|
||||
$"%PlayButton".grab_focus()
|
||||
GlobalAudio.play_scene_independent("res://assets/music/Shopping For The Future (LOOP).wav","Music", -17, true)
|
||||
|
||||
@ -225,8 +225,7 @@ scroll_horizontal_enabled = false
|
||||
script = ExtResource( 11 )
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MenuContainer/Panel/LevelList"]
|
||||
margin_right = 123.0
|
||||
margin_bottom = 102.0
|
||||
margin_right = 119.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
@ -11,105 +11,105 @@ var freed_frogs := []
|
||||
var is_dead: = false setget set_dead
|
||||
|
||||
func _ready() -> void:
|
||||
GlobalState.gsr.last_played_level = levelName
|
||||
SaveManager.save_default()
|
||||
signal_manager.connect("level_completed", self, "_on_level_completed")
|
||||
signal_manager.connect("player_died", self, "player_dying")
|
||||
GlobalState.gsr.last_played_level = levelName
|
||||
SaveManager.save_default()
|
||||
signal_manager.connect("level_completed", self, "_on_level_completed")
|
||||
signal_manager.connect("player_died", self, "player_dying")
|
||||
|
||||
func reset() -> void:
|
||||
deaths = 0
|
||||
currency = 0
|
||||
freed_frogs = []
|
||||
# TODO Maybe not the place for this?
|
||||
if GlobalState.gsr.progress_dict.has(levelName):
|
||||
GlobalState.gsr.progress_dict[levelName].erase("savepoint")
|
||||
deaths = 0
|
||||
currency = 0
|
||||
freed_frogs = []
|
||||
# TODO Maybe not the place for this?
|
||||
if GlobalState.gsr.progress_dict.has(levelName):
|
||||
GlobalState.gsr.progress_dict[levelName].erase("savepoint")
|
||||
|
||||
func set_currency(value: int) -> void:
|
||||
currency = value
|
||||
signal_manager.emit_signal("currency_updated")
|
||||
currency = value
|
||||
signal_manager.emit_signal("currency_updated")
|
||||
|
||||
func set_deaths(value: int) -> void:
|
||||
deaths = value
|
||||
deaths = value
|
||||
|
||||
func set_dead(value: bool) -> void:
|
||||
is_dead = value
|
||||
is_dead = value
|
||||
|
||||
func register_frog(number: int, freed: bool = false) -> void:
|
||||
update_global_state()
|
||||
if(!GlobalState.gsr.progress_dict[levelName]["froggies"].has(number)):
|
||||
GlobalState.gsr.progress_dict[levelName]["froggies"][number] = freed
|
||||
GlobalState.save()
|
||||
update_global_state()
|
||||
if(!GlobalState.gsr.progress_dict[levelName]["froggies"].has(number)):
|
||||
GlobalState.gsr.progress_dict[levelName]["froggies"][number] = freed
|
||||
GlobalState.save()
|
||||
|
||||
func free_a_frog(number: int) -> void:
|
||||
freed_frogs.append(number)
|
||||
freed_frogs.append(number)
|
||||
|
||||
func needs_tutorial(lesson: String) -> bool:
|
||||
if(!GlobalState.gsr.tutorial_prompts.has(lesson)):
|
||||
return false
|
||||
return GlobalState.gsr.tutorial_prompts[lesson]
|
||||
if(!GlobalState.gsr.tutorial_prompts.has(lesson)):
|
||||
return false
|
||||
return GlobalState.gsr.tutorial_prompts[lesson]
|
||||
|
||||
func register_tutorial(lesson: String) -> void:
|
||||
if(GlobalState.gsr.tutorial_prompts.has(lesson)):
|
||||
return
|
||||
GlobalState.gsr.tutorial_prompts[lesson] = true
|
||||
GlobalState.save()
|
||||
if(GlobalState.gsr.tutorial_prompts.has(lesson)):
|
||||
return
|
||||
GlobalState.gsr.tutorial_prompts[lesson] = true
|
||||
GlobalState.save()
|
||||
|
||||
func absolved_tutorial(lesson: String) -> void:
|
||||
if(!GlobalState.gsr.tutorial_prompts.has(lesson)):
|
||||
return
|
||||
GlobalState.gsr.tutorial_prompts[lesson] = false
|
||||
GlobalState.save()
|
||||
if(!GlobalState.gsr.tutorial_prompts.has(lesson)):
|
||||
return
|
||||
GlobalState.gsr.tutorial_prompts[lesson] = false
|
||||
GlobalState.save()
|
||||
|
||||
# Spends the currency when enough is available
|
||||
# and returns true if so. Else it does not spend and return false.
|
||||
func spend_currency(cost: int) -> bool:
|
||||
# TODO member that
|
||||
if(OS.is_debug_build()):
|
||||
return true
|
||||
if GlobalState.gsr.wallet + currency < cost:
|
||||
return false
|
||||
var remainder = currency - cost
|
||||
if remainder >= 0:
|
||||
currency = remainder
|
||||
else:
|
||||
currency = 0
|
||||
GlobalState.set_wallet(GlobalState.gsr.wallet + remainder)
|
||||
return true
|
||||
# TODO member that
|
||||
if(OS.is_debug_build()):
|
||||
return true
|
||||
if GlobalState.gsr.wallet + currency < cost:
|
||||
return false
|
||||
var remainder = currency - cost
|
||||
if remainder >= 0:
|
||||
currency = remainder
|
||||
else:
|
||||
currency = 0
|
||||
GlobalState.set_wallet(GlobalState.gsr.wallet + remainder)
|
||||
return true
|
||||
|
||||
func _on_level_completed():
|
||||
#if(OS.is_debug_build()):
|
||||
# return
|
||||
update_global_state()
|
||||
reset()
|
||||
#if(OS.is_debug_build()):
|
||||
# return
|
||||
update_global_state()
|
||||
reset()
|
||||
|
||||
func update_global_state() -> void:
|
||||
var progress_dict : Dictionary = GlobalState.get_progress()
|
||||
var levelProgress : Dictionary = {}
|
||||
var progress_dict : Dictionary = GlobalState.get_progress()
|
||||
var levelProgress : Dictionary = {}
|
||||
|
||||
levelProgress["currency"] = currency
|
||||
levelProgress["deaths"] = deaths
|
||||
|
||||
# TODO Doesnt account for multiple plays of same level
|
||||
if !progress_dict.has(levelName):
|
||||
progress_dict[levelName] = levelProgress
|
||||
else:
|
||||
progress_dict[levelName]["currency"] = GlobalState.get_property_value(levelName,"currency") + currency
|
||||
progress_dict[levelName]["deaths"] = GlobalState.get_property_value(levelName,"deaths") + deaths
|
||||
if !progress_dict[levelName].has("froggies"):
|
||||
progress_dict[levelName]["froggies"] = {}
|
||||
else:
|
||||
for frog_number in freed_frogs:
|
||||
if progress_dict[levelName]["froggies"].has(frog_number):
|
||||
progress_dict[levelName]["froggies"][frog_number] = true
|
||||
levelProgress["currency"] = currency
|
||||
levelProgress["deaths"] = deaths
|
||||
|
||||
# TODO Doesnt account for multiple plays of same level
|
||||
if !progress_dict.has(levelName):
|
||||
progress_dict[levelName] = levelProgress
|
||||
else:
|
||||
progress_dict[levelName]["currency"] = GlobalState.get_property_value(levelName,"currency") + currency
|
||||
progress_dict[levelName]["deaths"] = GlobalState.get_property_value(levelName,"deaths") + deaths
|
||||
if !progress_dict[levelName].has("froggies"):
|
||||
progress_dict[levelName]["froggies"] = {}
|
||||
else:
|
||||
for frog_number in freed_frogs:
|
||||
if progress_dict[levelName]["froggies"].has(frog_number):
|
||||
progress_dict[levelName]["froggies"][frog_number] = true
|
||||
|
||||
# TODO Wallet is independant from progress_dict because???
|
||||
GlobalState.set_wallet(GlobalState.gsr.wallet + currency)
|
||||
GlobalState.set_progress(progress_dict)
|
||||
# TODO Wallet is independant from progress_dict because???
|
||||
GlobalState.set_wallet(GlobalState.gsr.wallet + currency)
|
||||
GlobalState.set_progress(progress_dict)
|
||||
|
||||
func player_dying(animation_number: int = 0) -> void:
|
||||
currency = 0
|
||||
is_dead = true
|
||||
freed_frogs = []
|
||||
deaths += 1
|
||||
update_global_state()
|
||||
deaths = 0
|
||||
currency = 0
|
||||
is_dead = true
|
||||
freed_frogs = []
|
||||
deaths += 1
|
||||
update_global_state()
|
||||
deaths = 0
|
||||
|
||||
@ -8,74 +8,74 @@ onready var static_player: AudioStreamPlayer = $StaticPlayer
|
||||
|
||||
# Plays sound with the static player, interrupting sounds if currently playing
|
||||
func play_sound(
|
||||
sound_name: String,
|
||||
attenuation: float = 0.0,
|
||||
random_pitch = false,
|
||||
pitch = 1.0,
|
||||
start_time = 0.0,
|
||||
bus: String = "Effects"
|
||||
sound_name: String,
|
||||
attenuation: float = 0.0,
|
||||
random_pitch = false,
|
||||
pitch = 1.0,
|
||||
start_time = 0.0,
|
||||
bus: String = "Effects"
|
||||
) -> void:
|
||||
# TODO is it bad to grab the stream each time?
|
||||
var stream = GlobalState.sound_library[sound_name]
|
||||
if random_pitch:
|
||||
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)
|
||||
# TODO is it bad to grab the stream each time?
|
||||
var stream = GlobalState.sound_library[sound_name]
|
||||
if random_pitch:
|
||||
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():
|
||||
static_player.stream_paused = true
|
||||
static_player.stream_paused = true
|
||||
|
||||
|
||||
# Mirrors the GlobalAudio Method which can play sounds across scenes
|
||||
func play_parallel_sound(
|
||||
sound_name: String,
|
||||
attenuation: float = 0.0,
|
||||
random_pitch = false,
|
||||
pitch = 1.0,
|
||||
start_time = 0.0,
|
||||
bus: String = "Effects",
|
||||
singleton = false
|
||||
sound_name: String,
|
||||
attenuation: float = 0.0,
|
||||
random_pitch = false,
|
||||
pitch = 1.0,
|
||||
start_time = 0.0,
|
||||
bus: String = "Effects",
|
||||
singleton = false
|
||||
) -> void:
|
||||
if singleton && players.has(sound_name):
|
||||
return
|
||||
var disposable_player = AudioStreamPlayer.new()
|
||||
add_child(disposable_player)
|
||||
var stream = GlobalState.sound_library[sound_name]
|
||||
if random_pitch:
|
||||
stream = AudioStreamRandomPitch.new()
|
||||
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_parallel_player", [weakref(disposable_player)])
|
||||
players[sound_name] = weakref(disposable_player)
|
||||
if singleton && players.has(sound_name):
|
||||
return
|
||||
var disposable_player = AudioStreamPlayer.new()
|
||||
add_child(disposable_player)
|
||||
var stream = GlobalState.sound_library[sound_name]
|
||||
if random_pitch:
|
||||
stream = AudioStreamRandomPitch.new()
|
||||
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_parallel_player", [weakref(disposable_player)])
|
||||
players[sound_name] = weakref(disposable_player)
|
||||
|
||||
|
||||
func dispose_parallel_player(player: WeakRef) -> void:
|
||||
if !player.get_ref():
|
||||
return
|
||||
player.get_ref().queue_free()
|
||||
if !player.get_ref():
|
||||
return
|
||||
player.get_ref().queue_free()
|
||||
|
||||
|
||||
func pause_parallel_sound(sound_name: String):
|
||||
if players.has(sound_name) && players[sound_name].get_ref():
|
||||
players[sound_name].set_stream_paused(true)
|
||||
if players.has(sound_name) && players[sound_name].get_ref():
|
||||
players[sound_name].set_stream_paused(true)
|
||||
|
||||
|
||||
func continue_parallel_sound(sound_name: String):
|
||||
if players.has(sound_name) && players[sound_name].get_ref():
|
||||
players[sound_name].set_stream_paused(false)
|
||||
if players.has(sound_name) && players[sound_name].get_ref():
|
||||
players[sound_name].set_stream_paused(false)
|
||||
|
||||
|
||||
func stop_parallel_sound(sound_name: String):
|
||||
if players.has(sound_name) && players[sound_name].get_ref():
|
||||
dispose_parallel_player(players[sound_name])
|
||||
players.erase(sound_name)
|
||||
if players.has(sound_name) && players[sound_name].get_ref():
|
||||
dispose_parallel_player(players[sound_name])
|
||||
players.erase(sound_name)
|
||||
|
||||
@ -17,4 +17,4 @@ signal savemanager_saved()
|
||||
signal game_paused(value)
|
||||
|
||||
func _on_Timer_timeout() -> void:
|
||||
emit_signal("getback_timer_up")
|
||||
emit_signal("getback_timer_up")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user