diff --git a/src/Composer/Composer.gd b/src/Composer/Composer.gd index dcd061c..91424b9 100644 --- a/src/Composer/Composer.gd +++ b/src/Composer/Composer.gd @@ -6,7 +6,7 @@ extends Node ## the option to have a loading screen and the transfer of data between scenes. ## Emitted when Composer has been fully initialised, alongside with its timer. -signal finished_initialising() +signal finished_initialising ## Emitted when provided scene has been invalid (may not exist or path is invalid). signal invalid_scene(path: String) @@ -22,7 +22,7 @@ signal finished_loading(scene: Node) ## Use with loading screens, for scene activation (i.e making scene visible or activating certain game logic). @warning_ignore("unused_signal") -signal loading_activated() +signal loading_activated ## Tracks if composer finished initializing; i.e when its ready to use. var has_initialized: bool = false: @@ -42,7 +42,8 @@ var cache_mode: ResourceLoader.CacheMode = ResourceLoader.CACHE_MODE_REUSE ## This should not be changed unless absolutely necessary. var loading_timer_delay: float = 0.1: set(val): - if !has_initialized: await finished_initialising + if !has_initialized: + await finished_initialising loading_timer_delay = val _loading_timer.wait_time = loading_timer_delay @@ -60,6 +61,7 @@ var _current_scene: Node = null var _current_data: Dictionary = {} + func _enter_tree() -> void: invalid_scene.connect(_on_invalid_scene) failed_loading.connect(_on_failed_loading) @@ -68,22 +70,28 @@ func _enter_tree() -> void: root = get_tree().root _setup_timer() + ## Replaces the current scene with a new scene using a path, ## can also be used for transferring data between scenes with the optional data_to_transfer ## parameter. Data will be stored as new scene metadata, named "transferred_data". func load_scene(path_to_scene: String, data_to_transfer: Dictionary = {}) -> void: - if _is_loading: return + if _is_loading: + return - if !has_initialized: await finished_initialising + if !has_initialized: + await finished_initialising - var loader: Error = ResourceLoader.load_threaded_request(path_to_scene, "", is_using_subthreads, cache_mode) + var loader: Error = ResourceLoader.load_threaded_request( + path_to_scene, "", is_using_subthreads, cache_mode + ) if not ResourceLoader.exists(path_to_scene) or loader == null: invalid_scene.emit(path_to_scene) return _is_loading = true - if _loading_timer == null: _setup_timer() + if _loading_timer == null: + _setup_timer() if _current_scene: _current_scene.queue_free() @@ -93,28 +101,34 @@ func load_scene(path_to_scene: String, data_to_transfer: Dictionary = {}) -> voi _current_data = data_to_transfer _loading_timer.start() + ## Creates a loading screen using a path and adds it to the SceneTree. ## Returns an instance of it for usage with signals. func setup_load_screen(path_to_load_screen: String) -> Node: - if _has_loading_screen: return + if _has_loading_screen: + return _has_loading_screen = true _current_load_screen = load(path_to_load_screen).instantiate() - root.call_deferred("add_child",_current_load_screen) - root.call_deferred("move_child",_current_load_screen, get_child_count()-1) + root.call_deferred("add_child", _current_load_screen) + root.call_deferred("move_child", _current_load_screen, get_child_count() - 1) return _current_load_screen + ## Gets rid of the loading screen. func clear_load_screen() -> void: _current_load_screen.queue_free() _current_load_screen = null _has_loading_screen = false + func _check_loading_status() -> void: var load_progress: Array = [] - var load_status: ResourceLoader.ThreadLoadStatus = ResourceLoader.load_threaded_get_status(_current_loading_path, load_progress) + var load_status: ResourceLoader.ThreadLoadStatus = ResourceLoader.load_threaded_get_status( + _current_loading_path, load_progress + ) match load_status: ResourceLoader.THREAD_LOAD_INVALID_RESOURCE: @@ -129,19 +143,23 @@ func _check_loading_status() -> void: updated_loading.emit(_current_loading_path, int(load_progress[0] * 100)) ResourceLoader.THREAD_LOAD_LOADED: _loading_timer.stop() - finished_loading.emit(ResourceLoader.load_threaded_get(_current_loading_path).instantiate()) + finished_loading.emit( + ResourceLoader.load_threaded_get(_current_loading_path).instantiate() + ) + func _setup_timer() -> void: _loading_timer = Timer.new() _loading_timer.name = "LoadingTimer" _loading_timer.wait_time = 0.1 _loading_timer.timeout.connect(_check_loading_status) - root.call_deferred("add_child",_loading_timer) + root.call_deferred("add_child", _loading_timer) await _loading_timer.ready has_initialized = true + func _on_finished_loading(scene: Node) -> void: scene.set_meta("transferred_data", _current_data) @@ -152,8 +170,10 @@ func _on_finished_loading(scene: Node) -> void: _is_loading = false _current_data = {} + func _on_invalid_scene(path: String) -> void: printerr("Error: Invalid resource: " + path) + func _on_failed_loading(path: String) -> void: printerr("Error: Failed to load resource: " + path) diff --git a/src/Composer/LoadingScreens/Fade/fade_screen.gd b/src/Composer/LoadingScreens/Fade/fade_screen.gd index 4fd873d..859a941 100644 --- a/src/Composer/LoadingScreens/Fade/fade_screen.gd +++ b/src/Composer/LoadingScreens/Fade/fade_screen.gd @@ -1,36 +1,40 @@ extends CanvasLayer -signal finished_fade_in() +signal finished_fade_in @onready var fade_rect: ColorRect = $FadeRect var fade_tween: Tween + func _ready() -> void: fade_in() Composer.finished_loading.connect(_on_finished_loading) + func fade_in() -> void: - fade_rect.color = Color(0,0,0,0) + fade_rect.color = Color(0, 0, 0, 0) fade_tween = get_tree().create_tween() - fade_tween.tween_property(fade_rect,"color:a",1.0,0.75) + fade_tween.tween_property(fade_rect, "color:a", 1.0, 0.75) fade_tween.tween_callback( func() -> void: fade_tween.kill() finished_fade_in.emit() ) + func fade_out() -> void: - fade_rect.color = Color(0,0,0,1) + fade_rect.color = Color(0, 0, 0, 1) fade_tween = get_tree().create_tween() - fade_tween.tween_property(fade_rect,"color:a",0.0,0.75) + fade_tween.tween_property(fade_rect, "color:a", 0.0, 0.75) fade_tween.tween_callback( func() -> void: fade_tween.kill() Composer.clear_load_screen() ) + func _on_finished_loading(_scene: Node) -> void: fade_out() diff --git a/src/Composer/LoadingScreens/ZigZag/zig_zag_screen.gd b/src/Composer/LoadingScreens/ZigZag/zig_zag_screen.gd index eb3ab25..08ad4da 100644 --- a/src/Composer/LoadingScreens/ZigZag/zig_zag_screen.gd +++ b/src/Composer/LoadingScreens/ZigZag/zig_zag_screen.gd @@ -6,12 +6,13 @@ var height: int = ProjectSettings.get_setting("display/window/size/viewport_heig var color: Color = Color.BLACK var points: PackedVector2Array = [] + func setup_zigzag() -> void: var temp_array: PackedVector2Array = [] var x: int = width var y: int = 0 - points.append(Vector2(x,y)) + points.append(Vector2(x, y)) temp_array.append(Vector2(x - (width + 64), y)) while y <= height * 2: @@ -21,7 +22,7 @@ func setup_zigzag() -> void: else: x -= 32 - points.append(Vector2(x,y)) + points.append(Vector2(x, y)) temp_array.append(Vector2(x - (width + 64), y)) temp_array.reverse() @@ -29,5 +30,6 @@ func setup_zigzag() -> void: global_position = Vector2(-width, 0) + func _draw() -> void: draw_polygon(points, [color]) diff --git a/src/Composer/LoadingScreens/ZigZag/zig_zag_screen_boot.gd b/src/Composer/LoadingScreens/ZigZag/zig_zag_screen_boot.gd index 25159ba..79c7692 100644 --- a/src/Composer/LoadingScreens/ZigZag/zig_zag_screen_boot.gd +++ b/src/Composer/LoadingScreens/ZigZag/zig_zag_screen_boot.gd @@ -1,38 +1,42 @@ class_name ZigZag extends CanvasLayer -signal finished_moving() +signal finished_moving @onready var control: Control = $Control var zigzag_tween: Tween + func _ready() -> void: control.setup_zigzag() move_to_center() Composer.finished_loading.connect(_on_finished_loading) + func move_to_center() -> void: zigzag_tween = get_tree().create_tween() zigzag_tween.set_trans(Tween.TRANS_QUAD) - zigzag_tween.tween_property(control,"global_position:x",0,0.75) + zigzag_tween.tween_property(control, "global_position:x", 0, 0.75) zigzag_tween.tween_callback( func() -> void: zigzag_tween.kill() finished_moving.emit() ) + func move_to_back() -> void: control.global_position = Vector2(0, 0) zigzag_tween = get_tree().create_tween() zigzag_tween.set_trans(Tween.TRANS_QUAD) - zigzag_tween.tween_property(control,"global_position:x",control.width,0.75) + zigzag_tween.tween_property(control, "global_position:x", control.width, 0.75) zigzag_tween.tween_callback( func() -> void: zigzag_tween.kill() Composer.clear_load_screen() ) + func _on_finished_loading(_scene: Node) -> void: move_to_back() diff --git a/src/Game/Enemies/Barnacle/barnacle.gd b/src/Game/Enemies/Barnacle/barnacle.gd index 1745bcd..3e69331 100644 --- a/src/Game/Enemies/Barnacle/barnacle.gd +++ b/src/Game/Enemies/Barnacle/barnacle.gd @@ -7,15 +7,18 @@ class_name Barnacle extends Enemy var movement_tween: Tween + func _ready() -> void: show_timer.start() + func kill() -> void: if movement_tween != null: movement_tween.pause() super() + func collision_check(body: Node2D) -> void: if body.is_in_group("Player"): if Globals.player.is_immune: @@ -42,10 +45,11 @@ func collision_check(body: Node2D) -> void: player_hit.emit(false) kill() + func _on_show_timer_timeout() -> void: animated_sprite_2d.play("close") movement_tween = get_tree().create_tween() - movement_tween.tween_property(self, "global_position:y",global_position.y-172, 1.5) + movement_tween.tween_property(self, "global_position:y", global_position.y - 172, 1.5) movement_tween.tween_callback( func() -> void: animated_sprite_2d.play("open") @@ -53,10 +57,11 @@ func _on_show_timer_timeout() -> void: movement_tween.kill() ) + func _on_hide_timer_timeout() -> void: animated_sprite_2d.play("close") movement_tween = get_tree().create_tween() - movement_tween.tween_property(self, "global_position:y",global_position.y+172, 1.5) + movement_tween.tween_property(self, "global_position:y", global_position.y + 172, 1.5) movement_tween.tween_callback( func() -> void: show_timer.wait_time = 1.5 + randf_range(1.0, max_delay) diff --git a/src/Game/Enemies/Bat/bat.gd b/src/Game/Enemies/Bat/bat.gd index 4238d4d..b758588 100644 --- a/src/Game/Enemies/Bat/bat.gd +++ b/src/Game/Enemies/Bat/bat.gd @@ -7,16 +7,19 @@ var movement_tween: Tween var initial_pos: Vector2 var ray2_collider: Node + func _ready() -> void: initial_pos = global_position animated_sprite_2d.play("hang") + func kill() -> void: if movement_tween != null: movement_tween.pause() super() + func move(delta: float) -> void: # Move the bat towards the player when detected if player_ray.is_colliding(): @@ -46,6 +49,7 @@ func move(delta: float) -> void: ray2_collider = null player_tracked_stopped.emit() + func collision_check(body: Node2D) -> void: if body.is_in_group("Player"): if Globals.player.is_immune: @@ -63,13 +67,16 @@ func collision_check(body: Node2D) -> void: player_hit.emit(false) kill() + func _on_player_tracked() -> void: if not is_chasing: is_chasing = true # Calculate the bat's target position and flight time. - var desired_pos: Vector2 = Vector2(Globals.player.global_position.x, Globals.player.global_position.y) - var fly_time: float = clampf((desired_pos.y - initial_pos.y)/2000, 1, 1.5) + var desired_pos: Vector2 = Vector2( + Globals.player.global_position.x, Globals.player.global_position.y + ) + var fly_time: float = clampf((desired_pos.y - initial_pos.y) / 2000, 1, 1.5) animated_sprite_2d.play("fly") movement_tween = get_tree().create_tween() diff --git a/src/Game/Enemies/Bee/bee.gd b/src/Game/Enemies/Bee/bee.gd index 3b764a9..b84c001 100644 --- a/src/Game/Enemies/Bee/bee.gd +++ b/src/Game/Enemies/Bee/bee.gd @@ -4,25 +4,30 @@ var time: float var is_chasing: bool = false var movement_tween: Tween + func _ready() -> void: animated_sprite_2d.play("fly") + func turn_right() -> void: direction = Vector2.RIGHT animated_sprite_2d.flip_h = true player_ray.rotation = deg_to_rad(-224) + func turn_left() -> void: direction = Vector2.LEFT animated_sprite_2d.flip_h = false player_ray.rotation = deg_to_rad(225) + func move(delta: float) -> void: if not is_chasing: super(delta) time += delta - global_position += Vector2(direction.x, sin(time*3)) * actual_speed * delta + global_position += Vector2(direction.x, sin(time * 3)) * actual_speed * delta + func kill() -> void: if movement_tween != null: @@ -30,14 +35,17 @@ func kill() -> void: super() + func _on_player_tracked() -> void: if not is_chasing: is_chasing = true # Calculate the bee's target position and flight time. var initial_pos: Vector2 = global_position - var desired_pos: Vector2 = Vector2(Globals.player.global_position.x, Globals.player.global_position.y) - var fly_time: float = clampf((desired_pos.y - initial_pos.y)/2000, 1, 1.5) + var desired_pos: Vector2 = Vector2( + Globals.player.global_position.x, Globals.player.global_position.y + ) + var fly_time: float = clampf((desired_pos.y - initial_pos.y) / 2000, 1, 1.5) movement_tween = get_tree().create_tween() movement_tween.tween_property(self, "global_position", desired_pos, fly_time) diff --git a/src/Game/Enemies/Ghost/ghost.gd b/src/Game/Enemies/Ghost/ghost.gd index d12b772..49ccc0e 100644 --- a/src/Game/Enemies/Ghost/ghost.gd +++ b/src/Game/Enemies/Ghost/ghost.gd @@ -1,8 +1,10 @@ class_name Ghost extends Enemy + func _ready() -> void: animated_sprite_2d.play("normal") + func collision_check(body: Node2D) -> void: # A ghost is killable only if the player has immunity if body.is_in_group("Player"): @@ -17,19 +19,23 @@ func collision_check(body: Node2D) -> void: else: turn_right() + func move(delta: float) -> void: super(delta) global_position += direction * actual_speed * delta + func kill() -> void: animated_sprite_2d.play("dead") super() + func _on_player_tracked() -> void: actual_speed = chase_speed animated_sprite_2d.play("chase") + func _on_player_tracked_stopped() -> void: actual_speed = speed animated_sprite_2d.play("normal") diff --git a/src/Game/Enemies/Piranha/piranha.gd b/src/Game/Enemies/Piranha/piranha.gd index 80e408d..10672c0 100644 --- a/src/Game/Enemies/Piranha/piranha.gd +++ b/src/Game/Enemies/Piranha/piranha.gd @@ -13,11 +13,13 @@ var y_direction: float = 0.0 var init_pos: Vector2 + func _ready() -> void: init_pos = global_position jump_timer.wait_time = 1.0 + delay jump_timer.start() + func move(delta: float) -> void: super(delta) @@ -46,6 +48,7 @@ func move(delta: float) -> void: global_position += Vector2(0, y_direction) * actual_speed * delta + func _on_jump_timer_timeout() -> void: collision_shape_2d.set_deferred("disabled", false) time = 0.0 diff --git a/src/Game/Enemies/Slime/slime.gd b/src/Game/Enemies/Slime/slime.gd index 58284a3..619b3b8 100644 --- a/src/Game/Enemies/Slime/slime.gd +++ b/src/Game/Enemies/Slime/slime.gd @@ -1,13 +1,16 @@ class_name Slime extends Enemy + func _ready() -> void: animated_sprite_2d.play("walk") + func move(delta: float) -> void: super(delta) global_position += direction * speed * delta + func kill() -> void: animated_sprite_2d.play("dead") super() diff --git a/src/Game/Enemies/Spider/spider.gd b/src/Game/Enemies/Spider/spider.gd index 10ef2e6..b76a696 100644 --- a/src/Game/Enemies/Spider/spider.gd +++ b/src/Game/Enemies/Spider/spider.gd @@ -1,22 +1,27 @@ class_name Spider extends Enemy + func _ready() -> void: animated_sprite_2d.play("walk") + func move(delta: float) -> void: super(delta) global_position += direction * actual_speed * delta + func kill() -> void: animated_sprite_2d.play("dead") super() + # Speeden up the spider if its tracking the player func _on_player_tracked() -> void: actual_speed = chase_speed animated_sprite_2d.speed_scale = 2 + func _on_player_tracked_stopped() -> void: actual_speed = speed animated_sprite_2d.speed_scale = 1 diff --git a/src/Game/Enemies/Spinner/spinner.gd b/src/Game/Enemies/Spinner/spinner.gd index 7c6b7b6..d94bc11 100644 --- a/src/Game/Enemies/Spinner/spinner.gd +++ b/src/Game/Enemies/Spinner/spinner.gd @@ -1,7 +1,7 @@ class_name Spinner extends CharacterBody2D -signal player_tracked() -signal player_tracked_stopped() +signal player_tracked +signal player_tracked_stopped signal player_hit(is_hurt: bool) @export var speed: float = 300.0 @@ -21,21 +21,25 @@ var direction: Vector2 = Vector2.LEFT var actual_speed: float = speed var ray_collider: Node + func _ready() -> void: animated_sprite_2d.play("spin") + func turn_right() -> void: player_ray.rotation = deg_to_rad(180) wall_ray.rotation = deg_to_rad(180) direction = Vector2.RIGHT animated_sprite_2d.flip_h = true + func turn_left() -> void: player_ray.rotation = deg_to_rad(0) wall_ray.rotation = deg_to_rad(0) direction = Vector2.LEFT animated_sprite_2d.flip_h = false + func move(delta: float) -> void: # Change the direction of the enemy if reached a wall if wall_ray.is_colliding(): @@ -66,6 +70,7 @@ func move(delta: float) -> void: move_and_slide() + func kill() -> void: collision_shape_2d.set_deferred("disabled", true) set_physics_process(false) @@ -75,6 +80,7 @@ func kill() -> void: queue_free() + func collision_check(body: Node2D) -> void: if body.is_in_group("Player"): if Globals.player.is_immune: @@ -83,6 +89,7 @@ func collision_check(body: Node2D) -> void: else: player_hit.emit(true) + # Make the spinner jump with the player when its tracking them func _physics_process(delta: float) -> void: if ray_collider != null: @@ -92,14 +99,17 @@ func _physics_process(delta: float) -> void: move(delta) + # Speeden up the spinner if its tracking the player func _on_player_tracked() -> void: actual_speed = chase_speed animated_sprite_2d.speed_scale = 2 + func _on_player_tracked_stopped() -> void: actual_speed = speed animated_sprite_2d.speed_scale = 1 + func _on_hit_box_body_entered(body: Node2D) -> void: collision_check(body) diff --git a/src/Game/Enemies/enemy.gd b/src/Game/Enemies/enemy.gd index e3c54bd..6122844 100644 --- a/src/Game/Enemies/enemy.gd +++ b/src/Game/Enemies/enemy.gd @@ -1,7 +1,7 @@ class_name Enemy extends Area2D -signal player_tracked() -signal player_tracked_stopped() +signal player_tracked +signal player_tracked_stopped signal player_hit(is_hurt: bool) @export var speed: float = 500.0 @@ -20,16 +20,19 @@ var direction: Vector2 = Vector2.LEFT var actual_speed: float = speed var ray_collider: Node + func turn_right() -> void: direction = Vector2.RIGHT animated_sprite_2d.flip_h = true player_ray.rotation = deg_to_rad(180) + func turn_left() -> void: direction = Vector2.LEFT animated_sprite_2d.flip_h = false player_ray.rotation = deg_to_rad(0) + func move(delta: float) -> void: # Change the direction of the enemy if trying to move off a platform or a cliff if not left_ray.is_colliding(): @@ -53,6 +56,7 @@ func move(delta: float) -> void: ray_collider = null player_tracked_stopped.emit() + func kill() -> void: collision_shape_2d.set_deferred("disabled", true) set_physics_process(false) @@ -62,6 +66,7 @@ func kill() -> void: queue_free() + func collision_check(area: Area2D) -> void: if area.is_in_group("Player"): # Kill the enemy by default if a player has immunity @@ -82,12 +87,15 @@ func collision_check(area: Area2D) -> void: player_hit.emit(false) kill() + func _physics_process(delta: float) -> void: move(delta) + func _on_area_entered(area: Area2D) -> void: collision_check(area) + func _on_body_entered(body: Node2D) -> void: # Change the direction if an enemy hit something (that is not the player) if not body.is_in_group("Player"): diff --git a/src/Game/Level/level.gd b/src/Game/Level/level.gd index 6743be8..00676bb 100644 --- a/src/Game/Level/level.gd +++ b/src/Game/Level/level.gd @@ -1,12 +1,13 @@ class_name Level extends Node2D -signal level_end() +signal level_end @onready var tiles: TileMapLayer = $Tiles @onready var player: Player = $Player @export var level_time: int = 200 + func _ready() -> void: # Calculate the camera limit of the level (so that the player doesn't see beyond the boundaries) player.camera_limit_x = (tiles.get_used_rect().size.x * 128) - 128 @@ -21,9 +22,11 @@ func _ready() -> void: for spinner: Spinner in get_tree().get_nodes_in_group("EnemySpinner"): spinner.player_hit.connect(player._on_player_hit) + func _on_level_end_end_reached() -> void: level_end.emit() + func _on_player_player_dead() -> void: var game: Game = get_parent() game.is_counting_time = false diff --git a/src/Game/Objects/LevelEnd/level_end.gd b/src/Game/Objects/LevelEnd/level_end.gd index 2eb12a6..8afaa17 100644 --- a/src/Game/Objects/LevelEnd/level_end.gd +++ b/src/Game/Objects/LevelEnd/level_end.gd @@ -1,10 +1,11 @@ class_name LevelEnd extends Area2D -signal end_reached() +signal end_reached @onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D @onready var animation_player: AnimationPlayer = $AnimationPlayer + func _on_body_entered(body: Node2D) -> void: if not body.is_in_group("Player"): return diff --git a/src/Game/Objects/Pickup/pickup.gd b/src/Game/Objects/Pickup/pickup.gd index fddcc2a..f335e3c 100644 --- a/src/Game/Objects/Pickup/pickup.gd +++ b/src/Game/Objects/Pickup/pickup.gd @@ -6,9 +6,11 @@ signal pickup_collected(object_name: String) @onready var pickup_sound: AudioStreamPlayer = $Area2D/PickupSound @onready var collision_shape_2d: CollisionShape2D = $Area2D/CollisionShape2D + func _ready() -> void: animation_player.play("Move") + func _on_body_entered(body: Node2D) -> void: # Remove the pickup if collected by the player if body.is_in_group("Player"): diff --git a/src/Game/Player/player.gd b/src/Game/Player/player.gd index 841ea9d..9a79912 100644 --- a/src/Game/Player/player.gd +++ b/src/Game/Player/player.gd @@ -1,7 +1,7 @@ class_name Player extends CharacterBody2D signal update_ui(score: int, coins: int, health: int, level: int, time: int) -signal player_dead() +signal player_dead @export var camera_limit_x: int = 3840: set(val): @@ -62,6 +62,7 @@ var is_right_hold: bool var is_hurt: bool = false var is_immune: bool = false + func _ready() -> void: Globals.player = self Globals.game.game_end.connect(ui._on_game_end) @@ -82,14 +83,27 @@ func _ready() -> void: jump_count = jumps - update_ui.emit(Globals.level_score, Globals.level_coins, Globals.player_health, Globals.level, Globals.level_time) + update_ui.emit( + Globals.level_score, + Globals.level_coins, + Globals.player_health, + Globals.level, + Globals.level_time + ) + func _hurt() -> void: if not is_hurt: is_hurt = true Globals.player_health -= 1 ui.play_health_anim("Decrease") - update_ui.emit(Globals.level_score, Globals.level_coins, Globals.player_health, Globals.level, Globals.level_time) + update_ui.emit( + Globals.level_score, + Globals.level_coins, + Globals.player_health, + Globals.level, + Globals.level_time + ) if Globals.player_health <= 0: _kill() @@ -105,6 +119,7 @@ func _hurt() -> void: await animation_player.animation_finished is_hurt = false + func _kill() -> void: Globals.total_deaths += 1 $CollisionShape2D.set_deferred("disabled", true) @@ -117,6 +132,7 @@ func _kill() -> void: animation_player.play("Kill") player_dead.emit() + func _jump() -> void: if jump_count > 0: jump_long.play() @@ -124,14 +140,17 @@ func _jump() -> void: was_jump_pressed = false velocity.y = max_jump_vel + func _coyote_time() -> void: await get_tree().create_timer(coyote_time).timeout is_coyote_active = false + func _buffer_jump() -> void: await get_tree().create_timer(buffer_time).timeout was_jump_pressed = false + func _process(_delta: float) -> void: is_left_hold = Input.is_action_pressed("left") is_right_hold = Input.is_action_pressed("right") @@ -153,6 +172,7 @@ func _process(_delta: float) -> void: if velocity.y > 40: animated_sprite_2d.play("fall") + func _physics_process(delta: float) -> void: var is_jump_tapped: bool = Input.is_action_just_pressed("jump") var is_jump_released: bool = Input.is_action_just_released("jump") @@ -234,14 +254,22 @@ func _physics_process(delta: float) -> void: move_and_slide() + func _on_time_timer_timeout() -> void: Globals.level_time -= 1 - update_ui.emit(Globals.level_score, Globals.level_coins, Globals.player_health, Globals.level, Globals.level_time) + update_ui.emit( + Globals.level_score, + Globals.level_coins, + Globals.player_health, + Globals.level, + Globals.level_time + ) if Globals.level_time == 0: time_timer.stop() _kill() + func _on_player_hit(hurt: bool) -> void: if hurt: _hurt() @@ -253,6 +281,7 @@ func _on_player_hit(hurt: bool) -> void: ui.play_score_anim("Increase") velocity.y = max_jump_vel + func _on_pickup_collected(object_name: String) -> void: # Identify the collected pickup and apply its effects. if object_name.contains("Coin"): @@ -270,7 +299,14 @@ func _on_pickup_collected(object_name: String) -> void: animation_player.play("Immunity") immunity_timer.start() - update_ui.emit(Globals.level_score, Globals.level_coins, Globals.player_health, Globals.level, Globals.level_time) + update_ui.emit( + Globals.level_score, + Globals.level_coins, + Globals.player_health, + Globals.level, + Globals.level_time + ) + func _on_immunity_timeout() -> void: max_speed /= 1.5 @@ -280,6 +316,7 @@ func _on_immunity_timeout() -> void: if Globals.player_health > 0: animation_player.stop() + func _on_level_end_reached() -> void: immunity_timer.stop() time_timer.stop() diff --git a/src/Game/Player/ui.gd b/src/Game/Player/ui.gd index 7211992..d1ba0ed 100644 --- a/src/Game/Player/ui.gd +++ b/src/Game/Player/ui.gd @@ -18,17 +18,20 @@ class_name UI extends Control @onready var coin_anim: AnimationPlayer = %CoinAnim @onready var health_anim: AnimationPlayer = %HealthAnim + func _ready() -> void: dead_animation.play("RESET") prompt_animation.play("RESET") dead_text.hide() end_text.hide() + func set_color_white() -> void: dead_text.add_theme_color_override("font_color", Color.WHITE) end_text.add_theme_color_override("font_color", Color.WHITE) prompt.add_theme_color_override("font_color", Color.WHITE) + func play_score_anim(animation: String) -> void: if score_anim.is_playing() and score_anim.current_animation == animation: score_anim.play(animation) @@ -36,6 +39,7 @@ func play_score_anim(animation: String) -> void: score_anim.play("RESET") score_anim.play(animation) + func play_coin_anim(animation: String) -> void: if coin_anim.is_playing() and coin_anim.current_animation == animation: coin_anim.play(animation) @@ -43,6 +47,7 @@ func play_coin_anim(animation: String) -> void: coin_anim.play("RESET") coin_anim.play(animation) + func play_health_anim(animation: String) -> void: if health_anim.is_playing() and health_anim.current_animation == animation: health_anim.play(animation) @@ -50,6 +55,7 @@ func play_health_anim(animation: String) -> void: health_anim.play("RESET") health_anim.play(animation) + func _on_player_update_ui(score: int, coins: int, health: int, level: int, time: int) -> void: score_text.text = "Score: " + str(score) coin_text.text = "Coins: " + str(coins) @@ -67,10 +73,12 @@ func _on_player_update_ui(score: int, coins: int, health: int, level: int, time: else: time_text.modulate = Color.WHITE + func _on_player_player_dead() -> void: dead_text.show() dead_animation.play("Blink") + func _on_game_end() -> void: end_text_container.show() prompt_animation.play("Blink") diff --git a/src/Game/game.gd b/src/Game/game.gd index a0f5f46..0e93b7b 100644 --- a/src/Game/game.gd +++ b/src/Game/game.gd @@ -1,7 +1,7 @@ class_name Game extends Node2D -signal game_paused() -signal game_end() +signal game_paused +signal game_end @onready var score_increase: AudioStreamPlayer = $ScoreIncrease @onready var win_sound: AudioStreamPlayer = $WinSound @@ -20,6 +20,7 @@ var level: Level var is_counting_time: bool = true var is_game_over: bool = false + func _ready() -> void: Globals.game = self Globals.set_game_theme() @@ -47,6 +48,7 @@ func _ready() -> void: speedrun_ui.show() _setup_speedrun() + func _setup_speedrun() -> void: Globals.start_time = Time.get_unix_time_from_system() * 1000.0 @@ -58,18 +60,24 @@ func _setup_speedrun() -> void: level_5.show() total_time.show() else: - var level_time_label: Label = $SpeedrunUI/Control/VBoxContainer.get_node("Level" + str(Globals.level)) + var level_time_label: Label = $SpeedrunUI/Control/VBoxContainer.get_node( + "Level" + str(Globals.level) + ) level_time_label.show() + func _load_level() -> void: Globals.reset_level() - var level_scene: PackedScene = ResourceLoader.load("res://src/Game/Level/Levels/Level" + str(Globals.level) + ".tscn") + var level_scene: PackedScene = ResourceLoader.load( + "res://src/Game/Level/Levels/Level" + str(Globals.level) + ".tscn" + ) level = level_scene.instantiate() add_child(level) level.level_end.connect(_on_level_end) + func _on_level_end() -> void: is_counting_time = false @@ -89,13 +97,20 @@ func _on_level_end() -> void: score_increase.play() end_timer.start() + func _process(_delta: float) -> void: if Globals.is_speedrun_mode and is_counting_time: var time: float = Time.get_unix_time_from_system() * 1000.0 var diff: float = (time - Globals.start_time) / 1000.0 Globals.level_speedrun_times[Globals.level] = diff - Globals.level_speedrun_times[6] = Globals.level_speedrun_times[1] + Globals.level_speedrun_times[2] + Globals.level_speedrun_times[3] + Globals.level_speedrun_times[4] + Globals.level_speedrun_times[5] + Globals.level_speedrun_times[6] = ( + Globals.level_speedrun_times[1] + + Globals.level_speedrun_times[2] + + Globals.level_speedrun_times[3] + + Globals.level_speedrun_times[4] + + Globals.level_speedrun_times[5] + ) level_1.text = "Level 1: " + str(Globals.level_speedrun_times[1]) level_2.text = "Level 2: " + str(Globals.level_speedrun_times[2]) level_3.text = "Level 3: " + str(Globals.level_speedrun_times[3]) @@ -103,6 +118,7 @@ func _process(_delta: float) -> void: level_5.text = "Level 5: " + str(Globals.level_speedrun_times[5]) total_time.text = "Total: " + str(Globals.level_speedrun_times[6]) + func _input(event: InputEvent) -> void: if Input.is_action_just_pressed("pause"): set_process_input(false) @@ -133,6 +149,7 @@ func _input(event: InputEvent) -> void: else: Globals.go_to_with_fade("res://src/GameEnd/GameEnd.tscn") + func _on_end_timer_timeout() -> void: is_game_over = true @@ -140,7 +157,13 @@ func _on_end_timer_timeout() -> void: Globals.total_score += 1 Globals.level_score += 1 Globals.level_time -= 1 - Globals.player.update_ui.emit(Globals.level_score, Globals.level_coins, Globals.player_health, Globals.level, Globals.level_time) + Globals.player.update_ui.emit( + Globals.level_score, + Globals.level_coins, + Globals.player_health, + Globals.level, + Globals.level_time + ) else: score_increase.stop() game_end.emit() diff --git a/src/Game/pause_ui.gd b/src/Game/pause_ui.gd index c35396a..456eaeb 100644 --- a/src/Game/pause_ui.gd +++ b/src/Game/pause_ui.gd @@ -1,13 +1,15 @@ extends Label -signal game_unpaused() +signal game_unpaused @onready var pause_animation: AnimationPlayer = $PauseAnimation + func _ready() -> void: hide() set_process_input(false) + func _on_game_game_paused() -> void: show() pause_animation.play("Blink") @@ -16,6 +18,7 @@ func _on_game_game_paused() -> void: await get_tree().create_timer(0.5).timeout set_process_input(true) + func _input(event: InputEvent) -> void: if Input.is_action_just_pressed("pause"): pause_animation.stop() diff --git a/src/GameEnd/game_end.gd b/src/GameEnd/game_end.gd index 6b9f8e5..dcf186c 100644 --- a/src/GameEnd/game_end.gd +++ b/src/GameEnd/game_end.gd @@ -7,6 +7,7 @@ extends Control @onready var deaths_text: Label = %DeathsText @onready var enemies_text: Label = %EnemiesText + func _ready() -> void: if Globals.is_new_game: desc.text = """Congratulations! @@ -37,5 +38,6 @@ func _ready() -> void: $GameOver.play() + func _on_menu_button_pressed() -> void: Globals.go_to_with_zigzag("res://src/MainMenu/MainMenu.tscn") diff --git a/src/Globals/Globals.gd b/src/Globals/Globals.gd index 02297d3..864bf32 100644 --- a/src/Globals/Globals.gd +++ b/src/Globals/Globals.gd @@ -23,9 +23,7 @@ var total_deaths: int = 0 var menu_theme: AudioStreamPlayer var button_click: AudioStreamPlayer var game_theme: AudioStreamPlayer -var game_themes: Array = [ - -] +var game_themes: Array = [] var _current_game_theme: int = 0 @@ -48,6 +46,7 @@ var master_volume: float = 100.0 var music_volume: float = 100.0 var sfx_volume: float = 100.0 + func new_game() -> void: # Resets all data, including the level variables _current_game_theme = 0 @@ -68,6 +67,7 @@ func new_game() -> void: total_score = 0 total_time = 0 + func new_level() -> void: # Resets all data, except for the level variables _current_game_theme = 0 @@ -86,17 +86,19 @@ func new_level() -> void: total_time = 0 is_new_game = false + func reset_level() -> void: level_coins = 0 level_kills = 0 level_score = 0 level_time = 0 + func set_game_theme() -> void: # Choose a music track based on settings and the current level. var this_game_theme_id: int = 0 - this_game_theme_id += (Globals.level-1) + this_game_theme_id += (Globals.level - 1) if is_alternative_ost: this_game_theme_id += 5 @@ -114,16 +116,22 @@ func set_game_theme() -> void: game_theme.pitch_scale = 1 game_theme.play() + func go_to_with_fade(scene: String) -> void: - var transition: Node = Composer.setup_load_screen("res://src/Composer/LoadingScreens/Fade/FadeScreen.tscn") + var transition: Node = Composer.setup_load_screen( + "res://src/Composer/LoadingScreens/Fade/FadeScreen.tscn" + ) if transition: button_click.play() await transition.finished_fade_in Composer.load_scene(scene) + func go_to_with_zigzag(scene: String) -> void: - var transition: ZigZag = Composer.setup_load_screen("res://src/Composer/LoadingScreens/ZigZag/ZigZagScreen.tscn") + var transition: ZigZag = Composer.setup_load_screen( + "res://src/Composer/LoadingScreens/ZigZag/ZigZagScreen.tscn" + ) if transition: button_click.play() diff --git a/src/Help/help.gd b/src/Help/help.gd index afa2373..b0a7fba 100644 --- a/src/Help/help.gd +++ b/src/Help/help.gd @@ -15,17 +15,17 @@ var headings: Array[String] = [ var content: Array[String] = [ """use wasd or arrow keys to walk\npress space to jump\npress q in game to go back to menu \npress r to quickly restart the level\npress enter to proceed to the next level""", - """You are an alien who has been travelling space with a spaceship. Unfortunately, a collision with an asteroid forced you to land on earth and catapult yourself. now you have to find your vehicle to get back home.""", - """coding: Sp4r0w & VargaDot\nart & Blocks font: kenney\nWatermelon Days font: Khurasan \nButton sprites: Viktor Gogela\nMusic: joshuuu (alt OST: Clustertruck OST)""", ] + func _ready() -> void: title.text = headings[page] help.text = content[page] + func _on_switch_button_pressed() -> void: if is_switching: return @@ -41,6 +41,7 @@ func _on_switch_button_pressed() -> void: page_switch.tween_property(help, "position:x", 485.5, 1) page_switch.tween_callback(_on_switch_done) + func _on_page_switch() -> void: page = (page + 1) % 3 title.text = headings[page] @@ -48,10 +49,12 @@ func _on_page_switch() -> void: help.position.x = -4000 + func _on_switch_done() -> void: is_switching = false page_switch.kill() + func _on_back_button_pressed() -> void: if is_switching: return diff --git a/src/LevelSelect/level_select.gd b/src/LevelSelect/level_select.gd index f82baa2..7eb5a7a 100644 --- a/src/LevelSelect/level_select.gd +++ b/src/LevelSelect/level_select.gd @@ -13,24 +13,29 @@ var level_previews: Array = [ var level_idx: int = 0 + func _on_play_button_pressed() -> void: Globals.new_level() Globals.menu_theme.stop() Globals.go_to_with_fade("res://src/Game/Game.tscn") + func _on_menu_button_pressed() -> void: Globals.go_to_with_zigzag("res://src/MainMenu/MainMenu.tscn") + func _redraw_level() -> void: Globals.button_click.play() - Globals.level = level_idx+1 - level_title.text = "Level " + str(level_idx+1) + Globals.level = level_idx + 1 + level_title.text = "Level " + str(level_idx + 1) level_preview.texture = level_previews[level_idx] + func _on_prev_button_pressed() -> void: - level_idx = clampi(level_idx - 1, 0, level_previews.size()-1) + level_idx = clampi(level_idx - 1, 0, level_previews.size() - 1) _redraw_level() + func _on_next_button_pressed() -> void: - level_idx = clampi(level_idx + 1, 0, level_previews.size()-1) + level_idx = clampi(level_idx + 1, 0, level_previews.size() - 1) _redraw_level() diff --git a/src/Main/main.gd b/src/Main/main.gd index e5475e6..1bf9255 100644 --- a/src/Main/main.gd +++ b/src/Main/main.gd @@ -1,5 +1,6 @@ class_name Main extends Node + func _ready() -> void: Globals.menu_theme = $MenuTheme Globals.button_click = $ButtonClick diff --git a/src/MainMenu/main_menu.gd b/src/MainMenu/main_menu.gd index a00c184..d2de8fb 100644 --- a/src/MainMenu/main_menu.gd +++ b/src/MainMenu/main_menu.gd @@ -5,6 +5,7 @@ extends Control var main: Main + func _ready() -> void: if not Globals.menu_theme.playing: Globals.menu_theme.play() @@ -14,28 +15,35 @@ func _ready() -> void: if OS.get_name() == "Web": $Buttons/QuitButton.hide() + func _on_play_button_pressed() -> void: # Show a game select panel when play is pressed Globals.button_click.play() level_select_panel.show() + func _on_options_button_pressed() -> void: Globals.go_to_with_zigzag("res://src/Settings/Settings.tscn") + func _on_help_button_pressed() -> void: Globals.go_to_with_zigzag("res://src/Help/Help.tscn") + func _on_quit_button_pressed() -> void: get_tree().quit() + func _on_x_button_pressed() -> void: Globals.button_click.play() level_select_panel.hide() + func _on_new_game_button_pressed() -> void: Globals.menu_theme.stop() Globals.new_game() Globals.go_to_with_fade("res://src/Game/Game.tscn") + func _on_level_select_button_pressed() -> void: Globals.go_to_with_zigzag("res://src/LevelSelect/LevelSelect.tscn") diff --git a/src/Settings/settings.gd b/src/Settings/settings.gd index a36f464..d457bef 100644 --- a/src/Settings/settings.gd +++ b/src/Settings/settings.gd @@ -12,10 +12,12 @@ extends Control @onready var sfx_title: Label = %SfxTitle @onready var sfx_slider: HSlider = %SfxSlider + func _ready() -> void: _update_buttons() _update_sliders() + func _update_buttons() -> void: if Globals.is_alternative_ost: ost_title.text = "Alternative ost: on" @@ -27,40 +29,53 @@ func _update_buttons() -> void: else: speedrun_title.text = "Speedrun mode: off" + func _update_sliders() -> void: master_title.text = "master volume: " + str(Globals.master_volume) master_slider.value = Globals.master_volume - AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear_to_db(Globals.master_volume/100)) + AudioServer.set_bus_volume_db( + AudioServer.get_bus_index("Master"), linear_to_db(Globals.master_volume / 100) + ) music_title.text = "music volume: " + str(Globals.music_volume) music_slider.value = Globals.music_volume - AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Music"), linear_to_db(Globals.music_volume/100)) + AudioServer.set_bus_volume_db( + AudioServer.get_bus_index("Music"), linear_to_db(Globals.music_volume / 100) + ) sfx_title.text = "sfx volume: " + str(Globals.sfx_volume) sfx_slider.value = Globals.sfx_volume - AudioServer.set_bus_volume_db(AudioServer.get_bus_index("SFX"), linear_to_db(Globals.sfx_volume/100)) + AudioServer.set_bus_volume_db( + AudioServer.get_bus_index("SFX"), linear_to_db(Globals.sfx_volume / 100) + ) + func _on_ost_button_pressed() -> void: Globals.button_click.play() Globals.is_alternative_ost = !Globals.is_alternative_ost _update_buttons() + func _on_mode_button_pressed() -> void: Globals.button_click.play() Globals.is_speedrun_mode = !Globals.is_speedrun_mode _update_buttons() + func _on_master_slider_value_changed(value: float) -> void: Globals.master_volume = value _update_sliders() + func _on_music_slider_value_changed(value: float) -> void: Globals.music_volume = value _update_sliders() + func _on_sfx_slider_value_changed(value: float) -> void: Globals.sfx_volume = value _update_sliders() + func _on_back_button_pressed() -> void: Globals.go_to_with_zigzag("res://src/MainMenu/MainMenu.tscn")