151 lines
4.8 KiB
GDScript
151 lines
4.8 KiB
GDScript
extends CharacterBody2D
|
|
|
|
@onready var current_level : Node2D = $".." #The current level.
|
|
@onready var tile_layer : TileMapLayer = $"../TileMapLayer" #The tile map layer of the current level.
|
|
@onready var particles : GPUParticles2D = $GPUParticles2D #The particles of the player.
|
|
@onready var transition_rect : ColorRect = $SceneTransitionRect #The white rectangle used for fading in and out.
|
|
@onready var transition_anim : AnimationPlayer = $SceneTransitionRect/AnimationPlayer #The animation player attached to the transition rectangle.
|
|
|
|
@export_category("Movement")
|
|
@export var acceleration : float = 50
|
|
@export var braking : float = 20
|
|
@export var move_speed : float = 100
|
|
|
|
var move_input : float
|
|
var dead : bool
|
|
var tile_map_custom_data = []
|
|
|
|
signal player_respawned
|
|
|
|
func _ready() -> void:
|
|
|
|
#Loads in all of the custom tile data from the Tile Map Layer.
|
|
for i in range(tile_layer.tile_set.get_custom_data_layers_count()):
|
|
tile_map_custom_data.append(tile_layer.tile_set.get_custom_data_layer_name(i))
|
|
|
|
#Triggers fade in animation, and then triggers respawn script.
|
|
transition_rect.fade_in()
|
|
respawn()
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
|
|
#Only allows movement if the player is not considered dead.
|
|
if dead == false:
|
|
|
|
#Horizontal movement.
|
|
move_input = Input.get_axis("move_left", "move_right")
|
|
if move_input != 0:
|
|
velocity.x = lerp(velocity.x, move_input * move_speed, acceleration * delta)
|
|
else:
|
|
velocity.x = lerp(velocity.x, 0.0, braking * delta)
|
|
|
|
#Vertical movement.
|
|
velocity.y += al_globals.y_gravity * delta
|
|
|
|
#Horizonal gravity, if applied.
|
|
velocity.x += al_globals.x_gravity * delta
|
|
|
|
#Gravity flip.
|
|
if Input.is_action_just_pressed("flip") and (is_on_floor() or is_on_ceiling() or is_on_wall()):
|
|
al_globals.y_gravity *= -1
|
|
|
|
#If the player is moving downwards fast, turn on particles. Otherwise, disable them.
|
|
if velocity.y > 500 and not (is_on_floor() or is_on_ceiling()):
|
|
particles.emitting = true
|
|
else:
|
|
particles.emitting = false
|
|
|
|
move_and_slide() #Allow physics control.
|
|
tilemap_detection() #Checks for tiles with the "Spike" custom data enabled.
|
|
|
|
#Facilitates the detection and interaction with tiles on the tile map.
|
|
func tilemap_detection() -> void:
|
|
#Adapted from Godot forum post.
|
|
|
|
#Get current tile, and then put the data from it into a variable.
|
|
var tile_coord = tile_layer.local_to_map(tile_layer.to_local(global_position))
|
|
var tile_data = tile_layer.get_cell_tile_data(tile_coord)
|
|
|
|
if not tile_data:
|
|
return
|
|
|
|
#If it has data, check for it. If it has the "spike" custom data, ensure the gravity is set back to normal, and then reset the level.
|
|
for x in tile_map_custom_data:
|
|
if tile_data.get_custom_data(x) == true:
|
|
match x:
|
|
"spike":
|
|
death(false)
|
|
"exit":
|
|
next_level(current_level.next_level)
|
|
"event":
|
|
current_level.event()
|
|
"left_grav":
|
|
al_globals.x_gravity = al_globals.gravity * -5
|
|
"right_grav":
|
|
al_globals.x_gravity = al_globals.gravity * 15
|
|
"canc_grav":
|
|
al_globals.x_gravity = 0
|
|
al_globals.y_gravity = al_globals.gravity
|
|
"void":
|
|
print("you hit the void")
|
|
|
|
#Facilitates the death of the player.
|
|
func death(fallen: bool) -> void:
|
|
|
|
#Prevents movement.
|
|
dead = true
|
|
|
|
#Checks if the player has not fallen out of bounds.
|
|
#If not, halt all current velocity, and shrink them down to 0 scale as a death animation.
|
|
if !fallen:
|
|
velocity.x = 0
|
|
velocity.y = 0
|
|
scale.x = lerp(scale.x, 0.0, 0.1)
|
|
scale.y = lerp(scale.y, 0.0, 0.1)
|
|
|
|
#Pauses for a second for effect, then triggers the respawn function.
|
|
await get_tree().create_timer(1.0).timeout
|
|
respawn()
|
|
|
|
#Facilitates the respawn of the player.
|
|
func respawn() -> void:
|
|
#Reset player velocity to 0, scale them back to full size.
|
|
velocity.y = 0
|
|
scale.x = lerp(scale.x, 1.0, 0.1)
|
|
scale.y = lerp(scale.y, 1.0, 0.1)
|
|
|
|
#Sets the X gravity back to default (nothing)
|
|
if al_globals.x_gravity != 0:
|
|
al_globals.x_gravity = 0
|
|
|
|
#Sets the Y gravity back to default (downwards)
|
|
if al_globals.y_gravity < 0:
|
|
al_globals.y_gravity *= -1
|
|
|
|
player_respawned.emit()
|
|
|
|
#Change their position to the start position of the current level.
|
|
position.x = current_level.startPosX
|
|
position.y = current_level.startPosY
|
|
|
|
#Mark them as alive.
|
|
dead = false
|
|
|
|
#Facilitates transitioning to the next level.
|
|
#level = the path to the next level desired.
|
|
func next_level(level : String) -> void:
|
|
#Prevent movement, and halt their current velocity.
|
|
dead = true
|
|
velocity.x = 0
|
|
velocity.y = 0
|
|
|
|
#Trigger the fade out animation, and then change to the level specified.
|
|
transition_rect.fade_out()
|
|
await get_tree().create_timer(transition_anim.current_animation_length).timeout
|
|
get_tree().change_scene_to_file(level)
|
|
|
|
#Detects if the player fell out of view of the camera.
|
|
#Most likely due to falling out of bounds.
|
|
func _on_visible_on_screen_notifier_2d_screen_exited() -> void:
|
|
if !dead:
|
|
death(true)
|