TheFlipSide/Scripts/player.gd
2026-03-18 15:25:01 -04:00

145 lines
4.7 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 = []
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
#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.gravity *= -1
#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)