fix: better vaccum caterpillar sprites, consistent caterpillar behaviour
This commit is contained in:
parent
522e472c4d
commit
12a7a3d76a
Binary file not shown.
BIN
assets/enemy/Caterpilllar.png
Normal file
BIN
assets/enemy/Caterpilllar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 692 B |
35
assets/enemy/Caterpilllar.png.import
Normal file
35
assets/enemy/Caterpilllar.png.import
Normal file
@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/Caterpilllar.png-f7385704d20b491d5205bc11eb188006.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/enemy/Caterpilllar.png"
|
||||
dest_files=[ "res://.import/Caterpilllar.png-f7385704d20b491d5205bc11eb188006.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=false
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=false
|
||||
svg/scale=1.0
|
||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 604 B After Width: | Height: | Size: 703 B |
@ -9,6 +9,11 @@
|
||||
config_version=4
|
||||
|
||||
_global_script_classes=[ {
|
||||
"base": "AudioStreamPlayer",
|
||||
"class": "ACVoiceBox",
|
||||
"language": "GDScript",
|
||||
"path": "res://addons/ACVoicebox/ACVoicebox.gd"
|
||||
}, {
|
||||
"base": "KinematicBody2D",
|
||||
"class": "Actor",
|
||||
"language": "GDScript",
|
||||
@ -90,6 +95,7 @@ _global_script_classes=[ {
|
||||
"path": "res://src/StateMachines/StateMachine.gd"
|
||||
} ]
|
||||
_global_script_class_icons={
|
||||
"ACVoiceBox": "",
|
||||
"Actor": "",
|
||||
"AudibleButton": "",
|
||||
"AudibleCheckbox": "",
|
||||
|
||||
@ -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
|
||||
|
||||
# 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 linear_velocity.y < max_velocity["jump"].y:
|
||||
linear_velocity.y += y_velocity
|
||||
|
||||
if is_correct_airstrafe_input():
|
||||
linear_velocity = execute_airstrafe(linear_velocity, delta, direction)
|
||||
# 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)
|
||||
# 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)
|
||||
|
||||
@ -4385,7 +4385,7 @@ texture = SubResource( 62 )
|
||||
offset = Vector2( 1, 0 )
|
||||
hframes = 6
|
||||
vframes = 6
|
||||
frame = 9
|
||||
frame = 5
|
||||
__meta__ = {
|
||||
"_editor_description_": "YXNlcHJpdGVfd2l6YXJkX2NvbmZpZwpwbGF5ZXJ8PUJsb2JieVNwcml0ZS9CbG9iYnltYXRpb25QbGF5ZXIKc291cmNlfD1yZXM6Ly9hc3NldHMvYmxvYmJ5L2Jsb2JieS1zcHJpdGVzaGVldHQuYXNlcHJpdGUKbGF5ZXJ8PUJsb2JieQpvcF9leHB8PUZhbHNlCm9fZm9sZGVyfD0Kb19uYW1lfD0Kb25seV92aXNpYmxlfD1GYWxzZQpvX2V4X3B8PQo="
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ func execute_movement(delta: float) -> void:
|
||||
# velocity
|
||||
var v = Vector2(velocity.x * movement, 0)
|
||||
time += delta
|
||||
$AnimationPlayer.play("moving")
|
||||
move_and_slide_with_snap(
|
||||
v.rotated(rotation), snap.rotated(rotation), FLOOR_NORMAL, false, 4, PI, false
|
||||
)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=7 format=2]
|
||||
[gd_scene load_steps=8 format=2]
|
||||
|
||||
[ext_resource path="res://assets/enemy/enemy.png" type="Texture" id=1]
|
||||
[ext_resource path="res://assets/enemy/Caterpilllar.png" type="Texture" id=1]
|
||||
[ext_resource path="res://src/Actors/Enemies/Caterpillar.gd" type="Script" id=2]
|
||||
[ext_resource path="res://src/StateMachines/CaterpillarStateMachine.gd" type="Script" id=3]
|
||||
|
||||
@ -13,6 +13,23 @@ extents = Vector2( 15, 8.61814 )
|
||||
[sub_resource type="RectangleShape2D" id=1]
|
||||
extents = Vector2( 14.7108, 7.85442 )
|
||||
|
||||
[sub_resource type="Animation" id=4]
|
||||
resource_name = "moving"
|
||||
loop = true
|
||||
step = 0.05
|
||||
tracks/0/type = "value"
|
||||
tracks/0/path = NodePath("enemy:scale")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/keys = {
|
||||
"times": PoolRealArray( 0, 0.25, 0.5, 0.75 ),
|
||||
"transitions": PoolRealArray( 1, 1, 1, 1 ),
|
||||
"update": 0,
|
||||
"values": [ Vector2( 1, 1 ), Vector2( 1.05, 1 ), Vector2( 1.1, 1.05 ), Vector2( 1.05, 1.1 ) ]
|
||||
}
|
||||
|
||||
[node name="Caterpillar" type="KinematicBody2D" groups=["harmful"]]
|
||||
scale = Vector2( 0.747749, 0.572926 )
|
||||
collision_layer = 2
|
||||
@ -21,11 +38,12 @@ collision/safe_margin = 0.001
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="enemy" type="Sprite" parent="."]
|
||||
position = Vector2( 0, -1.90735e-06 )
|
||||
scale = Vector2( 0.286789, 0.276348 )
|
||||
position = Vector2( 0, -3.49085 )
|
||||
scale = Vector2( 1.01, 1.02 )
|
||||
texture = ExtResource( 1 )
|
||||
|
||||
[node name="VisibilityEnabler2D" type="VisibilityEnabler2D" parent="."]
|
||||
visible = false
|
||||
position = Vector2( 1362.81, -0.138177 )
|
||||
scale = Vector2( 15.4865, 1.28502 )
|
||||
rect = Rect2( -89, -10, 2, 20 )
|
||||
@ -33,30 +51,35 @@ process_parent = true
|
||||
physics_process_parent = true
|
||||
|
||||
[node name="SlopeRaycastLeft" type="RayCast2D" parent="."]
|
||||
visible = false
|
||||
position = Vector2( -7.5, 12 )
|
||||
enabled = true
|
||||
cast_to = Vector2( 0, 2 )
|
||||
collision_mask = 8
|
||||
|
||||
[node name="SlopeRaycastRight" type="RayCast2D" parent="."]
|
||||
visible = false
|
||||
position = Vector2( 7.5, 12 )
|
||||
enabled = true
|
||||
cast_to = Vector2( 0, 2 )
|
||||
collision_mask = 8
|
||||
|
||||
[node name="WallRaycastLeft" type="RayCast2D" parent="."]
|
||||
visible = false
|
||||
position = Vector2( -14.711, 11.5 )
|
||||
enabled = true
|
||||
cast_to = Vector2( -3, 0 )
|
||||
collision_mask = 8
|
||||
|
||||
[node name="WallRaycastRight" type="RayCast2D" parent="."]
|
||||
visible = false
|
||||
position = Vector2( 14.711, 11.5 )
|
||||
enabled = true
|
||||
cast_to = Vector2( 3, 0 )
|
||||
collision_mask = 8
|
||||
|
||||
[node name="StompDetector" type="Area2D" parent="." groups=["weakpoint"]]
|
||||
visible = false
|
||||
modulate = Color( 0, 0.0392157, 1, 1 )
|
||||
light_mask = 0
|
||||
position = Vector2( 0, -6.44095 )
|
||||
@ -66,26 +89,34 @@ monitorable = false
|
||||
priority = 1.0
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="StompDetector"]
|
||||
visible = false
|
||||
position = Vector2( 0, -2.28618 )
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="EnemySkin" type="Area2D" parent="."]
|
||||
process_priority = -1
|
||||
visible = false
|
||||
collision_layer = 2
|
||||
collision_mask = 127
|
||||
input_pickable = false
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionShape2D" parent="EnemySkin"]
|
||||
visible = false
|
||||
position = Vector2( 0, 3.49085 )
|
||||
shape = SubResource( 3 )
|
||||
|
||||
[node name="EnemyBody" type="CollisionShape2D" parent="."]
|
||||
visible = false
|
||||
position = Vector2( -6.37697e-07, 4.36357 )
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="StateMachine" type="Node2D" parent="."]
|
||||
visible = false
|
||||
script = ExtResource( 3 )
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
anims/moving = SubResource( 4 )
|
||||
|
||||
[connection signal="body_entered" from="StompDetector" to="." method="_on_StompDetector_body_entered"]
|
||||
[connection signal="area_entered" from="EnemySkin" to="." method="_on_EnemySkin_area_entered"]
|
||||
[connection signal="body_entered" from="EnemySkin" to="." method="_on_EnemySkin_body_entered"]
|
||||
|
||||
@ -4,6 +4,7 @@ const PhysicsFunc = preload("res://src/Utilities/Physic/PhysicsFunc.gd")
|
||||
export var invincible := false
|
||||
export var speed := 80
|
||||
export var acceleration := 80
|
||||
export var is_harmful := true
|
||||
|
||||
func _ready() -> void:
|
||||
$StompDetector.monitoring = !invincible
|
||||
@ -22,8 +23,6 @@ func _physics_process(delta: float) -> void:
|
||||
mass, delta)
|
||||
velocity.y = move_and_slide(velocity, FLOOR_NORMAL).y
|
||||
|
||||
if player_entered_stomp:
|
||||
$Sprite.frame = 1
|
||||
|
||||
# TODO Detects player over gaps
|
||||
func player_on_floor_direction() -> float:
|
||||
@ -33,3 +32,43 @@ func player_on_floor_direction() -> float:
|
||||
if collider.is_in_group("player"):
|
||||
return sign(collider.position.x - self.position.x)
|
||||
return 0.0
|
||||
|
||||
func _on_StompDetector_body_entered(body: Node) -> void:
|
||||
if !body.is_in_group("player"):
|
||||
return
|
||||
var incoming_vel_vector: Vector2 = body.velocity.normalized()
|
||||
print(rad2deg(abs(incoming_vel_vector.angle_to(Vector2.DOWN.rotated(rotation)))))
|
||||
if abs(incoming_vel_vector.angle_to(Vector2.DOWN.rotated(rotation))) > deg2rad(95) \
|
||||
&& is_harmful:
|
||||
print("too shallow entry")
|
||||
body.die()
|
||||
return
|
||||
signal_manager.emit_signal("got_stomped")
|
||||
#get_node("EnemyBody").disabled = true
|
||||
if(killable):
|
||||
remove_from_group("harmful")
|
||||
die()
|
||||
else:
|
||||
switch_spikes()
|
||||
|
||||
func switch_spikes() -> void:
|
||||
is_harmful = !is_harmful
|
||||
if $Sprite.frame == 0:
|
||||
$Sprite.frame = 1
|
||||
else:
|
||||
$Sprite.frame = 0
|
||||
|
||||
|
||||
|
||||
|
||||
func die() -> void:
|
||||
queue_free()
|
||||
|
||||
|
||||
func _on_EnemySkin_area_entered(area: Area2D) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_EnemySkin_body_entered(body: Node) -> void:
|
||||
if body.is_in_group("player") && is_harmful:
|
||||
body.die()
|
||||
|
||||
@ -2,7 +2,6 @@ extends Actor
|
||||
class_name Enemy
|
||||
|
||||
export(bool) var killable := true
|
||||
var player_entered_stomp = false
|
||||
|
||||
|
||||
func _on_StompDetector_body_entered(body: Node) -> void:
|
||||
@ -10,14 +9,11 @@ func _on_StompDetector_body_entered(body: Node) -> void:
|
||||
return
|
||||
var incoming_vel_vector: Vector2 = body.velocity.normalized()
|
||||
print(rad2deg(abs(incoming_vel_vector.angle_to(Vector2.DOWN.rotated(rotation)))))
|
||||
if abs(incoming_vel_vector.angle_to(Vector2.DOWN.rotated(rotation))) > deg2rad(95) \
|
||||
&& !player_entered_stomp:
|
||||
if abs(incoming_vel_vector.angle_to(Vector2.DOWN.rotated(rotation))) > deg2rad(95):
|
||||
print("too shallow entry")
|
||||
body.die()
|
||||
player_entered_stomp = false
|
||||
return
|
||||
signal_manager.emit_signal("got_stomped")
|
||||
player_entered_stomp = true
|
||||
#get_node("EnemyBody").disabled = true
|
||||
if(killable):
|
||||
remove_from_group("harmful")
|
||||
@ -35,5 +31,5 @@ func _on_EnemySkin_area_entered(area: Area2D) -> void:
|
||||
|
||||
|
||||
func _on_EnemySkin_body_entered(body: Node) -> void:
|
||||
if body.is_in_group("player") && !player_entered_stomp:
|
||||
if body.is_in_group("player"):
|
||||
body.die()
|
||||
|
||||
@ -125,9 +125,6 @@ unique_name_in_owner = true
|
||||
position = Vector2( -70, 1 )
|
||||
scale = Vector2( 0.878906, 0.936025 )
|
||||
|
||||
[node name="BlobbySprite" parent="Blobby" index="5"]
|
||||
frame = 8
|
||||
|
||||
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]
|
||||
parameters/playback = SubResource( 6 )
|
||||
|
||||
@ -223,9 +220,8 @@ speed = 16
|
||||
|
||||
[node name="DartingEnemy" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 609, 67 )
|
||||
mass = 1.0
|
||||
killable = false
|
||||
speed = 300
|
||||
acceleration = 800
|
||||
|
||||
[connection signal="body_exited" from="Blobby/BlobbySkin" to="Blobby" method="_on_BlobbySkin_body_exited"]
|
||||
|
||||
|
||||
@ -128,7 +128,7 @@ death_sound_1 = null
|
||||
death_sound_2 = null
|
||||
|
||||
[node name="BlobbySprite" parent="Blobby" index="5"]
|
||||
frame = 7
|
||||
frame = 6
|
||||
|
||||
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]
|
||||
parameters/playback = SubResource( 7 )
|
||||
|
||||
@ -132,9 +132,6 @@ jump_buffer_filled = null
|
||||
death_sound_1 = null
|
||||
death_sound_2 = null
|
||||
|
||||
[node name="BlobbySprite" parent="Blobby" index="5"]
|
||||
frame = 5
|
||||
|
||||
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]
|
||||
parameters/playback = SubResource( 53 )
|
||||
|
||||
|
||||
@ -135,7 +135,7 @@ death_sound_1 = null
|
||||
death_sound_2 = null
|
||||
|
||||
[node name="BlobbySprite" parent="Blobby" index="5"]
|
||||
frame = 10
|
||||
frame = 9
|
||||
|
||||
[node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"]
|
||||
parameters/playback = SubResource( 6 )
|
||||
@ -194,8 +194,8 @@ max_speed = 100
|
||||
|
||||
[node name="DartingEnemy" parent="." instance=ExtResource( 20 )]
|
||||
position = Vector2( -446, 259 )
|
||||
speed = 200
|
||||
acceleration = 320
|
||||
mass = 1.0
|
||||
killable = false
|
||||
|
||||
[node name="TileMap" type="TileMap" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
@ -131,9 +131,6 @@ 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 )
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -15,13 +15,16 @@ var halted = false
|
||||
var returning = false
|
||||
var initial_distance : float = 1.0
|
||||
|
||||
export(float) var velocity = 1
|
||||
export(float) var return_velocity = 10
|
||||
export(float) var initial_velocity = 20
|
||||
export(float) var max_velocity = 200
|
||||
export(float) var acceleration_force = 1200
|
||||
export(float) var mass = 10
|
||||
export(bool) var avoid_crushing = false
|
||||
export(bool) var fast_retrigger = false
|
||||
|
||||
var velocity = initial_velocity
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
$FlyingLaserCutterBody/Sprite/AnimationPlayer.play("default")
|
||||
@ -49,8 +52,8 @@ func _physics_process(delta: float) -> void:
|
||||
if halted && avoid_crushing:
|
||||
return
|
||||
returning = true
|
||||
velocity=1
|
||||
body.position.x += (max_velocity/3)*-1*delta
|
||||
velocity = initial_velocity
|
||||
body.position.x += return_velocity * -1 * delta
|
||||
|
||||
else:
|
||||
returning = false
|
||||
|
||||
@ -72,6 +72,10 @@ shader_param/oscilation_speed = 0.2
|
||||
|
||||
[node name="FlyingLaserCutter" type="Node2D"]
|
||||
script = ExtResource( 2 )
|
||||
return_velocity = 80.0
|
||||
initial_velocity = 30.0
|
||||
max_velocity = 190.0
|
||||
acceleration_force = 1000.0
|
||||
|
||||
[node name="FlyingLaserCutterBody" type="KinematicBody2D" parent="."]
|
||||
collision_layer = 32
|
||||
|
||||
Loading…
Reference in New Issue
Block a user