commit 18efc36800fd9227d6f127fff67c0f06c3cb4e02
Author: Gerard Gascón <52170489+GerardGascon@users.noreply.github.com>
Date: Thu Apr 24 17:06:24 2025 +0200
init
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..8ad74f7
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# Normalize EOL for all files that Git considers text files.
+* text=auto eol=lf
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4709183
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+# Godot 4+ specific ignores
+.godot/
diff --git a/MalagaJam18.csproj b/MalagaJam18.csproj
new file mode 100644
index 0000000..fde6d00
--- /dev/null
+++ b/MalagaJam18.csproj
@@ -0,0 +1,17 @@
+
+
+ net6.0
+ net7.0
+ net8.0
+ true
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MalagaJam18.sln b/MalagaJam18.sln
new file mode 100644
index 0000000..14d87ec
--- /dev/null
+++ b/MalagaJam18.sln
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MalagaJam18", "MalagaJam18.csproj", "{BD8C6378-570F-44CF-8376-0B7BDAE6637B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ ExportDebug|Any CPU = ExportDebug|Any CPU
+ ExportRelease|Any CPU = ExportRelease|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BD8C6378-570F-44CF-8376-0B7BDAE6637B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BD8C6378-570F-44CF-8376-0B7BDAE6637B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BD8C6378-570F-44CF-8376-0B7BDAE6637B}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
+ {BD8C6378-570F-44CF-8376-0B7BDAE6637B}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
+ {BD8C6378-570F-44CF-8376-0B7BDAE6637B}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
+ {BD8C6378-570F-44CF-8376-0B7BDAE6637B}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b39b0b3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,27 @@
+# Astromovida
+
+## Description
+
+**WARNING**: To be able to control this spaceship you need an advanced space control panel, if you do not have this you will not be able to play.
+
+The captain of the spaceship has fallen unconscious during a space accident, it’s time for you, as a fellow co-pilot and with your great inexperience, to try to prevent this situation from getting worse (it will).
+
+## The Team
+
+> Daerune - Art\
+> ChaosKing - Programming\
+> Gerard Gascón - Programming & Shaders\
+> Sastre del Desastre - Music & SFX\
+> No Coin Arcade - Alternative Controller
+
+## Game Jam
+
+MálagaJam Weekend 18 — July 26th - 28th 2024 (48 hours)
+
+## Theme
+
+From bad to worse
+
+## Languages
+
+Spanish
diff --git a/addons/sound_manager/LICENSE b/addons/sound_manager/LICENSE
new file mode 100644
index 0000000..09351d9
--- /dev/null
+++ b/addons/sound_manager/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021-present Nathan Hoad
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/addons/sound_manager/SoundManager.cs b/addons/sound_manager/SoundManager.cs
new file mode 100644
index 0000000..95a7611
--- /dev/null
+++ b/addons/sound_manager/SoundManager.cs
@@ -0,0 +1,255 @@
+using Godot;
+using Godot.Collections;
+
+namespace NathanHoad
+{
+ public partial class SoundManager : Node
+ {
+ private static Node instance;
+ public static Node Instance
+ {
+ get
+ {
+ if (instance == null)
+ {
+ instance = (Node)Engine.GetSingleton("SoundManager");
+ }
+ return instance;
+ }
+ }
+
+
+ public static ProcessModeEnum SoundProcessMode
+ {
+ get => ((Node)Instance.Get("sound_effects")).ProcessMode;
+ set
+ {
+ ((Node)Instance.Get("sound_effects")).ProcessMode = value;
+ }
+ }
+
+ public static ProcessModeEnum UISoundProcessMode
+ {
+ get => ((Node)Instance.Get("ui_sound_effects")).ProcessMode;
+ set
+ {
+ ((Node)Instance.Get("ui_sound_effects")).ProcessMode = value;
+ }
+ }
+
+ public static ProcessModeEnum AmbientSoundProcessMode
+ {
+ get => ((Node)Instance.Get("ambient_sounds")).ProcessMode;
+ set
+ {
+ ((Node)Instance.Get("ambient_sounds")).ProcessMode = value;
+ }
+ }
+
+ public static ProcessModeEnum MusicProcessMode
+ {
+ get => ((Node)Instance.Get("music")).ProcessMode;
+ set
+ {
+ ((Node)Instance.Get("music")).ProcessMode = value;
+ }
+ }
+
+
+ #region Sounds
+
+ public static float GetSoundVolume()
+ {
+ return (float)Instance.Call("get_sound_volume");
+ }
+
+
+ public static float GetUISoundVolume()
+ {
+ return (float)Instance.Call("get_ui_sound_volume");
+ }
+
+
+ public static void SetSoundVolume(float volume)
+ {
+ Instance.Call("set_sound_volume", volume);
+ }
+
+
+ public static AudioStreamPlayer PlaySound(AudioStream resource, string overrideBus = "")
+ {
+ return (AudioStreamPlayer)Instance.Call("play_sound", resource, overrideBus);
+ }
+
+
+ public static AudioStreamPlayer PlaySoundWithPitch(AudioStream resource, float pitch, string overrideBus = "")
+ {
+ return (AudioStreamPlayer)Instance.Call("play_sound_with_pitch", resource, pitch, overrideBus);
+ }
+
+
+ public static void StopSound(AudioStream resource)
+ {
+ Instance.Call("stop_sound", resource);
+ }
+
+
+ public static AudioStreamPlayer PlayUISound(AudioStream resource, string overrideBus = "")
+ {
+ return (AudioStreamPlayer)Instance.Call("play_ui_sound", resource, overrideBus);
+ }
+
+
+ public static AudioStreamPlayer PlayUISoundWithPitch(AudioStream resource, float pitch, string overrideBus = "")
+ {
+ return (AudioStreamPlayer)Instance.Call("play_ui_sound_with_pitch", resource, pitch, overrideBus);
+ }
+
+
+ public static void StopUISound(AudioStream resource)
+ {
+ Instance.Call("stop_ui_sound", resource);
+ }
+
+
+ public static void SetDefaultSoundBus(string bus)
+ {
+ Instance.Call("set_default_sound_bus", bus);
+ }
+
+
+ public static void SetDefaultUISoundBus(string bus)
+ {
+ Instance.Call("set_default_ui_sound_bus", bus);
+ }
+
+ #endregion
+
+
+ #region Ambient sounds
+
+ public static AudioStreamPlayer PlayAmbientSound(AudioStream resource, float fadeInDuration, string overrideBus = "")
+ {
+ return (AudioStreamPlayer)Instance.Call("play_ambient_sound", resource, fadeInDuration);
+ }
+
+
+ public static void StopAmbientSound(AudioStream resource, float fadeOutDuration)
+ {
+ Instance.Call("stop_ambient_sound", resource, fadeOutDuration);
+ }
+
+
+ public static void StopAllAmbientSounds(float fadeOutDuration)
+ {
+ Instance.Call("stop_all_ambient_sounds", fadeOutDuration);
+ }
+
+
+ public static void SetDefaultAmbientSoundBus(string bus)
+ {
+ Instance.Call("set_default_ambient_sound_bus", bus);
+ }
+
+ #endregion
+
+
+ #region Music
+
+ public static float GetMusicVolume()
+ {
+ return (float)Instance.Call("get_music_volume");
+ }
+
+
+ public static void SetMusicVolume(float volume)
+ {
+ Instance.Call("set_music_volume", volume);
+ }
+
+
+ public static AudioStreamPlayer PlayMusic(AudioStream resource, float crossFadeDuration = 0.0f, string overrideBus = "")
+ {
+ return (AudioStreamPlayer)Instance.Call("play_music", resource, crossFadeDuration, overrideBus);
+ }
+
+
+ public static AudioStreamPlayer PlayMusicFromPosition(AudioStream resource, float position, float crossFadeDuration = 0.0f, string overrideBus = "")
+ {
+ return (AudioStreamPlayer)Instance.Call("play_music_from_position", resource, position, crossFadeDuration, overrideBus);
+ }
+
+
+ public static AudioStreamPlayer PlayMusicAtVolume(AudioStream resource, float volume, float crossFadeDuration = 0.0f, string overrideBus = "")
+ {
+ return (AudioStreamPlayer)Instance.Call("play_music_at_volume", resource, volume, crossFadeDuration, overrideBus);
+ }
+
+ public static AudioStreamPlayer PlayMusicFromPositionAtVolume(AudioStream resource, float position, float volume, float crossFadeDuration = 0.0f, string overrideBus = "")
+ {
+ return (AudioStreamPlayer)Instance.Call("play_music_from_position_at_volume", resource, position, volume, crossFadeDuration, overrideBus);
+ }
+
+
+ public static Array GetMusicTrackHistory()
+ {
+ return (Array)Instance.Call("get_music_track_history");
+ }
+
+
+ public static string GetLastPlayedMusicTrack()
+ {
+ return (string)Instance.Call("get_last_played_music_track");
+ }
+
+
+ public static bool IsMusicPlaying(AudioStream resource = null)
+ {
+ return (bool)Instance.Call("is_music_playing", resource);
+ }
+
+
+ public static bool IsMusicTrackPlaying(string resource_path)
+ {
+ return (bool)Instance.Call("is_music_track_playing", resource_path);
+ }
+
+
+ public static Array GetCurrentlyPlayingMusic()
+ {
+ return (Array)Instance.Call("get_currently_playing_music");
+ }
+
+
+ public static Array GetCurrentlyPlayingTracks()
+ {
+ return (Array)Instance.Call("get_currently_playing_tracks");
+ }
+
+
+ public static void PauseMusic(AudioStream resource = null)
+ {
+ Instance.Call("pause_music", resource);
+ }
+
+
+ public static void ResumeMusic(AudioStream resource = null)
+ {
+ Instance.Call("resume_music", resource);
+ }
+
+
+ public static void StopMusic(float fadeOutDuration = 0.0f)
+ {
+ Instance.Call("stop_music", fadeOutDuration);
+ }
+
+
+ public static void SetDefaultMusicBus(string bus)
+ {
+ Instance.Call("set_default_music_bus", bus);
+ }
+
+ #endregion
+ }
+}
diff --git a/addons/sound_manager/abstract_audio_player_pool.gd b/addons/sound_manager/abstract_audio_player_pool.gd
new file mode 100644
index 0000000..4c54217
--- /dev/null
+++ b/addons/sound_manager/abstract_audio_player_pool.gd
@@ -0,0 +1,148 @@
+extends Node
+
+
+@export var default_busses := []
+@export var default_pool_size := 8
+
+
+var available_players: Array[AudioStreamPlayer] = []
+var busy_players: Array[AudioStreamPlayer] = []
+var bus: String = "Master"
+
+var _tweens: Dictionary = {}
+
+
+func _init(possible_busses: PackedStringArray = default_busses, pool_size: int = default_pool_size) -> void:
+ bus = get_possible_bus(possible_busses)
+
+ for i in pool_size:
+ increase_pool()
+
+func get_possible_bus(possible_busses: PackedStringArray) -> String:
+ for possible_bus in possible_busses:
+ var cases: PackedStringArray = [
+ possible_bus,
+ possible_bus.to_lower(),
+ possible_bus.to_camel_case(),
+ possible_bus.to_pascal_case(),
+ possible_bus.to_snake_case()
+ ]
+ for case in cases:
+ if AudioServer.get_bus_index(case) > -1:
+ return case
+ return "Master"
+
+
+func prepare(resource: AudioStream, override_bus: String = "") -> AudioStreamPlayer:
+ var player: AudioStreamPlayer
+
+ if resource is AudioStreamRandomizer:
+ player = get_player_with_resource(resource)
+
+ if player == null:
+ player = get_available_player()
+
+ player.stream = resource
+ player.bus = override_bus if override_bus != "" else bus
+ player.volume_db = linear_to_db(1.0)
+ player.pitch_scale = 1
+ return player
+
+
+func get_available_player() -> AudioStreamPlayer:
+ if available_players.size() == 0:
+ increase_pool()
+ var player = available_players.pop_front()
+ busy_players.append(player)
+ return player
+
+
+func get_player_with_resource(resource: AudioStream) -> AudioStreamPlayer:
+ for player in busy_players + available_players:
+ if player.stream == resource:
+ return player
+ return null
+
+
+func get_busy_player_with_resource(resource: AudioStream) -> AudioStreamPlayer:
+ for player in busy_players:
+ if player.stream.resource_path == resource.resource_path:
+ return player
+ return null
+
+
+func mark_player_as_available(player: AudioStreamPlayer) -> void:
+ if busy_players.has(player):
+ busy_players.erase(player)
+
+ if available_players.size() >= default_pool_size:
+ player.queue_free()
+ elif not available_players.has(player):
+ available_players.append(player)
+
+
+func increase_pool() -> void:
+ # See if we can reclaim a rogue busy player
+ for player in busy_players:
+ if not player.playing:
+ mark_player_as_available(player)
+ return
+
+ # Otherwise, add a new player
+ var player := AudioStreamPlayer.new()
+ add_child(player)
+ available_players.append(player)
+ player.bus = bus
+ player.finished.connect(_on_player_finished.bind(player))
+
+
+func fade_volume(player: AudioStreamPlayer, from_volume: float, to_volume: float, duration: float) -> AudioStreamPlayer:
+ # Remove any tweens that might already be on this player
+ _remove_tween(player)
+
+ # Start a new tween
+ var tween: Tween = get_tree().create_tween().bind_node(self)
+
+ player.volume_db = from_volume
+ if from_volume > to_volume:
+ # Fade out
+ tween.tween_property(player, "volume_db", to_volume, duration).set_trans(Tween.TRANS_CIRC).set_ease(Tween.EASE_IN)
+ else:
+ # Fade in
+ tween.tween_property(player, "volume_db", to_volume, duration).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
+
+ _tweens[player] = tween
+ tween.finished.connect(_on_fade_completed.bind(player, tween, from_volume, to_volume, duration))
+
+ return player
+
+
+#region Helpers
+
+
+func _remove_tween(player: AudioStreamPlayer) -> void:
+ if _tweens.has(player):
+ var fade: Tween = _tweens.get(player)
+ fade.kill()
+ _tweens.erase(player)
+
+
+#endregion
+
+#region Signals
+
+
+func _on_player_finished(player: AudioStreamPlayer) -> void:
+ mark_player_as_available(player)
+
+
+func _on_fade_completed(player: AudioStreamPlayer, tween: Tween, from_volume: float, to_volume: float, duration: float):
+ _remove_tween(player)
+
+ # If we just faded out then our player is now available
+ if to_volume <= -79.0:
+ player.stop()
+ mark_player_as_available(player)
+
+
+#endregion
diff --git a/addons/sound_manager/ambient_sounds.gd b/addons/sound_manager/ambient_sounds.gd
new file mode 100644
index 0000000..a8f38f1
--- /dev/null
+++ b/addons/sound_manager/ambient_sounds.gd
@@ -0,0 +1,30 @@
+extends "./abstract_audio_player_pool.gd"
+
+
+func play(resource: AudioStream, fade_in_duration: float, override_bus: String = "") -> AudioStreamPlayer:
+ var player = get_busy_player_with_resource(resource)
+
+ # If it's already playing then don't play it again
+ if is_instance_valid(player): return player
+
+ player = prepare(resource, override_bus)
+ fade_volume(player, -80.0, 0.0, fade_in_duration)
+ player.call_deferred("play")
+ return player
+
+
+func stop(resource: AudioStream, fade_out_duration: float = 0.0) -> void:
+ if fade_out_duration <= 0.0:
+ fade_out_duration = 0.01
+
+ for player in busy_players:
+ if player.stream == resource:
+ fade_volume(player, player.volume_db, -80, fade_out_duration)
+
+
+func stop_all(fade_out_duration: float = 0.0) -> void:
+ if fade_out_duration <= 0.0:
+ fade_out_duration = 0.01
+
+ for player in busy_players:
+ fade_volume(player, player.volume_db, -80, fade_out_duration)
diff --git a/addons/sound_manager/music.gd b/addons/sound_manager/music.gd
new file mode 100644
index 0000000..6f6b7b3
--- /dev/null
+++ b/addons/sound_manager/music.gd
@@ -0,0 +1,82 @@
+extends "./abstract_audio_player_pool.gd"
+
+
+var track_history: PackedStringArray = []
+
+
+func play(resource: AudioStream, position: float = 0.0, volume: float = 0.0, crossfade_duration: float = 0.0, override_bus: String = "") -> AudioStreamPlayer:
+ stop(crossfade_duration * 2)
+
+ var player = get_busy_player_with_resource(resource)
+
+ # If the player already exists then just make sure the volume is right (it might have just been fading in or out)
+ if player != null:
+ fade_volume(player, player.volume_db, volume, crossfade_duration)
+ return player
+
+ # Otherwise we need to prep another player and handle its introduction
+ player = prepare(resource, override_bus)
+ fade_volume(player, -80.0, volume, crossfade_duration)
+
+ # Remember this track name
+ track_history.insert(0, resource.resource_path)
+ if track_history.size() > 50:
+ track_history.remove_at(50)
+
+ player.call_deferred("play", position)
+ return player
+
+
+func is_playing(resource: AudioStream) -> bool:
+ if resource != null:
+ return get_busy_player_with_resource(resource) != null
+ else:
+ return busy_players.size() > 0
+
+
+func stop(fade_out_duration: float = 0.0) -> void:
+ for player in busy_players:
+ if fade_out_duration <= 0.0:
+ fade_out_duration = 0.01
+ fade_volume(player, player.volume_db, -80, fade_out_duration)
+
+
+func pause(resource: AudioStream = null) -> void:
+ if resource != null:
+ var player = get_busy_player_with_resource(resource)
+ if is_instance_valid(player):
+ player.stream_paused = true
+ else:
+ for player in busy_players:
+ player.stream_paused = true
+
+
+func resume(resource: AudioStream = null) -> void:
+ if resource != null:
+ var player = get_busy_player_with_resource(resource)
+ if is_instance_valid(player):
+ player.stream_paused = false
+ else:
+ for player in busy_players:
+ player.stream_paused = false
+
+
+func is_track_playing(resource_path: String) -> bool:
+ for player in busy_players:
+ if player.stream.resource_path == resource_path:
+ return true
+ return false
+
+
+func get_currently_playing() -> Array[AudioStream]:
+ var tracks: Array[AudioStream] = []
+ for player in busy_players:
+ tracks.append(player.stream)
+ return tracks
+
+
+func get_currently_playing_tracks() -> PackedStringArray:
+ var tracks: PackedStringArray = []
+ for player in busy_players:
+ tracks.append(player.stream.resource_path)
+ return tracks
diff --git a/addons/sound_manager/plugin.cfg b/addons/sound_manager/plugin.cfg
new file mode 100644
index 0000000..dfdad5a
--- /dev/null
+++ b/addons/sound_manager/plugin.cfg
@@ -0,0 +1,7 @@
+[plugin]
+
+name="SoundManager"
+description="Manage your sounds and music"
+author="Nathan Hoad"
+version="2.6.2"
+script="plugin.gd"
diff --git a/addons/sound_manager/plugin.gd b/addons/sound_manager/plugin.gd
new file mode 100644
index 0000000..30a770a
--- /dev/null
+++ b/addons/sound_manager/plugin.gd
@@ -0,0 +1,14 @@
+@tool
+extends EditorPlugin
+
+
+func _enter_tree():
+ add_autoload_singleton("SoundManager", get_plugin_path() + "/sound_manager.gd")
+
+
+func _exit_tree():
+ remove_autoload_singleton("SoundManager")
+
+
+func get_plugin_path() -> String:
+ return get_script().resource_path.get_base_dir()
diff --git a/addons/sound_manager/sound_effects.gd b/addons/sound_manager/sound_effects.gd
new file mode 100644
index 0000000..30e8008
--- /dev/null
+++ b/addons/sound_manager/sound_effects.gd
@@ -0,0 +1,13 @@
+extends "./abstract_audio_player_pool.gd"
+
+
+func play(resource: AudioStream, override_bus: String = "") -> AudioStreamPlayer:
+ var player = prepare(resource, override_bus)
+ player.call_deferred("play")
+ return player
+
+
+func stop(resource: AudioStream) -> void:
+ for player in busy_players:
+ if player.stream == resource:
+ player.call_deferred("stop")
diff --git a/addons/sound_manager/sound_manager.gd b/addons/sound_manager/sound_manager.gd
new file mode 100644
index 0000000..ebfc992
--- /dev/null
+++ b/addons/sound_manager/sound_manager.gd
@@ -0,0 +1,227 @@
+extends Node
+
+
+const SoundEffectsPlayer = preload("./sound_effects.gd")
+const AmbientSoundsPlayer = preload("./ambient_sounds.gd")
+const MusicPlayer = preload("./music.gd")
+
+var sound_effects: SoundEffectsPlayer = SoundEffectsPlayer.new(["Sounds", "SFX"], 8)
+var ui_sound_effects: SoundEffectsPlayer = SoundEffectsPlayer.new(["UI", "Interface", "Sounds", "SFX"], 8)
+var ambient_sounds: AmbientSoundsPlayer = AmbientSoundsPlayer.new(["Sounds", "SFX"], 1)
+var music: MusicPlayer = MusicPlayer.new(["Music"], 2)
+
+var sound_process_mode: ProcessMode:
+ set(value):
+ sound_effects.process_mode = value
+ get:
+ return sound_effects.process_mode
+
+var ui_sound_process_mode: ProcessMode:
+ set(value):
+ ui_sound_effects.process_mode = value
+ get:
+ return ui_sound_effects.process_mode
+
+
+var ambient_sound_process_mode: ProcessMode:
+ set(value):
+ ambient_sounds.process_mode = value
+ get:
+ return ambient_sounds.process_mode
+
+
+var music_process_mode: ProcessMode:
+ set(value):
+ music.process_mode = value
+ get:
+ return music.process_mode
+
+
+func _init() -> void:
+ Engine.register_singleton("SoundManager", self)
+
+ add_child(sound_effects)
+ add_child(ui_sound_effects)
+ add_child(ambient_sounds)
+ add_child(music)
+
+ self.sound_process_mode = PROCESS_MODE_PAUSABLE
+ self.ui_sound_process_mode = PROCESS_MODE_ALWAYS
+ self.ambient_sound_process_mode = PROCESS_MODE_ALWAYS
+ self.music_process_mode = PROCESS_MODE_ALWAYS
+
+
+#region Sounds
+
+
+func get_sound_volume() -> float:
+ return db_to_linear(AudioServer.get_bus_volume_db(AudioServer.get_bus_index(sound_effects.bus)))
+
+
+func set_sound_volume(volume_between_0_and_1: float) -> void:
+ _show_shared_bus_warning()
+ AudioServer.set_bus_volume_db(AudioServer.get_bus_index(sound_effects.bus), linear_to_db(volume_between_0_and_1))
+
+
+func play_sound(resource: AudioStream, override_bus: String = "") -> AudioStreamPlayer:
+ return sound_effects.play(resource, override_bus)
+
+
+func play_sound_with_pitch(resource: AudioStream, pitch: float = 1.0, override_bus: String = "") -> AudioStreamPlayer:
+ var player = sound_effects.play(resource, override_bus)
+ player.pitch_scale = pitch
+ return player
+
+
+func stop_sound(resource: AudioStream) -> void:
+ return sound_effects.stop(resource)
+
+
+func set_default_sound_bus(bus: String) -> void:
+ sound_effects.bus = bus
+
+
+#endregion
+
+#region UI sounds
+
+
+func get_ui_sound_volume() -> float:
+ return db_to_linear(AudioServer.get_bus_volume_db(AudioServer.get_bus_index(ui_sound_effects.bus)))
+
+
+func set_ui_sound_volume(volume_between_0_and_1: float) -> void:
+ _show_shared_bus_warning()
+ AudioServer.set_bus_volume_db(AudioServer.get_bus_index(ui_sound_effects.bus), linear_to_db(volume_between_0_and_1))
+
+
+func play_ui_sound(resource: AudioStream, override_bus: String = "") -> AudioStreamPlayer:
+ return ui_sound_effects.play(resource, override_bus)
+
+
+func play_ui_sound_with_pitch(resource: AudioStream, pitch: float = 1.0, override_bus: String = "") -> AudioStreamPlayer:
+ var player = ui_sound_effects.play(resource, override_bus)
+ player.pitch_scale = pitch
+ return player
+
+
+func stop_ui_sound(resource: AudioStream) -> void:
+ return ui_sound_effects.stop(resource)
+
+
+func set_default_ui_sound_bus(bus: String) -> void:
+ ui_sound_effects.bus = bus
+
+
+#endregion
+
+#region Ambient sound
+
+
+func get_ambient_sound_volume() -> float:
+ return db_to_linear(AudioServer.get_bus_volume_db(AudioServer.get_bus_index(ambient_sounds.bus)))
+
+
+func set_ambient_sound_volume(volume_between_0_and_1: float) -> void:
+ _show_shared_bus_warning()
+ AudioServer.set_bus_volume_db(AudioServer.get_bus_index(ambient_sounds.bus), linear_to_db(volume_between_0_and_1))
+
+
+func play_ambient_sound(resource: AudioStream, fade_in_duration: float = 0.0, override_bus: String = "") -> AudioStreamPlayer:
+ return ambient_sounds.play(resource, fade_in_duration, override_bus)
+
+
+func stop_ambient_sound(resource: AudioStream, fade_out_duration: float = 0.0) -> void:
+ ambient_sounds.stop(resource, fade_out_duration)
+
+
+func stop_all_ambient_sounds(fade_out_duration: float = 0.0) -> void:
+ ambient_sounds.stop_all(fade_out_duration)
+
+
+func set_default_ambient_sound_bus(bus: String) -> void:
+ ambient_sounds.bus = bus
+
+
+#endregion
+
+#region Music
+
+func get_music_volume() -> float:
+ return db_to_linear(AudioServer.get_bus_volume_db(AudioServer.get_bus_index(music.bus)))
+
+
+func set_music_volume(volume_between_0_and_1: float) -> void:
+ _show_shared_bus_warning()
+ AudioServer.set_bus_volume_db(AudioServer.get_bus_index(music.bus), linear_to_db(volume_between_0_and_1))
+
+
+func play_music(resource: AudioStream, crossfade_duration: float = 0.0, override_bus: String = "") -> AudioStreamPlayer:
+ return music.play(resource, 0.0, 0.0, crossfade_duration, override_bus)
+
+
+func play_music_from_position(resource: AudioStream, position: float = 0.0, crossfade_duration: float = 0.0, override_bus: String = "") -> AudioStreamPlayer:
+ return music.play(resource, position, 0.0, crossfade_duration, override_bus)
+
+
+func play_music_at_volume(resource: AudioStream, volume: float = 0.0, crossfade_duration: float = 0.0, override_bus: String = "") -> AudioStreamPlayer:
+ return music.play(resource, 0.0, volume, crossfade_duration, override_bus)
+
+
+func play_music_from_position_at_volume(resource: AudioStream, position: float = 0.0, volume: float = 0.0, crossfade_duration: float = 0.0, override_bus: String = "") -> AudioStreamPlayer:
+ return music.play(resource, position, volume, crossfade_duration, override_bus)
+
+
+func get_music_track_history() -> Array:
+ return music.track_history
+
+
+func get_last_played_music_track() -> String:
+ return music.track_history[0]
+
+
+func is_music_playing(resource: AudioStream = null) -> bool:
+ return music.is_playing(resource)
+
+
+func is_music_track_playing(resource_path: String) -> bool:
+ return music.is_track_playing(resource_path)
+
+
+func get_currently_playing_music() -> Array:
+ return music.get_currently_playing()
+
+
+func get_currently_playing_music_tracks() -> Array:
+ return music.get_currently_playing_tracks()
+
+
+func pause_music(resource: AudioStream = null) -> void:
+ music.pause(resource)
+
+
+func resume_music(resource: AudioStream = null) -> void:
+ music.resume(resource)
+
+
+func stop_music(fade_out_duration: float = 0.0) -> void:
+ music.stop(fade_out_duration)
+
+
+func set_default_music_bus(bus: String) -> void:
+ music.bus = bus
+
+
+#endregion
+
+#region helpers
+
+
+func _show_shared_bus_warning() -> void:
+ if "Master" in [music.bus, sound_effects.bus, ui_sound_effects.bus, ambient_sounds.bus]:
+ push_warning("Using the Master sound bus directly isn't recommended.")
+ if music.bus == sound_effects.bus or music.bus == ui_sound_effects.bus:
+ push_warning("Both music and sounds are using the same bus: %s" % music.bus)
+
+
+#endregion
diff --git a/audio/ingame/alarm/beep-warning-6387.mp3 b/audio/ingame/alarm/beep-warning-6387.mp3
new file mode 100644
index 0000000..b15e525
Binary files /dev/null and b/audio/ingame/alarm/beep-warning-6387.mp3 differ
diff --git a/audio/ingame/alarm/beep-warning-6387.mp3.import b/audio/ingame/alarm/beep-warning-6387.mp3.import
new file mode 100644
index 0000000..7afdc7a
--- /dev/null
+++ b/audio/ingame/alarm/beep-warning-6387.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://cqkwp7ohpy4wt"
+path="res://.godot/imported/beep-warning-6387.mp3-c84940d2cc390207a21dd32ebf897c13.mp3str"
+
+[deps]
+
+source_file="res://audio/ingame/alarm/beep-warning-6387.mp3"
+dest_files=["res://.godot/imported/beep-warning-6387.mp3-c84940d2cc390207a21dd32ebf897c13.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0.0
+bpm=0.0
+beat_count=0
+bar_beats=4
diff --git a/audio/ingame/alarm/red-alert_nuclear_buzzer-99741.mp3 b/audio/ingame/alarm/red-alert_nuclear_buzzer-99741.mp3
new file mode 100644
index 0000000..e1361da
Binary files /dev/null and b/audio/ingame/alarm/red-alert_nuclear_buzzer-99741.mp3 differ
diff --git a/audio/ingame/alarm/red-alert_nuclear_buzzer-99741.mp3.import b/audio/ingame/alarm/red-alert_nuclear_buzzer-99741.mp3.import
new file mode 100644
index 0000000..8b54cb1
--- /dev/null
+++ b/audio/ingame/alarm/red-alert_nuclear_buzzer-99741.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://gsr48kyou765"
+path="res://.godot/imported/red-alert_nuclear_buzzer-99741.mp3-7fdb1f3aa3b48aa8b5305b7cb2ba9eab.mp3str"
+
+[deps]
+
+source_file="res://audio/ingame/alarm/red-alert_nuclear_buzzer-99741.mp3"
+dest_files=["res://.godot/imported/red-alert_nuclear_buzzer-99741.mp3-7fdb1f3aa3b48aa8b5305b7cb2ba9eab.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/audio/ingame/dinamo03.wav b/audio/ingame/dinamo03.wav
new file mode 100644
index 0000000..6adb0b9
Binary files /dev/null and b/audio/ingame/dinamo03.wav differ
diff --git a/audio/ingame/dinamo03.wav.import b/audio/ingame/dinamo03.wav.import
new file mode 100644
index 0000000..a566b2c
--- /dev/null
+++ b/audio/ingame/dinamo03.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://ddejj31me7x4m"
+path="res://.godot/imported/dinamo03.wav-1b48b38958573c59fbeefcd81ba86b44.sample"
+
+[deps]
+
+source_file="res://audio/ingame/dinamo03.wav"
+dest_files=["res://.godot/imported/dinamo03.wav-1b48b38958573c59fbeefcd81ba86b44.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=2
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0
diff --git a/audio/ingame/explosion/bigboom-42826.mp3 b/audio/ingame/explosion/bigboom-42826.mp3
new file mode 100644
index 0000000..e0219c1
Binary files /dev/null and b/audio/ingame/explosion/bigboom-42826.mp3 differ
diff --git a/audio/ingame/explosion/bigboom-42826.mp3.import b/audio/ingame/explosion/bigboom-42826.mp3.import
new file mode 100644
index 0000000..f5fe7fe
--- /dev/null
+++ b/audio/ingame/explosion/bigboom-42826.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://d3gfdigg7qmkq"
+path="res://.godot/imported/bigboom-42826.mp3-205b84f9ced19b91fde87c2f8aafcc3b.mp3str"
+
+[deps]
+
+source_file="res://audio/ingame/explosion/bigboom-42826.mp3"
+dest_files=["res://.godot/imported/bigboom-42826.mp3-205b84f9ced19b91fde87c2f8aafcc3b.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/audio/ingame/explosion/distant-explosion-47562.mp3 b/audio/ingame/explosion/distant-explosion-47562.mp3
new file mode 100644
index 0000000..7cba8d5
Binary files /dev/null and b/audio/ingame/explosion/distant-explosion-47562.mp3 differ
diff --git a/audio/ingame/explosion/distant-explosion-47562.mp3.import b/audio/ingame/explosion/distant-explosion-47562.mp3.import
new file mode 100644
index 0000000..bd3fb9c
--- /dev/null
+++ b/audio/ingame/explosion/distant-explosion-47562.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://cx6c74xlim53n"
+path="res://.godot/imported/distant-explosion-47562.mp3-bddbb6efff3bde4affdf80a0beff1d29.mp3str"
+
+[deps]
+
+source_file="res://audio/ingame/explosion/distant-explosion-47562.mp3"
+dest_files=["res://.godot/imported/distant-explosion-47562.mp3-bddbb6efff3bde4affdf80a0beff1d29.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/audio/ingame/explosion/medium-explosion-40472.mp3 b/audio/ingame/explosion/medium-explosion-40472.mp3
new file mode 100644
index 0000000..81bfc17
Binary files /dev/null and b/audio/ingame/explosion/medium-explosion-40472.mp3 differ
diff --git a/audio/ingame/explosion/medium-explosion-40472.mp3.import b/audio/ingame/explosion/medium-explosion-40472.mp3.import
new file mode 100644
index 0000000..578a620
--- /dev/null
+++ b/audio/ingame/explosion/medium-explosion-40472.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://dgntsonvvvwjn"
+path="res://.godot/imported/medium-explosion-40472.mp3-691f38b717a2b565d5e248e79174ee79.mp3str"
+
+[deps]
+
+source_file="res://audio/ingame/explosion/medium-explosion-40472.mp3"
+dest_files=["res://.godot/imported/medium-explosion-40472.mp3-691f38b717a2b565d5e248e79174ee79.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/audio/ingame/voicy01.wav b/audio/ingame/voicy01.wav
new file mode 100644
index 0000000..f7493c5
Binary files /dev/null and b/audio/ingame/voicy01.wav differ
diff --git a/audio/ingame/voicy01.wav.import b/audio/ingame/voicy01.wav.import
new file mode 100644
index 0000000..2789f0d
--- /dev/null
+++ b/audio/ingame/voicy01.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://oie1p0ruj3mm"
+path="res://.godot/imported/voicy01.wav-459b3bed15537b45feb63554181da3eb.sample"
+
+[deps]
+
+source_file="res://audio/ingame/voicy01.wav"
+dest_files=["res://.godot/imported/voicy01.wav-459b3bed15537b45feb63554181da3eb.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0
diff --git a/audio/ingame/voicy02.wav b/audio/ingame/voicy02.wav
new file mode 100644
index 0000000..ab164c8
Binary files /dev/null and b/audio/ingame/voicy02.wav differ
diff --git a/audio/ingame/voicy02.wav.import b/audio/ingame/voicy02.wav.import
new file mode 100644
index 0000000..95c73e9
--- /dev/null
+++ b/audio/ingame/voicy02.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://bcmhn2w0xhvog"
+path="res://.godot/imported/voicy02.wav-7fd90ad96aeab5c6b365d1da46177209.sample"
+
+[deps]
+
+source_file="res://audio/ingame/voicy02.wav"
+dest_files=["res://.godot/imported/voicy02.wav-7fd90ad96aeab5c6b365d1da46177209.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0
diff --git a/audio/music.wav b/audio/music.wav
new file mode 100644
index 0000000..fda0f5a
Binary files /dev/null and b/audio/music.wav differ
diff --git a/audio/music.wav.import b/audio/music.wav.import
new file mode 100644
index 0000000..146880b
--- /dev/null
+++ b/audio/music.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://dokkkq3u0tgmr"
+path="res://.godot/imported/music.wav-f70de144183aec913ba40436d959cfed.sample"
+
+[deps]
+
+source_file="res://audio/music.wav"
+dest_files=["res://.godot/imported/music.wav-f70de144183aec913ba40436d959cfed.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=2
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0
diff --git a/audio/sfx/coche_choque.wav b/audio/sfx/coche_choque.wav
new file mode 100644
index 0000000..0d6f5c8
Binary files /dev/null and b/audio/sfx/coche_choque.wav differ
diff --git a/audio/sfx/coche_choque.wav.import b/audio/sfx/coche_choque.wav.import
new file mode 100644
index 0000000..03b9d93
--- /dev/null
+++ b/audio/sfx/coche_choque.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://bbk7bwso0hlpp"
+path="res://.godot/imported/coche_choque.wav-2c26d8d6c2fc6c1587279911b3c86304.sample"
+
+[deps]
+
+source_file="res://audio/sfx/coche_choque.wav"
+dest_files=["res://.godot/imported/coche_choque.wav-2c26d8d6c2fc6c1587279911b3c86304.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0
diff --git a/audio/sfx/cucaracha.wav b/audio/sfx/cucaracha.wav
new file mode 100644
index 0000000..3bd597d
Binary files /dev/null and b/audio/sfx/cucaracha.wav differ
diff --git a/audio/sfx/cucaracha.wav.import b/audio/sfx/cucaracha.wav.import
new file mode 100644
index 0000000..9163b9c
--- /dev/null
+++ b/audio/sfx/cucaracha.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://tpf5bcnaugm8"
+path="res://.godot/imported/cucaracha.wav-72ef6edded57d1827a0848f2c039dc0e.sample"
+
+[deps]
+
+source_file="res://audio/sfx/cucaracha.wav"
+dest_files=["res://.godot/imported/cucaracha.wav-72ef6edded57d1827a0848f2c039dc0e.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0
diff --git a/audio/sfx/le_fishe.wav b/audio/sfx/le_fishe.wav
new file mode 100644
index 0000000..0feb910
Binary files /dev/null and b/audio/sfx/le_fishe.wav differ
diff --git a/audio/sfx/le_fishe.wav.import b/audio/sfx/le_fishe.wav.import
new file mode 100644
index 0000000..805f957
--- /dev/null
+++ b/audio/sfx/le_fishe.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://bibremy5etxpr"
+path="res://.godot/imported/le_fishe.wav-7214aaaf7ecc10b20e5e67ce902b29d2.sample"
+
+[deps]
+
+source_file="res://audio/sfx/le_fishe.wav"
+dest_files=["res://.godot/imported/le_fishe.wav-7214aaaf7ecc10b20e5e67ce902b29d2.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0
diff --git a/audio/sfx/metal.wav b/audio/sfx/metal.wav
new file mode 100644
index 0000000..e6572ca
Binary files /dev/null and b/audio/sfx/metal.wav differ
diff --git a/audio/sfx/metal.wav.import b/audio/sfx/metal.wav.import
new file mode 100644
index 0000000..97a0c2f
--- /dev/null
+++ b/audio/sfx/metal.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://bilo0hq0hxfqx"
+path="res://.godot/imported/metal.wav-0d736a9ee5189ab480f5afe11f05f644.sample"
+
+[deps]
+
+source_file="res://audio/sfx/metal.wav"
+dest_files=["res://.godot/imported/metal.wav-0d736a9ee5189ab480f5afe11f05f644.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=0
diff --git a/events/dialog_event_01.tscn b/events/dialog_event_01.tscn
new file mode 100644
index 0000000..8ee52e9
--- /dev/null
+++ b/events/dialog_event_01.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://df8n0o7xie1pd"]
+
+[ext_resource type="Script" path="res://scripts/events/dialog_event_01.gd" id="1_58hqn"]
+
+[node name="DialogEvent01" type="Node"]
+script = ExtResource("1_58hqn")
diff --git a/events/event_01.tscn b/events/event_01.tscn
new file mode 100644
index 0000000..dd18bee
--- /dev/null
+++ b/events/event_01.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://j2321b52c786"]
+
+[ext_resource type="Script" path="res://scripts/events/event_01.gd" id="1_0bkk8"]
+
+[node name="Event01" type="Node"]
+script = ExtResource("1_0bkk8")
diff --git a/events/event_02.tscn b/events/event_02.tscn
new file mode 100644
index 0000000..1958b10
--- /dev/null
+++ b/events/event_02.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://bgd0kleafe3tt"]
+
+[ext_resource type="Script" path="res://scripts/events/event_02.gd" id="1_rwmf3"]
+
+[node name="Event02" type="Node"]
+script = ExtResource("1_rwmf3")
diff --git a/events/event_03.tscn b/events/event_03.tscn
new file mode 100644
index 0000000..92c9796
--- /dev/null
+++ b/events/event_03.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://bp51aimop7oh4"]
+
+[ext_resource type="Script" path="res://scripts/events/event_03.gd" id="1_4ha5h"]
+
+[node name="Event03" type="Node"]
+script = ExtResource("1_4ha5h")
diff --git a/events/event_04.tscn b/events/event_04.tscn
new file mode 100644
index 0000000..0dbce06
--- /dev/null
+++ b/events/event_04.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://d0gb7qrfx8a2y"]
+
+[ext_resource type="Script" path="res://scripts/events/event_04.gd" id="1_05xcx"]
+
+[node name="Event04" type="Node"]
+script = ExtResource("1_05xcx")
diff --git a/events/event_05.tscn b/events/event_05.tscn
new file mode 100644
index 0000000..a18ef24
--- /dev/null
+++ b/events/event_05.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://cvnyfyuv2n48k"]
+
+[ext_resource type="Script" path="res://scripts/events/event_05.gd" id="1_8uise"]
+
+[node name="Event05" type="Node"]
+script = ExtResource("1_8uise")
diff --git a/events/event_06.tscn b/events/event_06.tscn
new file mode 100644
index 0000000..692540e
--- /dev/null
+++ b/events/event_06.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://bghp7h1dikme2"]
+
+[ext_resource type="Script" path="res://scripts/events/event_06.gd" id="1_jw6mr"]
+
+[node name="Event06" type="Node"]
+script = ExtResource("1_jw6mr")
diff --git a/events/event_07.tscn b/events/event_07.tscn
new file mode 100644
index 0000000..523a3dc
--- /dev/null
+++ b/events/event_07.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://dbbsawl4vhdpr"]
+
+[ext_resource type="Script" path="res://scripts/events/event_07.gd" id="1_6qnir"]
+
+[node name="Event07" type="Node"]
+script = ExtResource("1_6qnir")
diff --git a/events/event_08.tscn b/events/event_08.tscn
new file mode 100644
index 0000000..05a0311
--- /dev/null
+++ b/events/event_08.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://wrd4owimkfca"]
+
+[ext_resource type="Script" path="res://scripts/events/event_08.gd" id="1_rm2lo"]
+
+[node name="Event08" type="Node"]
+script = ExtResource("1_rm2lo")
diff --git a/events/event_09.tscn b/events/event_09.tscn
new file mode 100644
index 0000000..e36725b
--- /dev/null
+++ b/events/event_09.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://b6uffq6kk6qsu"]
+
+[ext_resource type="Script" path="res://scripts/events/event_09.gd" id="1_dkbce"]
+
+[node name="Event09" type="Node"]
+script = ExtResource("1_dkbce")
diff --git a/events/event_10.tscn b/events/event_10.tscn
new file mode 100644
index 0000000..5161b5d
--- /dev/null
+++ b/events/event_10.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://bif5k7krl80mb"]
+
+[ext_resource type="Script" path="res://scripts/events/event_10.gd" id="1_c6skj"]
+
+[node name="Event10" type="Node"]
+script = ExtResource("1_c6skj")
diff --git a/events/event_11.tscn b/events/event_11.tscn
new file mode 100644
index 0000000..b1c4e7e
--- /dev/null
+++ b/events/event_11.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://b3034uxqmdmvi"]
+
+[ext_resource type="Script" path="res://scripts/events/event_11.gd" id="1_mqgus"]
+
+[node name="Event11" type="Node"]
+script = ExtResource("1_mqgus")
diff --git a/events/test_event.tscn b/events/test_event.tscn
new file mode 100644
index 0000000..47e7a3e
--- /dev/null
+++ b/events/test_event.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://d3pnrkd4g5516"]
+
+[ext_resource type="Script" path="res://scripts/event.gd" id="1_c81gq"]
+
+[node name="Node" type="Node"]
+script = ExtResource("1_c81gq")
diff --git a/export_presets.cfg b/export_presets.cfg
new file mode 100644
index 0000000..f2efa7f
--- /dev/null
+++ b/export_presets.cfg
@@ -0,0 +1,65 @@
+[preset.0]
+
+name="Windows Desktop"
+platform="Windows Desktop"
+runnable=true
+dedicated_server=false
+custom_features=""
+export_filter="all_resources"
+include_filter=""
+exclude_filter=""
+export_path="../../OneDrive/Escriptori/Build/Astromovidas.exe"
+encryption_include_filters=""
+encryption_exclude_filters=""
+encrypt_pck=false
+encrypt_directory=false
+
+[preset.0.options]
+
+custom_template/debug=""
+custom_template/release=""
+debug/export_console_wrapper=1
+binary_format/embed_pck=false
+texture_format/bptc=true
+texture_format/s3tc=true
+texture_format/etc=false
+texture_format/etc2=false
+binary_format/architecture="x86_64"
+codesign/enable=false
+codesign/timestamp=true
+codesign/timestamp_server_url=""
+codesign/digest_algorithm=1
+codesign/description=""
+codesign/custom_options=PackedStringArray()
+application/modify_resources=true
+application/icon=""
+application/console_wrapper_icon=""
+application/icon_interpolation=4
+application/file_version=""
+application/product_version=""
+application/company_name=""
+application/product_name=""
+application/file_description=""
+application/copyright=""
+application/trademarks=""
+application/export_angle=0
+ssh_remote_deploy/enabled=false
+ssh_remote_deploy/host="user@host_ip"
+ssh_remote_deploy/port="22"
+ssh_remote_deploy/extra_args_ssh=""
+ssh_remote_deploy/extra_args_scp=""
+ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
+$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
+$trigger = New-ScheduledTaskTrigger -Once -At 00:00
+$settings = New-ScheduledTaskSettingsSet
+$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
+Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
+Start-ScheduledTask -TaskName godot_remote_debug
+while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
+Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
+ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
+Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
+Remove-Item -Recurse -Force '{temp_dir}'"
+dotnet/include_scripts_content=false
+dotnet/include_debug_symbols=true
+dotnet/embed_build_outputs=false
diff --git a/font/DMSerifDisplay-Regular.ttf b/font/DMSerifDisplay-Regular.ttf
new file mode 100644
index 0000000..65a57b7
Binary files /dev/null and b/font/DMSerifDisplay-Regular.ttf differ
diff --git a/font/DMSerifDisplay-Regular.ttf.import b/font/DMSerifDisplay-Regular.ttf.import
new file mode 100644
index 0000000..66bba8e
--- /dev/null
+++ b/font/DMSerifDisplay-Regular.ttf.import
@@ -0,0 +1,33 @@
+[remap]
+
+importer="font_data_dynamic"
+type="FontFile"
+uid="uid://dpsmqkos4x6b5"
+path="res://.godot/imported/DMSerifDisplay-Regular.ttf-c3f77f34c96ecaf3a2a54addd8073748.fontdata"
+
+[deps]
+
+source_file="res://font/DMSerifDisplay-Regular.ttf"
+dest_files=["res://.godot/imported/DMSerifDisplay-Regular.ttf-c3f77f34c96ecaf3a2a54addd8073748.fontdata"]
+
+[params]
+
+Rendering=null
+antialiasing=1
+generate_mipmaps=false
+multichannel_signed_distance_field=false
+msdf_pixel_range=8
+msdf_size=48
+allow_system_fallback=true
+force_autohinter=false
+hinting=1
+subpixel_positioning=1
+oversampling=0.0
+Fallbacks=null
+fallbacks=[]
+Compress=null
+compress=true
+preload=[]
+language_support={}
+script_support={}
+opentype_features={}
diff --git a/icon.svg b/icon.svg
new file mode 100644
index 0000000..3fe4f4a
--- /dev/null
+++ b/icon.svg
@@ -0,0 +1 @@
+
diff --git a/icon.svg.import b/icon.svg.import
new file mode 100644
index 0000000..b1cb88b
--- /dev/null
+++ b/icon.svg.import
@@ -0,0 +1,37 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bp6wsawhevdfj"
+path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icon.svg"
+dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/project.godot b/project.godot
new file mode 100644
index 0000000..ea2bc03
--- /dev/null
+++ b/project.godot
@@ -0,0 +1,166 @@
+; Engine configuration file.
+; It's best edited using the editor UI and not directly,
+; since the parameters that go here are not all obvious.
+;
+; Format:
+; [section] ; section goes between []
+; param=value ; assign values to parameters
+
+config_version=5
+
+[application]
+
+config/name="MalagaJam18"
+run/main_scene="res://scenes/titile.tscn"
+config/features=PackedStringArray("4.2", "C#", "Forward Plus")
+config/icon="res://icon.svg"
+
+[autoload]
+
+SoundManager="*res://addons/sound_manager/sound_manager.gd"
+
+[display]
+
+window/size/viewport_width=1920
+window/size/viewport_height=1080
+window/size/mode=3
+window/size/window_width_override=1152
+window/size/window_height_override=648
+window/stretch/mode="canvas_items"
+
+[dotnet]
+
+project/assembly_name="MalagaJam18"
+
+[editor_plugins]
+
+enabled=PackedStringArray("res://addons/sound_manager/plugin.cfg")
+
+[input]
+
+BTN_1={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":71,"key_label":0,"unicode":103,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+BTN_2={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":72,"key_label":0,"unicode":104,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+BTN_3={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":74,"key_label":0,"unicode":106,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":2,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+BTN_4={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":75,"key_label":0,"unicode":107,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":3,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+LJ_UP={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":11,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+LJ_DOWN={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":12,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+LJ_LEFT={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":13,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+LJ_RIGHT={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":14,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+RJ_UP={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":1.0,"script":null)
+]
+}
+RJ_DOWN={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":5,"axis_value":1.0,"script":null)
+]
+}
+RJ_LEFT={
+"deadzone": 0.5,
+"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":9,"pressure":0.0,"pressed":true,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"echo":false,"script":null)
+]
+}
+RJ_RIGHT={
+"deadzone": 0.5,
+"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":10,"pressure":0.0,"pressed":true,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"echo":false,"script":null)
+]
+}
+BTN_5={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":76,"key_label":0,"unicode":108,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":6,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+DEBUG_Lock_Cursor={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194332,"key_label":0,"unicode":0,"echo":false,"script":null)
+]
+}
+DEBUG_Unlock_Cursor={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194333,"key_label":0,"unicode":0,"echo":false,"script":null)
+]
+}
+BTN_6={
+"deadzone": 0.5,
+"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":4,"pressure":0.0,"pressed":true,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":80,"key_label":0,"unicode":80,"echo":false,"script":null)
+]
+}
+
+[rendering]
+
+environment/defaults/default_clear_color=Color(0.396078, 0.466667, 0.745098, 1)
+RJ_LEFT={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":9,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+RJ_RIGHT={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":10,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+BTN_5={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":76,"key_label":0,"unicode":108,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":6,"pressure":0.0,"pressed":true,"script":null)
+]
+}
+DEBUG_Lock_Cursor={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194332,"key_label":0,"unicode":0,"echo":false,"script":null)
+]
+}
+DEBUG_Unlock_Cursor={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194333,"key_label":0,"unicode":0,"echo":false,"script":null)
+]
+}
diff --git a/resources/sample_action.tres b/resources/sample_action.tres
new file mode 100644
index 0000000..0465b8f
--- /dev/null
+++ b/resources/sample_action.tres
@@ -0,0 +1,9 @@
+[gd_resource type="Resource" script_class="ActionData" load_steps=2 format=3 uid="uid://dld73wxvntv6w"]
+
+[ext_resource type="Script" path="res://scripts/action_data.gd" id="1_1wo7v"]
+
+[resource]
+script = ExtResource("1_1wo7v")
+text = ""
+actions = PackedStringArray()
+duration = 0.0
diff --git a/scenes/crt.tscn b/scenes/crt.tscn
new file mode 100644
index 0000000..ac76c03
--- /dev/null
+++ b/scenes/crt.tscn
@@ -0,0 +1,84 @@
+[gd_scene load_steps=6 format=3 uid="uid://fu50vlhoj4tc"]
+
+[ext_resource type="Shader" path="res://shaders/crt.gdshader" id="1_4lil0"]
+[ext_resource type="Shader" path="res://shaders/crt_glitch.gdshader" id="1_buck2"]
+[ext_resource type="Script" path="res://scripts/crt_controller.gd" id="1_iyhmc"]
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_3sjvv"]
+shader = ExtResource("1_buck2")
+shader_parameter/overlay = true
+shader_parameter/scanlines_opacity = 0.4
+shader_parameter/scanlines_width = 0.25
+shader_parameter/grille_opacity = 0.1
+shader_parameter/resolution = Vector2(1920, 1080)
+shader_parameter/pixelate = false
+shader_parameter/roll = true
+shader_parameter/roll_speed = 0.0
+shader_parameter/roll_size = 0.0
+shader_parameter/roll_variation = 3.444
+shader_parameter/distort_intensity = 0.2
+shader_parameter/noise_opacity = 0.848
+shader_parameter/noise_speed = 11.0
+shader_parameter/static_noise_intensity = 1.0
+shader_parameter/aberration = 0.576
+shader_parameter/brightness = 1.0
+shader_parameter/discolor = false
+shader_parameter/warp_amount = 1.153
+shader_parameter/clip_warp = false
+shader_parameter/vignette_intensity = 1.32
+shader_parameter/vignette_opacity = 0.612
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_276sp"]
+shader = ExtResource("1_4lil0")
+shader_parameter/overlay = false
+shader_parameter/scanlines_opacity = 0.1
+shader_parameter/scanlines_width = 0.25
+shader_parameter/grille_opacity = 0.3
+shader_parameter/resolution = Vector2(640, 480)
+shader_parameter/pixelate = false
+shader_parameter/roll = true
+shader_parameter/roll_speed = 3.0
+shader_parameter/roll_size = 5.0
+shader_parameter/roll_variation = 1.8
+shader_parameter/distort_intensity = 0.01
+shader_parameter/noise_opacity = 0.4
+shader_parameter/noise_speed = 5.0
+shader_parameter/static_noise_intensity = 0.06
+shader_parameter/aberration = 0.01
+shader_parameter/brightness = 1.4
+shader_parameter/discolor = false
+shader_parameter/warp_amount = 1.153
+shader_parameter/clip_warp = false
+shader_parameter/vignette_intensity = 0.4
+shader_parameter/vignette_opacity = 0.5
+
+[node name="CRT" type="Control" node_paths=PackedStringArray("normal_filter", "distortion_filter")]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_iyhmc")
+normal_filter = NodePath("Normal")
+distortion_filter = NodePath("Distortion")
+
+[node name="Distortion" type="ColorRect" parent="."]
+visible = false
+material = SubResource("ShaderMaterial_3sjvv")
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="Normal" type="ColorRect" parent="."]
+visible = false
+material = SubResource("ShaderMaterial_276sp")
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
diff --git a/scenes/end_card.tscn b/scenes/end_card.tscn
new file mode 100644
index 0000000..715812a
--- /dev/null
+++ b/scenes/end_card.tscn
@@ -0,0 +1,64 @@
+[gd_scene load_steps=7 format=3 uid="uid://3gej4vd7cwgk"]
+
+[ext_resource type="Script" path="res://scripts/end_card.gd" id="1_gj4nw"]
+
+[sub_resource type="Gradient" id="Gradient_d3v7t"]
+offsets = PackedFloat32Array(0)
+colors = PackedColorArray(0, 0, 0, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_6m76t"]
+gradient = SubResource("Gradient_d3v7t")
+
+[sub_resource type="LabelSettings" id="LabelSettings_w7cdy"]
+font_size = 72
+
+[sub_resource type="LabelSettings" id="LabelSettings_ea5bh"]
+font_size = 48
+
+[sub_resource type="LabelSettings" id="LabelSettings_2m5lh"]
+font_size = 32
+
+[node name="EndCard" type="Control"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_gj4nw")
+
+[node name="BG" type="TextureRect" parent="."]
+layout_mode = 0
+offset_right = 1936.0
+offset_bottom = 1096.0
+texture = SubResource("GradientTexture2D_6m76t")
+
+[node name="Title" type="Label" parent="."]
+layout_mode = 0
+offset_top = 16.0
+offset_right = 1919.0
+offset_bottom = 918.0
+text = "Moriste de forma espectacular"
+label_settings = SubResource("LabelSettings_w7cdy")
+horizontal_alignment = 1
+vertical_alignment = 1
+
+[node name="Time" type="Label" parent="."]
+layout_mode = 0
+offset_left = 433.0
+offset_top = 523.0
+offset_right = 1501.0
+offset_bottom = 590.0
+text = "Has durado unos segundos"
+label_settings = SubResource("LabelSettings_ea5bh")
+horizontal_alignment = 1
+
+[node name="Subtitle" type="Label" parent="."]
+layout_mode = 0
+offset_left = 431.0
+offset_top = 609.0
+offset_right = 1493.0
+offset_bottom = 654.0
+text = "Pulsa un botón para intentarlo de nuevo"
+label_settings = SubResource("LabelSettings_2m5lh")
+horizontal_alignment = 1
diff --git a/scenes/event_test.tscn b/scenes/event_test.tscn
new file mode 100644
index 0000000..7980eca
--- /dev/null
+++ b/scenes/event_test.tscn
@@ -0,0 +1,61 @@
+[gd_scene load_steps=7 format=3 uid="uid://diosd3dqg1151"]
+
+[ext_resource type="PackedScene" uid="uid://b0ky8bjwk3xp4" path="res://scenes/game_manager.tscn" id="1_p3bjn"]
+[ext_resource type="Script" path="res://scripts/spinner_tester.gd" id="3_bnp66"]
+
+[sub_resource type="LabelSettings" id="LabelSettings_4gvpi"]
+font_size = 30
+font_color = Color(0, 0, 0, 1)
+
+[sub_resource type="Gradient" id="Gradient_ud337"]
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_76fwl"]
+gradient = SubResource("Gradient_ud337")
+
+[sub_resource type="GDScript" id="GDScript_sswhn"]
+resource_name = "ev_starter"
+script/source = "extends Node
+
+@onready var manager = $\"../GameManager\"
+var res_ev01 = load(\"res://events/event_01.tscn\")
+var res_ev02 = load(\"res://events/event_02.tscn\")
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ var ev01 = res_ev01.instantiate()
+ var ev02 = res_ev02.instantiate()
+ await get_tree().create_timer(5).timeout
+ print(\"event 1 start!\")
+ manager.insert_event(ev01)
+ await get_tree().create_timer(10).timeout
+ print(\"event 2 start!\")
+ manager.insert_event(ev02)
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ pass
+"
+
+[node name="EventTest" type="Node2D"]
+
+[node name="GameManager" parent="." instance=ExtResource("1_p3bjn")]
+
+[node name="Label" type="Label" parent="."]
+offset_left = 1265.0
+offset_top = 55.0
+offset_right = 1598.0
+offset_bottom = 97.0
+text = "Dead Spinner Indicator"
+label_settings = SubResource("LabelSettings_4gvpi")
+
+[node name="dead_spinner" type="TextureRect" parent="."]
+offset_left = 1387.0
+offset_top = 136.0
+offset_right = 1451.0
+offset_bottom = 200.0
+texture = SubResource("GradientTexture2D_76fwl")
+script = ExtResource("3_bnp66")
+
+[node name="EventStarter" type="Node" parent="."]
+script = SubResource("GDScript_sswhn")
diff --git a/scenes/game_manager.tscn b/scenes/game_manager.tscn
new file mode 100644
index 0000000..ecd3fde
--- /dev/null
+++ b/scenes/game_manager.tscn
@@ -0,0 +1,17 @@
+[gd_scene load_steps=2 format=3 uid="uid://b0ky8bjwk3xp4"]
+
+[ext_resource type="Script" path="res://scripts/game_manager.gd" id="1_g2l3u"]
+
+[node name="GameManager" type="Node"]
+script = ExtResource("1_g2l3u")
+
+[node name="GracePeriod" type="Timer" parent="."]
+wait_time = 7.0
+one_shot = true
+
+[node name="EventTimer" type="Timer" parent="."]
+wait_time = 4.0
+one_shot = true
+
+[connection signal="timeout" from="GracePeriod" to="." method="_on_grace_period_timeout"]
+[connection signal="timeout" from="EventTimer" to="." method="_on_event_timer_timeout"]
diff --git a/scenes/pulse_generator.tscn b/scenes/pulse_generator.tscn
new file mode 100644
index 0000000..2eec95d
--- /dev/null
+++ b/scenes/pulse_generator.tscn
@@ -0,0 +1,7 @@
+[gd_scene load_steps=2 format=3 uid="uid://ci0e3v6oslfp0"]
+
+[ext_resource type="Script" path="res://scripts/arduino_control/pulse_generator.gd" id="1_v2vrn"]
+
+[node name="PulseGenerator" type="Node"]
+script = ExtResource("1_v2vrn")
+pulseInterval = 0.05
diff --git a/scenes/smoke_particles.tscn b/scenes/smoke_particles.tscn
new file mode 100644
index 0000000..fce6d60
--- /dev/null
+++ b/scenes/smoke_particles.tscn
@@ -0,0 +1,25 @@
+[gd_scene load_steps=4 format=3 uid="uid://13c4hels5d38"]
+
+[ext_resource type="Texture2D" uid="uid://ctlhowug3qhm3" path="res://sprites/fx/whitePuff00.png" id="1_2qblt"]
+
+[sub_resource type="Curve" id="Curve_7skad"]
+_data = [Vector2(0, 0.0360453), 0.0, 1.36273, 0, 0, Vector2(1, 0.364058), -0.50206, 0.0, 0, 0]
+point_count = 2
+
+[sub_resource type="Gradient" id="Gradient_khhnp"]
+colors = PackedColorArray(0.619608, 0.564706, 0.556863, 0.65098, 1, 1, 1, 0)
+
+[node name="smoke_particles" type="CPUParticles2D"]
+amount = 30
+lifetime = 10.0
+texture = ExtResource("1_2qblt")
+spread = 180.0
+gravity = Vector2(0, -10)
+initial_velocity_min = 1.0
+initial_velocity_max = 20.0
+angle_min = 1.0
+angle_max = 360.0
+scale_amount_min = 0.6
+scale_amount_max = 1.3
+scale_amount_curve = SubResource("Curve_7skad")
+color_ramp = SubResource("Gradient_khhnp")
diff --git a/scenes/spaceship.tscn b/scenes/spaceship.tscn
new file mode 100644
index 0000000..dc993a9
--- /dev/null
+++ b/scenes/spaceship.tscn
@@ -0,0 +1,617 @@
+[gd_scene load_steps=60 format=3 uid="uid://4i2kop2nto56"]
+
+[ext_resource type="PackedScene" uid="uid://b0ky8bjwk3xp4" path="res://scenes/game_manager.tscn" id="1_a6e3b"]
+[ext_resource type="PackedScene" uid="uid://fu50vlhoj4tc" path="res://scenes/crt.tscn" id="3_82t0k"]
+[ext_resource type="PackedScene" uid="uid://gds4ywca08dr" path="res://scenes/text_typing.tscn" id="3_enu1t"]
+[ext_resource type="Texture2D" uid="uid://bfuksp220ejmv" path="res://sprites/background.png" id="3_gecr6"]
+[ext_resource type="Texture2D" uid="uid://hwdnd10qvxn4" path="res://sprites/fondo general.png" id="3_iqnac"]
+[ext_resource type="Script" path="res://scripts/effects/shake.gd" id="3_ogixi"]
+[ext_resource type="Texture2D" uid="uid://b02f0labhmgac" path="res://sprites/fx/estrellita_cutre.png" id="4_aaugx"]
+[ext_resource type="Texture2D" uid="uid://r1vlkamrdvut" path="res://sprites/ondas.png" id="4_ugm7x"]
+[ext_resource type="Texture2D" uid="uid://gh06fhvhmn35" path="res://sprites/retrato.png" id="5_8rmq8"]
+[ext_resource type="Script" path="res://scripts/game_flow.gd" id="6_8btdw"]
+[ext_resource type="Texture2D" uid="uid://4abm8qv3y12q" path="res://sprites/motor izquierdo.png" id="6_hoqpc"]
+[ext_resource type="Texture2D" uid="uid://bmwvo4wau13e8" path="res://sprites/motor derecho.png" id="7_mflr1"]
+[ext_resource type="Script" path="res://scripts/effects/engines.gd" id="7_mwk5j"]
+[ext_resource type="Texture2D" uid="uid://cd7ebcxsui4c3" path="res://sprites/ondas1.png" id="7_plbq2"]
+[ext_resource type="Texture2D" uid="uid://d35eui04v3k80" path="res://sprites/ondas2.png" id="8_8nqun"]
+[ext_resource type="Texture2D" uid="uid://c3s7ahkssti82" path="res://sprites/luz 4.png" id="8_mlnnv"]
+[ext_resource type="Script" path="res://scripts/effects/lights.gd" id="9_72l8n"]
+[ext_resource type="Texture2D" uid="uid://3jt08tccjv7p" path="res://sprites/luz 3.png" id="9_bpqdk"]
+[ext_resource type="Texture2D" uid="uid://d33s6pef40flk" path="res://sprites/luz 2.png" id="10_5e241"]
+[ext_resource type="Texture2D" uid="uid://bn160j1ao7da5" path="res://sprites/luz 1.png" id="11_ftija"]
+[ext_resource type="Texture2D" uid="uid://d0fbphqlv1pcp" path="res://sprites/cara tieso.png" id="12_pgcgj"]
+[ext_resource type="Texture2D" uid="uid://hjwhjwfpabnj" path="res://sprites/cara panico.png" id="13_tnoyt"]
+[ext_resource type="Script" path="res://scripts/effects/light_face.gd" id="14_5samn"]
+[ext_resource type="Texture2D" uid="uid://c5p8vhabiwx3d" path="res://sprites/cara feliz.png" id="14_g7lfk"]
+[ext_resource type="Texture2D" uid="uid://cymf1kthfn0am" path="res://sprites/altavoz encendido.png" id="15_ymy1l"]
+[ext_resource type="Script" path="res://scripts/effects/speaker.gd" id="16_53e0o"]
+[ext_resource type="Texture2D" uid="uid://chem1yo0ossu1" path="res://sprites/altavoz apagado.png" id="16_sgsed"]
+[ext_resource type="AudioStream" uid="uid://bbk7bwso0hlpp" path="res://audio/sfx/coche_choque.wav" id="17_uxtxy"]
+[ext_resource type="AudioStream" uid="uid://tpf5bcnaugm8" path="res://audio/sfx/cucaracha.wav" id="18_2e634"]
+[ext_resource type="AudioStream" uid="uid://bilo0hq0hxfqx" path="res://audio/sfx/metal.wav" id="19_jjs05"]
+[ext_resource type="AudioStream" uid="uid://bibremy5etxpr" path="res://audio/sfx/le_fishe.wav" id="20_yv348"]
+[ext_resource type="Script" path="res://scripts/effects/shadow.gd" id="21_86vaa"]
+[ext_resource type="Texture2D" uid="uid://dbq3yme5m8th8" path="res://sprites/retrato2.png" id="28_ax6da"]
+[ext_resource type="Texture2D" uid="uid://dtr13fgmo5i3n" path="res://sprites/retrato3.png" id="29_a1guj"]
+[ext_resource type="Shader" path="res://shaders/vignette.gdshader" id="31_3ivd2"]
+[ext_resource type="Script" path="res://scripts/arduino_control/pulse_generator.gd" id="31_kyreg"]
+[ext_resource type="Script" path="res://scripts/effects/vignette.gd" id="32_qlewj"]
+[ext_resource type="Script" path="res://scripts/effects/smoke.gd" id="36_0c4t4"]
+[ext_resource type="Texture2D" uid="uid://cfj7novxcpont" path="res://sprites/burbuja_Blur.png" id="36_7dbgh"]
+[ext_resource type="Texture2D" uid="uid://dfwqex0goxj5j" path="res://sprites/mascara.png" id="36_l7cj1"]
+[ext_resource type="AudioStream" uid="uid://dokkkq3u0tgmr" path="res://audio/music.wav" id="39_ecyg1"]
+[ext_resource type="AudioStream" uid="uid://ddejj31me7x4m" path="res://audio/ingame/dinamo03.wav" id="40_swbqh"]
+[ext_resource type="Script" path="res://scripts/explosion_player.gd" id="43_4k1hy"]
+[ext_resource type="AudioStream" uid="uid://d3gfdigg7qmkq" path="res://audio/ingame/explosion/bigboom-42826.mp3" id="44_r4e8v"]
+[ext_resource type="AudioStream" uid="uid://cx6c74xlim53n" path="res://audio/ingame/explosion/distant-explosion-47562.mp3" id="45_ojk1h"]
+[ext_resource type="AudioStream" uid="uid://dgntsonvvvwjn" path="res://audio/ingame/explosion/medium-explosion-40472.mp3" id="46_nvk6r"]
+[ext_resource type="AudioStream" uid="uid://cqkwp7ohpy4wt" path="res://audio/ingame/alarm/beep-warning-6387.mp3" id="47_ra8w3"]
+[ext_resource type="AudioStream" uid="uid://gsr48kyou765" path="res://audio/ingame/alarm/red-alert_nuclear_buzzer-99741.mp3" id="48_3jpdp"]
+
+[sub_resource type="Animation" id="Animation_hsrc7"]
+resource_name = "game_flow"
+length = 120.0
+tracks/0/type = "method"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("GameManager/AnimationPlayer")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(2, 7, 13, 16.1, 18.1, 24, 31, 34, 37.1, 42, 48, 49, 53, 56, 59, 62, 67, 68, 73, 79, 80, 82.9, 86, 91, 97, 101, 104.5, 106, 109, 114),
+"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
+"values": [{
+"args": [],
+"method": &"mishap1"
+}, {
+"args": [],
+"method": &"play_5s_shake"
+}, {
+"args": [],
+"method": &"mishap2"
+}, {
+"args": [2],
+"method": &"distort"
+}, {
+"args": [],
+"method": &"play_5s_shake"
+}, {
+"args": [],
+"method": &"mishap3"
+}, {
+"args": [],
+"method": &"play_5s_shake"
+}, {
+"args": [2],
+"method": &"distort"
+}, {
+"args": [],
+"method": &"mishap4"
+}, {
+"args": [],
+"method": &"play_5s_shake"
+}, {
+"args": [],
+"method": &"mishap5"
+}, {
+"args": [3],
+"method": &"distort"
+}, {
+"args": [],
+"method": &"play_5s_shake"
+}, {
+"args": [6],
+"method": &"distort"
+}, {
+"args": [],
+"method": &"mishap6"
+}, {
+"args": [],
+"method": &"play_5s_shake"
+}, {
+"args": [6],
+"method": &"distort"
+}, {
+"args": [],
+"method": &"mishap7"
+}, {
+"args": [],
+"method": &"play_5s_shake"
+}, {
+"args": [],
+"method": &"mishap8"
+}, {
+"args": [],
+"method": &"play_5s_shake"
+}, {
+"args": [2],
+"method": &"distort"
+}, {
+"args": [],
+"method": &"mishap9"
+}, {
+"args": [],
+"method": &"play_5s_shake"
+}, {
+"args": [],
+"method": &"mishap10"
+}, {
+"args": [],
+"method": &"play_5s_shake"
+}, {
+"args": [4],
+"method": &"distort"
+}, {
+"args": [],
+"method": &"mishap11"
+}, {
+"args": [],
+"method": &"play_5s_shake"
+}, {
+"args": [],
+"method": &"end_game"
+}]
+}
+tracks/1/type = "method"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath("ArduinoShake")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/keys = {
+"times": PackedFloat32Array(),
+"transitions": PackedFloat32Array(),
+"values": []
+}
+tracks/2/type = "method"
+tracks/2/imported = false
+tracks/2/enabled = true
+tracks/2/path = NodePath("Spawner")
+tracks/2/interp = 1
+tracks/2/loop_wrap = true
+tracks/2/keys = {
+"times": PackedFloat32Array(6, 12.5, 18.3, 24.6, 32.1, 37.5, 45.2, 51.5, 59.5, 69.6, 78.3, 86.1, 95.5, 105.1),
+"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
+"values": [{
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}, {
+"args": [],
+"method": &"spawn"
+}]
+}
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_86qm3"]
+_data = {
+"game_flow": SubResource("Animation_hsrc7")
+}
+
+[sub_resource type="Animation" id="Animation_uyck0"]
+resource_name = "RESET"
+length = 0.1
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("../Camera2D:intensity")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [0.0]
+}
+tracks/1/type = "value"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath("../CanvasLayer/Vignette:intensity")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [0.0]
+}
+
+[sub_resource type="Animation" id="Animation_mq20l"]
+resource_name = "shake 5s"
+length = 5.0
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("../Camera2D:intensity")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0, 4.9, 5),
+"transitions": PackedFloat32Array(1, 1, 1),
+"update": 0,
+"values": [0.0, 1.0, 0.0]
+}
+tracks/1/type = "value"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath("../CanvasLayer/Vignette:intensity")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/keys = {
+"times": PackedFloat32Array(0, 4.9, 5),
+"transitions": PackedFloat32Array(1, 1, 1),
+"update": 0,
+"values": [0.0, 1.5, 0.0]
+}
+tracks/2/type = "method"
+tracks/2/imported = false
+tracks/2/enabled = true
+tracks/2/path = NodePath("../ArduinoShake")
+tracks/2/interp = 1
+tracks/2/loop_wrap = true
+tracks/2/keys = {
+"times": PackedFloat32Array(4.7),
+"transitions": PackedFloat32Array(1),
+"values": [{
+"args": [2],
+"method": &"shakeController"
+}]
+}
+tracks/3/type = "method"
+tracks/3/imported = false
+tracks/3/enabled = true
+tracks/3/path = NodePath("../sfx")
+tracks/3/interp = 1
+tracks/3/loop_wrap = true
+tracks/3/keys = {
+"times": PackedFloat32Array(1.8, 4.7),
+"transitions": PackedFloat32Array(1, 1),
+"values": [{
+"args": [],
+"method": &"play_alarm"
+}, {
+"args": [],
+"method": &"play_explosion"
+}]
+}
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_odc1g"]
+_data = {
+"RESET": SubResource("Animation_uyck0"),
+"shake 5s": SubResource("Animation_mq20l")
+}
+
+[sub_resource type="Curve" id="Curve_pxncd"]
+_data = [Vector2(0, 0.0395778), 0.0, 0.0, 0, 0, Vector2(1, 0.751319), 0.0, 0.0, 0, 0]
+point_count = 2
+
+[sub_resource type="Gradient" id="Gradient_sww5j"]
+interpolation_mode = 2
+offsets = PackedFloat32Array(0, 0.224638)
+colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 1)
+
+[sub_resource type="SpriteFrames" id="SpriteFrames_m4rwq"]
+animations = [{
+"frames": [{
+"duration": 1.0,
+"texture": ExtResource("4_ugm7x")
+}, {
+"duration": 1.0,
+"texture": ExtResource("7_plbq2")
+}, {
+"duration": 1.0,
+"texture": ExtResource("8_8nqun")
+}],
+"loop": true,
+"name": &"default",
+"speed": 10.0
+}]
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_7nj25"]
+shader = ExtResource("31_3ivd2")
+shader_parameter/inner_radius = 0.1
+shader_parameter/outer_radius = 1.0
+shader_parameter/vignette_strength = 0.0
+shader_parameter/dither_strength = 0.03
+shader_parameter/vignette_color = Color(1, 0, 0, 1)
+
+[sub_resource type="Curve" id="Curve_lmmd8"]
+max_value = 0.94
+_data = [Vector2(0, 0.94), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
+point_count = 2
+
+[sub_resource type="Curve" id="Curve_4x2qo"]
+max_value = 0.94
+_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.129747, 0.459698), 0.0, 0.0, 0, 0, Vector2(0.211886, 0.330693), 0.0, 0.0, 0, 0, Vector2(0.344937, 0.664358), 0.0, 0.0, 0, 0, Vector2(0.490956, 0.567527), 0.0, 0.0, 0, 0, Vector2(0.741602, 0.935452), 0.0, 0.0, 0, 0]
+point_count = 6
+
+[node name="Spaceship" type="Node2D"]
+
+[node name="GameManager" parent="." node_paths=PackedStringArray("text_typer", "dinamo") instance=ExtResource("1_a6e3b")]
+text_typer = NodePath("../TextTyping")
+dinamo = NodePath("../Dinamo")
+
+[node name="AnimationPlayer" type="AnimationPlayer" parent="GameManager" node_paths=PackedStringArray("crt")]
+root_node = NodePath("../..")
+libraries = {
+"": SubResource("AnimationLibrary_86qm3")
+}
+autoplay = "game_flow"
+script = ExtResource("6_8btdw")
+crt = NodePath("../../CanvasLayer/CRT")
+
+[node name="VFX" type="AnimationPlayer" parent="GameManager"]
+libraries = {
+"": SubResource("AnimationLibrary_odc1g")
+}
+
+[node name="Sprites" type="Node2D" parent="."]
+
+[node name="Space" type="Sprite2D" parent="Sprites"]
+position = Vector2(960, 540)
+texture = ExtResource("3_gecr6")
+
+[node name="CPUParticles2D" type="CPUParticles2D" parent="Sprites"]
+position = Vector2(960, 540)
+amount = 200
+lifetime = 20.0
+preprocess = 100.0
+texture = ExtResource("4_aaugx")
+spread = 180.0
+gravity = Vector2(0, 0)
+initial_velocity_min = 25.0
+initial_velocity_max = 50.0
+angular_velocity_max = 180.0
+linear_accel_min = 5.0
+linear_accel_max = 5.0
+angle_min = -180.0
+angle_max = 180.0
+scale_amount_min = 0.25
+scale_amount_max = 0.5
+scale_amount_curve = SubResource("Curve_pxncd")
+color_ramp = SubResource("Gradient_sww5j")
+
+[node name="Background" type="Sprite2D" parent="Sprites"]
+position = Vector2(960, 540)
+texture = ExtResource("3_iqnac")
+
+[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="Sprites"]
+sprite_frames = SubResource("SpriteFrames_m4rwq")
+autoplay = "default"
+frame_progress = 0.604089
+offset = Vector2(960, 540)
+
+[node name="Retrato" type="Sprite2D" parent="Sprites"]
+position = Vector2(960, 540)
+texture = ExtResource("5_8rmq8")
+
+[node name="Motores" type="Node2D" parent="Sprites"]
+script = ExtResource("7_mwk5j")
+leftPowerSprites = Array[Texture2D]([null, ExtResource("6_hoqpc")])
+rightPowerSprites = Array[Texture2D]([null, ExtResource("7_mflr1")])
+transitionDelta = 1.0
+
+[node name="MotorIzquierdo" type="Sprite2D" parent="Sprites/Motores"]
+position = Vector2(960, 540)
+texture = ExtResource("6_hoqpc")
+
+[node name="MotorDerecho" type="Sprite2D" parent="Sprites/Motores"]
+position = Vector2(960, 540)
+texture = ExtResource("7_mflr1")
+
+[node name="Luces" type="Node2D" parent="Sprites" node_paths=PackedStringArray("light1", "light2", "light3", "light4")]
+script = ExtResource("9_72l8n")
+light1 = NodePath("Luz1")
+light2 = NodePath("Luz2")
+light3 = NodePath("Luz3")
+light4 = NodePath("Luz4")
+
+[node name="Luz4" type="Sprite2D" parent="Sprites/Luces"]
+position = Vector2(960, 540)
+texture = ExtResource("8_mlnnv")
+
+[node name="Luz3" type="Sprite2D" parent="Sprites/Luces"]
+position = Vector2(960, 540)
+texture = ExtResource("9_bpqdk")
+
+[node name="Luz2" type="Sprite2D" parent="Sprites/Luces"]
+position = Vector2(960, 540)
+texture = ExtResource("10_5e241")
+
+[node name="Luz1" type="Sprite2D" parent="Sprites/Luces"]
+position = Vector2(960, 540)
+texture = ExtResource("11_ftija")
+
+[node name="Cara" type="Node2D" parent="Sprites" node_paths=PackedStringArray("game_manager")]
+script = ExtResource("14_5samn")
+game_manager = NodePath("../../GameManager")
+
+[node name="CaraTieso" type="Sprite2D" parent="Sprites/Cara"]
+position = Vector2(960, 540)
+texture = ExtResource("12_pgcgj")
+
+[node name="CaraPanico" type="Sprite2D" parent="Sprites/Cara"]
+position = Vector2(960, 540)
+texture = ExtResource("13_tnoyt")
+
+[node name="CaraFeliz" type="Sprite2D" parent="Sprites/Cara"]
+position = Vector2(960, 540)
+texture = ExtResource("14_g7lfk")
+
+[node name="Altavoz" type="Node2D" parent="Sprites" node_paths=PackedStringArray("enabled_speaker", "disabled_speaker")]
+script = ExtResource("16_53e0o")
+sound_sources = Array[AudioStream]([ExtResource("17_uxtxy"), ExtResource("18_2e634"), ExtResource("19_jjs05"), ExtResource("20_yv348")])
+enabled_speaker = NodePath("AltavozEncendido")
+disabled_speaker = NodePath("AltavozApagado")
+
+[node name="AltavozEncendido" type="Sprite2D" parent="Sprites/Altavoz"]
+position = Vector2(960, 540)
+texture = ExtResource("15_ymy1l")
+
+[node name="AltavozApagado" type="Sprite2D" parent="Sprites/Altavoz"]
+position = Vector2(960, 540)
+texture = ExtResource("16_sgsed")
+
+[node name="Timer" type="Timer" parent="Sprites/Altavoz"]
+
+[node name="AudioPlayer" type="AudioStreamPlayer" parent="Sprites/Altavoz"]
+
+[node name="TextTyping" parent="." node_paths=PackedStringArray("imageField") instance=ExtResource("3_enu1t")]
+offset_right = 1920.0
+offset_bottom = 1080.0
+imageField = NodePath("../Sprites/Retrato")
+characterPool = Array[Texture2D]([ExtResource("28_ax6da"), ExtResource("29_a1guj"), ExtResource("5_8rmq8")])
+
+[node name="BurbujaBlur" type="Sprite2D" parent="TextTyping"]
+modulate = Color(1, 1, 1, 0)
+position = Vector2(962, 708)
+texture = ExtResource("36_7dbgh")
+
+[node name="Camera2D" type="Camera2D" parent="."]
+offset = Vector2(960, 540)
+ignore_rotation = false
+position_smoothing_enabled = true
+position_smoothing_speed = 50.0
+rotation_smoothing_enabled = true
+script = ExtResource("3_ogixi")
+randomStrength = 15.0
+
+[node name="ArduinoShake" type="Node" parent="." node_paths=PackedStringArray("colorRect")]
+script = ExtResource("31_kyreg")
+pulseInterval = 0.05
+colorRect = NodePath("../CanvasLayer/Flash")
+
+[node name="Spawner" type="Node2D" parent="." node_paths=PackedStringArray("positions")]
+script = ExtResource("36_0c4t4")
+positions = [NodePath("Pos"), NodePath("Pos2"), NodePath("Pos3"), NodePath("Pos4"), NodePath("Pos5"), NodePath("Pos6"), NodePath("Pos7"), NodePath("Pos8"), NodePath("Pos9"), NodePath("Pos10"), NodePath("Pos11"), NodePath("Pos12"), NodePath("Pos13")]
+
+[node name="Pos" type="Marker2D" parent="Spawner"]
+position = Vector2(276, 975)
+
+[node name="Pos2" type="Marker2D" parent="Spawner"]
+position = Vector2(466, 705)
+
+[node name="Pos3" type="Marker2D" parent="Spawner"]
+position = Vector2(1517, 584)
+
+[node name="Pos4" type="Marker2D" parent="Spawner"]
+position = Vector2(1441, 819)
+
+[node name="Pos5" type="Marker2D" parent="Spawner"]
+position = Vector2(1844, 524)
+
+[node name="Pos6" type="Marker2D" parent="Spawner"]
+position = Vector2(647, 311)
+
+[node name="Pos7" type="Marker2D" parent="Spawner"]
+position = Vector2(307, 267)
+
+[node name="Pos8" type="Marker2D" parent="Spawner"]
+position = Vector2(1199, 423)
+
+[node name="Pos9" type="Marker2D" parent="Spawner"]
+position = Vector2(1070, 879)
+
+[node name="Pos10" type="Marker2D" parent="Spawner"]
+position = Vector2(591, 932)
+
+[node name="Pos11" type="Marker2D" parent="Spawner"]
+position = Vector2(1831, 972)
+
+[node name="Pos12" type="Marker2D" parent="Spawner"]
+position = Vector2(952, 423)
+
+[node name="Pos13" type="Marker2D" parent="Spawner"]
+position = Vector2(1612, 181)
+
+[node name="CanvasLayer" type="CanvasLayer" parent="."]
+
+[node name="Vignette" type="ColorRect" parent="CanvasLayer"]
+material = SubResource("ShaderMaterial_7nj25")
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("32_qlewj")
+
+[node name="MascaraSombra" type="Sprite2D" parent="CanvasLayer" node_paths=PackedStringArray("bubbleMask")]
+modulate = Color(1, 1, 1, 0)
+position = Vector2(960, 540)
+texture = ExtResource("36_l7cj1")
+script = ExtResource("21_86vaa")
+powerOnCurve = SubResource("Curve_lmmd8")
+shutDownCurve = SubResource("Curve_4x2qo")
+duration = 4.0
+bubbleMask = NodePath("../../TextTyping/BurbujaBlur")
+
+[node name="Flash" type="ColorRect" parent="CanvasLayer"]
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+color = Color(1, 1, 1, 0)
+
+[node name="CRT" parent="CanvasLayer" instance=ExtResource("3_82t0k")]
+
+[node name="Music" type="AudioStreamPlayer" parent="."]
+stream = ExtResource("39_ecyg1")
+volume_db = 15.0
+autoplay = true
+
+[node name="Dinamo" type="AudioStreamPlayer" parent="."]
+stream = ExtResource("40_swbqh")
+volume_db = -80.0
+autoplay = true
+
+[node name="sfx" type="Node" parent="."]
+script = ExtResource("43_4k1hy")
+explosions = Array[AudioStream]([ExtResource("44_r4e8v"), ExtResource("45_ojk1h"), ExtResource("46_nvk6r")])
+alarms = Array[AudioStream]([ExtResource("47_ra8w3"), ExtResource("48_3jpdp")])
+
+[connection signal="event_complete" from="GameManager" to="TextTyping" method="_on_event_complete"]
+[connection signal="event_fail" from="GameManager" to="TextTyping" method="_on_event_fail"]
+[connection signal="left_engine_off" from="GameManager" to="Sprites/Motores" method="_on_left_engine_off"]
+[connection signal="left_engine_on" from="GameManager" to="Sprites/Motores" method="_on_left_engine_on"]
+[connection signal="lights_in" from="GameManager" to="CanvasLayer/MascaraSombra" method="_on_lights_in"]
+[connection signal="lights_out" from="GameManager" to="Sprites/Cara" method="_on_lights_out"]
+[connection signal="lights_out" from="GameManager" to="CanvasLayer/MascaraSombra" method="_on_lights_out"]
+[connection signal="right_engine_off" from="GameManager" to="Sprites/Motores" method="_on_right_engine_off"]
+[connection signal="right_engine_on" from="GameManager" to="Sprites/Motores" method="_on_right_engine_on"]
+[connection signal="timeout" from="Sprites/Altavoz/Timer" to="Sprites/Altavoz" method="_on_timer_timeout"]
diff --git a/scenes/text_typing.tscn b/scenes/text_typing.tscn
new file mode 100644
index 0000000..826c57e
--- /dev/null
+++ b/scenes/text_typing.tscn
@@ -0,0 +1,33 @@
+[gd_scene load_steps=5 format=3 uid="uid://gds4ywca08dr"]
+
+[ext_resource type="Script" path="res://scripts/text_typing/typer.gd" id="1_4ddj7"]
+[ext_resource type="Texture2D" uid="uid://bxs6vawsjx4oc" path="res://sprites/burbuja_conversacion.png" id="2_bbyv7"]
+[ext_resource type="AudioStream" uid="uid://bcmhn2w0xhvog" path="res://audio/ingame/voicy02.wav" id="2_l8odf"]
+[ext_resource type="FontFile" uid="uid://dpsmqkos4x6b5" path="res://font/DMSerifDisplay-Regular.ttf" id="4_gdw61"]
+
+[node name="TextTyping" type="Control"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_4ddj7")
+sound = ExtResource("2_l8odf")
+
+[node name="BurbujaConversacion" type="Sprite2D" parent="."]
+position = Vector2(960, 706)
+texture = ExtResource("2_bbyv7")
+
+[node name="RichTextLabel" type="RichTextLabel" parent="."]
+layout_mode = 0
+offset_left = 482.0
+offset_top = 638.0
+offset_right = 1434.0
+offset_bottom = 768.0
+theme_override_colors/default_color = Color(0, 0, 0, 1)
+theme_override_fonts/normal_font = ExtResource("4_gdw61")
+theme_override_font_sizes/normal_font_size = 40
+text = "Holaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+scroll_active = false
+visible_characters_behavior = 1
diff --git a/scenes/titile.tscn b/scenes/titile.tscn
new file mode 100644
index 0000000..9040ba3
--- /dev/null
+++ b/scenes/titile.tscn
@@ -0,0 +1,142 @@
+[gd_scene load_steps=23 format=3 uid="uid://rk208opb7h0v"]
+
+[ext_resource type="Texture2D" uid="uid://bfuksp220ejmv" path="res://sprites/background.png" id="1_6hpwd"]
+[ext_resource type="Script" path="res://scripts/title.gd" id="1_wwia3"]
+[ext_resource type="Texture2D" uid="uid://b02f0labhmgac" path="res://sprites/fx/estrellita_cutre.png" id="2_p3bku"]
+[ext_resource type="Texture2D" uid="uid://hwdnd10qvxn4" path="res://sprites/fondo general.png" id="3_fejje"]
+[ext_resource type="Texture2D" uid="uid://r1vlkamrdvut" path="res://sprites/ondas.png" id="4_2ux8k"]
+[ext_resource type="Texture2D" uid="uid://cd7ebcxsui4c3" path="res://sprites/ondas1.png" id="5_sou7u"]
+[ext_resource type="Texture2D" uid="uid://d35eui04v3k80" path="res://sprites/ondas2.png" id="6_7re5q"]
+[ext_resource type="Texture2D" uid="uid://gh06fhvhmn35" path="res://sprites/retrato.png" id="7_qgp2e"]
+[ext_resource type="Texture2D" uid="uid://4abm8qv3y12q" path="res://sprites/motor izquierdo.png" id="9_kkpmb"]
+[ext_resource type="Texture2D" uid="uid://bmwvo4wau13e8" path="res://sprites/motor derecho.png" id="10_xbh3r"]
+[ext_resource type="Texture2D" uid="uid://c3s7ahkssti82" path="res://sprites/luz 4.png" id="12_uwk8x"]
+[ext_resource type="Texture2D" uid="uid://3jt08tccjv7p" path="res://sprites/luz 3.png" id="13_dcmtd"]
+[ext_resource type="Texture2D" uid="uid://d33s6pef40flk" path="res://sprites/luz 2.png" id="14_2jdao"]
+[ext_resource type="Texture2D" uid="uid://bn160j1ao7da5" path="res://sprites/luz 1.png" id="15_5mu8h"]
+[ext_resource type="Texture2D" uid="uid://def0yc5mp8ocq" path="res://sprites/Logo_Astromovida.png" id="18_rkg3h"]
+[ext_resource type="Texture2D" uid="uid://c5p8vhabiwx3d" path="res://sprites/cara feliz.png" id="19_3bawn"]
+[ext_resource type="Texture2D" uid="uid://l7fftjlr2sqo" path="res://sprites/Aporrea_algo_para_empezar.png" id="19_41ppq"]
+[ext_resource type="Texture2D" uid="uid://chem1yo0ossu1" path="res://sprites/altavoz apagado.png" id="26_57pr4"]
+[ext_resource type="PackedScene" uid="uid://fu50vlhoj4tc" path="res://scenes/crt.tscn" id="29_2setv"]
+
+[sub_resource type="Curve" id="Curve_pxncd"]
+_data = [Vector2(0, 0.0395778), 0.0, 0.0, 0, 0, Vector2(1, 0.751319), 0.0, 0.0, 0, 0]
+point_count = 2
+
+[sub_resource type="Gradient" id="Gradient_sww5j"]
+interpolation_mode = 2
+offsets = PackedFloat32Array(0, 0.224638)
+colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 1)
+
+[sub_resource type="SpriteFrames" id="SpriteFrames_m4rwq"]
+animations = [{
+"frames": [{
+"duration": 1.0,
+"texture": ExtResource("4_2ux8k")
+}, {
+"duration": 1.0,
+"texture": ExtResource("5_sou7u")
+}, {
+"duration": 1.0,
+"texture": ExtResource("6_7re5q")
+}],
+"loop": true,
+"name": &"default",
+"speed": 10.0
+}]
+
+[node name="Title" type="Node2D"]
+script = ExtResource("1_wwia3")
+
+[node name="Sprites" type="Node2D" parent="."]
+
+[node name="Space" type="Sprite2D" parent="Sprites"]
+position = Vector2(960, 540)
+texture = ExtResource("1_6hpwd")
+
+[node name="CPUParticles2D" type="CPUParticles2D" parent="Sprites"]
+position = Vector2(960, 540)
+amount = 200
+lifetime = 20.0
+preprocess = 100.0
+texture = ExtResource("2_p3bku")
+spread = 180.0
+gravity = Vector2(0, 0)
+initial_velocity_min = 25.0
+initial_velocity_max = 50.0
+angular_velocity_max = 180.0
+linear_accel_min = 5.0
+linear_accel_max = 5.0
+angle_min = -180.0
+angle_max = 180.0
+scale_amount_min = 0.25
+scale_amount_max = 0.5
+scale_amount_curve = SubResource("Curve_pxncd")
+color_ramp = SubResource("Gradient_sww5j")
+
+[node name="Background" type="Sprite2D" parent="Sprites"]
+position = Vector2(960, 540)
+texture = ExtResource("3_fejje")
+
+[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="Sprites"]
+sprite_frames = SubResource("SpriteFrames_m4rwq")
+autoplay = "default"
+frame_progress = 0.604089
+offset = Vector2(960, 540)
+
+[node name="Retrato" type="Sprite2D" parent="Sprites"]
+position = Vector2(960, 540)
+texture = ExtResource("7_qgp2e")
+
+[node name="Motores" type="Node2D" parent="Sprites"]
+
+[node name="MotorIzquierdo" type="Sprite2D" parent="Sprites/Motores"]
+position = Vector2(960, 540)
+texture = ExtResource("9_kkpmb")
+
+[node name="MotorDerecho" type="Sprite2D" parent="Sprites/Motores"]
+position = Vector2(960, 540)
+texture = ExtResource("10_xbh3r")
+
+[node name="Luces" type="Node2D" parent="Sprites"]
+
+[node name="Luz4" type="Sprite2D" parent="Sprites/Luces"]
+position = Vector2(960, 540)
+texture = ExtResource("12_uwk8x")
+
+[node name="Luz3" type="Sprite2D" parent="Sprites/Luces"]
+position = Vector2(960, 540)
+texture = ExtResource("13_dcmtd")
+
+[node name="Luz2" type="Sprite2D" parent="Sprites/Luces"]
+position = Vector2(960, 540)
+texture = ExtResource("14_2jdao")
+
+[node name="Luz1" type="Sprite2D" parent="Sprites/Luces"]
+position = Vector2(960, 540)
+texture = ExtResource("15_5mu8h")
+
+[node name="Cara" type="Node2D" parent="Sprites"]
+
+[node name="CaraFeliz" type="Sprite2D" parent="Sprites/Cara"]
+position = Vector2(960, 540)
+texture = ExtResource("19_3bawn")
+
+[node name="Altavoz" type="Node2D" parent="Sprites"]
+
+[node name="AltavozApagado" type="Sprite2D" parent="Sprites/Altavoz"]
+position = Vector2(960, 540)
+texture = ExtResource("26_57pr4")
+
+[node name="CanvasLayer" type="CanvasLayer" parent="."]
+
+[node name="CRT" parent="CanvasLayer" instance=ExtResource("29_2setv")]
+
+[node name="LogoAstromovida" type="Sprite2D" parent="."]
+position = Vector2(962, 416)
+texture = ExtResource("18_rkg3h")
+
+[node name="AporreaAlgoParaEmpezar" type="Sprite2D" parent="."]
+position = Vector2(960, 644)
+texture = ExtResource("19_41ppq")
diff --git a/scripts/action_data.gd b/scripts/action_data.gd
new file mode 100644
index 0000000..a63d5a6
--- /dev/null
+++ b/scripts/action_data.gd
@@ -0,0 +1,6 @@
+class_name ActionData
+extends Resource
+
+@export var text: String
+@export var actions: PackedStringArray
+@export var duration: float
diff --git a/scripts/arduino_control/Vibration.cs b/scripts/arduino_control/Vibration.cs
new file mode 100644
index 0000000..76040ec
--- /dev/null
+++ b/scripts/arduino_control/Vibration.cs
@@ -0,0 +1,39 @@
+using System;
+using System.IO.Ports;
+using Godot;
+
+namespace MalagaJam18;
+
+[GlobalClass]
+public partial class Vibration : Node {
+ private static SerialPort _serialPort;
+ private static bool _initialized;
+
+ public static void Init(string port) {
+ GD.Print(port);
+ try {
+ _serialPort = new SerialPort();
+ _serialPort.PortName = port;
+ _serialPort.BaudRate = 9600;
+ _serialPort.Open();
+ _initialized = true;
+ }
+ catch (Exception e) {
+ GD.PrintErr(e);
+ }
+ }
+
+ public static void SendVibration() {
+ if (!_initialized || !_serialPort.IsOpen)
+ return;
+
+ _serialPort.WriteLine("#LED1ON");
+ }
+
+ public static void UnSendVibration() {
+ if (!_initialized || !_serialPort.IsOpen)
+ return;
+
+ _serialPort.WriteLine("#LED1OF");
+ }
+}
diff --git a/scripts/arduino_control/pulse_generator.gd b/scripts/arduino_control/pulse_generator.gd
new file mode 100644
index 0000000..09bd7fd
--- /dev/null
+++ b/scripts/arduino_control/pulse_generator.gd
@@ -0,0 +1,57 @@
+extends Node
+
+var comPort: String = "COM8"
+
+var time: float
+var pulseTime: float
+
+# min ideal setup interval 0.05 and duration 0.03
+@export_range(0, 0.5) var pulseInterval: float = 0.2
+@export_range(0, 0.1) var pulseDuration: float = 0.03
+
+@export var colorRect: ColorRect
+
+var pendingPulses: float = 0
+
+func _ready():
+ var arguments = {}
+ for argument in OS.get_cmdline_args():
+ if argument.find("=") > -1:
+ var key_value = argument.split("=")
+ arguments[key_value[0].lstrip("--")] = key_value[1]
+ else:
+ # Options without an argument will be present in the dictionary,
+ # with the value set to an empty string.
+ arguments[argument.lstrip("--")] = ""
+
+ var hasComPort = arguments.has("port")
+ if (hasComPort):
+ comPort = arguments["port"]
+
+ Vibration.Init(comPort)
+
+
+func _process(delta):
+ if (time > 0):
+ time -= delta
+ if (time <= 0):
+ Vibration.UnSendVibration()
+
+ if (pendingPulses > 0 and pulseTime > 0):
+ pulseTime -= delta
+ if (pulseTime <= 0):
+ _sendPulse(pendingPulses - 1)
+
+
+func shakeController(ammount: int):
+ _sendPulse(ammount)
+ var tween = get_tree().create_tween()
+ tween.tween_property(colorRect, "color", Color(Color.WHITE, 1), 0.05)
+ tween.tween_property(colorRect, "color", Color(Color.WHITE, 0), 0.05)
+
+
+func _sendPulse(ammount: int):
+ pendingPulses = ammount - 1
+ time = pulseDuration
+ pulseTime = pulseInterval
+ Vibration.SendVibration()
diff --git a/scripts/crt_controller.gd b/scripts/crt_controller.gd
new file mode 100644
index 0000000..578652e
--- /dev/null
+++ b/scripts/crt_controller.gd
@@ -0,0 +1,34 @@
+extends Node
+class_name CRT
+
+@export var normal_filter: Control
+@export var distortion_filter: Control
+
+var clicksNeeded: int
+var distortionEnabled: bool
+
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ normal_filter.visible = true
+ distortion_filter.visible = false
+
+
+func _process(_delta):
+ if distortionEnabled and Input.is_action_just_pressed("BTN_6"):
+ clicksNeeded -= 1
+ if clicksNeeded <= 0:
+ disable_distortion()
+
+
+func enable_distortion(clicks: int):
+ normal_filter.visible = false
+ distortion_filter.visible = true
+ clicksNeeded = clicks
+ distortionEnabled = true
+
+
+func disable_distortion():
+ normal_filter.visible = true
+ distortion_filter.visible = false
+ distortionEnabled = false
diff --git a/scripts/effects/engines.gd b/scripts/effects/engines.gd
new file mode 100644
index 0000000..0c29978
--- /dev/null
+++ b/scripts/effects/engines.gd
@@ -0,0 +1,51 @@
+extends Node
+
+@onready var leftEngine: Sprite2D = $MotorIzquierdo
+@onready var rightEngine: Sprite2D = $MotorDerecho
+
+var leftPowerLevel: float
+var currentLeftPowerLevel: float
+var rightPowerLevel: float
+var currentRightPowerLevel: float
+
+@export var leftPowerSprites: Array[Texture2D]
+@export var rightPowerSprites: Array[Texture2D]
+
+@export_range(0, 2) var transitionDelta: float
+
+
+func _transition(curr: float, goal: float, delta: float) -> float:
+ return curr + (goal - curr) * transitionDelta * delta
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ currentLeftPowerLevel = _transition(currentLeftPowerLevel, leftPowerLevel, delta)
+ currentRightPowerLevel = _transition(currentRightPowerLevel, rightPowerLevel, delta)
+
+ if not leftPowerSprites.is_empty():
+ var index = roundf(currentLeftPowerLevel * leftPowerSprites.size())
+ index = clamp(index, 0, leftPowerSprites.size() - 1)
+ leftEngine.texture = leftPowerSprites[index]
+ if not rightPowerSprites.is_empty():
+ var index = roundf(currentRightPowerLevel * rightPowerSprites.size())
+ index = clamp(index, 0, rightPowerSprites.size() - 1)
+ rightEngine.texture = rightPowerSprites[index]
+
+
+func _change_left_power_level(level: float):
+ leftPowerLevel = level
+
+
+func _change_right_power_level(level: float):
+ rightPowerLevel = level
+
+
+func _on_left_engine_off():
+ _change_left_power_level(0)
+func _on_left_engine_on():
+ _change_left_power_level(1)
+func _on_right_engine_off():
+ _change_right_power_level(0)
+func _on_right_engine_on():
+ _change_right_power_level(1)
diff --git a/scripts/effects/light_face.gd b/scripts/effects/light_face.gd
new file mode 100644
index 0000000..b222e91
--- /dev/null
+++ b/scripts/effects/light_face.gd
@@ -0,0 +1,41 @@
+extends Node2D
+
+@onready var on: Sprite2D = $CaraFeliz
+@onready var powerless: Sprite2D = $CaraTieso
+@onready var off: Sprite2D = $CaraPanico
+
+
+@export var game_manager: GameManager
+var lights_out: bool
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ if abs(game_manager.spinner_speed) > 0:
+ _on_face()
+ lights_out = false
+ elif not lights_out:
+ _powerless_face()
+
+
+func _on_lights_out():
+ lights_out = true
+ _off_face()
+
+
+func _on_face():
+ on.visible = true
+ powerless.visible = false
+ off.visible = false
+
+
+func _off_face():
+ on.visible = false
+ powerless.visible = false
+ off.visible = true
+
+
+func _powerless_face():
+ on.visible = false
+ powerless.visible = true
+ off.visible = false
diff --git a/scripts/effects/lights.gd b/scripts/effects/lights.gd
new file mode 100644
index 0000000..aa5191b
--- /dev/null
+++ b/scripts/effects/lights.gd
@@ -0,0 +1,21 @@
+extends Node2D
+
+@export var light1: Sprite2D
+@export var light2: Sprite2D
+@export var light3: Sprite2D
+@export var light4: Sprite2D
+
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ light1.visible = false
+ light2.visible = false
+ light3.visible = false
+ light4.visible = false
+
+
+func _process(_delta):
+ light1.visible = Input.is_action_pressed("BTN_1")
+ light2.visible = Input.is_action_pressed("BTN_2")
+ light3.visible = Input.is_action_pressed("BTN_3")
+ light4.visible = Input.is_action_pressed("BTN_4")
diff --git a/scripts/effects/shadow.gd b/scripts/effects/shadow.gd
new file mode 100644
index 0000000..19ac422
--- /dev/null
+++ b/scripts/effects/shadow.gd
@@ -0,0 +1,44 @@
+extends Sprite2D
+
+@export var powerOnCurve: Curve
+@export var shutDownCurve: Curve
+var time: float
+@export var duration: float
+
+@export var bubbleMask: Sprite2D
+
+var curve: Curve
+var animating: bool = false
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ if (not animating):
+ return
+
+ time += delta
+ var alpha = curve.sample(clamp(time / duration, 0, 1))
+ modulate = Color(Color.WHITE, alpha)
+ bubbleMask.modulate = Color(Color.WHITE, alpha)
+ if (time >= duration):
+ animating = false
+
+
+func shut_down():
+ time = 0
+ curve = shutDownCurve
+ animating = true
+
+
+func power_on():
+ time = 0
+ curve = powerOnCurve
+ animating = true
+
+
+func _on_lights_out():
+ shut_down()
+
+
+func _on_lights_in():
+ power_on()
diff --git a/scripts/effects/shake.gd b/scripts/effects/shake.gd
new file mode 100644
index 0000000..8c3a59e
--- /dev/null
+++ b/scripts/effects/shake.gd
@@ -0,0 +1,26 @@
+extends Camera2D
+
+@export var randomStrength: float = 30.0
+@export var randomRotationStrength: float = 5.0
+@export var shakeFade: float = 5.0
+
+@export var intensity: float = 0.0
+
+var rng = RandomNumberGenerator.new()
+var shake_strength: float = 0.0
+
+var initialPos: Vector2
+
+
+func _ready():
+ initialPos = offset
+
+func _process(delta):
+ offset = initialPos + randomOffset() * intensity
+ rotation = randomRotation() * intensity
+
+func randomOffset() -> Vector2:
+ return Vector2(rng.randf_range(-randomStrength, randomStrength), rng.randf_range(-randomStrength, randomStrength))
+
+func randomRotation() -> float:
+ return deg_to_rad(randf_range(-randomRotationStrength, randomRotationStrength))
diff --git a/scripts/effects/smoke.gd b/scripts/effects/smoke.gd
new file mode 100644
index 0000000..c74c5fd
--- /dev/null
+++ b/scripts/effects/smoke.gd
@@ -0,0 +1,14 @@
+extends Node2D
+
+@export var positions: Array[Node2D]
+
+
+func spawn():
+ var pos: Node2D = positions.pick_random()
+ if not pos:
+ return
+ positions.erase(pos)
+ var scene = load("res://scenes/smoke_particles.tscn")
+ var scene_instance = scene.instantiate()
+ add_child(scene_instance)
+ scene_instance.global_position = pos.global_position
diff --git a/scripts/effects/speaker.gd b/scripts/effects/speaker.gd
new file mode 100644
index 0000000..2bbb721
--- /dev/null
+++ b/scripts/effects/speaker.gd
@@ -0,0 +1,39 @@
+extends Node2D
+
+@export var sound_sources: Array[AudioStream]
+
+@export var enabled_speaker: Sprite2D
+@export var disabled_speaker: Sprite2D
+
+
+func _ready():
+ _disable_speaker()
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ if (Input.is_action_just_pressed("BTN_5")):
+ _play_random_sound()
+
+
+func _play_random_sound():
+ var stream = sound_sources.pick_random()
+ var length = stream.get_length()
+ SoundManager.play_sound(stream)
+
+ _enable_speaker()
+ if ($Timer.time_left < length):
+ $Timer.start(length)
+
+func _enable_speaker():
+ enabled_speaker.visible = true
+ disabled_speaker.visible = false
+
+
+func _disable_speaker():
+ enabled_speaker.visible = false
+ disabled_speaker.visible = true
+
+
+func _on_timer_timeout():
+ _disable_speaker()
diff --git a/scripts/effects/vignette.gd b/scripts/effects/vignette.gd
new file mode 100644
index 0000000..e71c0a0
--- /dev/null
+++ b/scripts/effects/vignette.gd
@@ -0,0 +1,15 @@
+extends ColorRect
+
+@export var intensity: float
+
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ var tween = get_tree().create_tween()
+ tween.tween_method(_set_vignette, 0.0, 1.5, 0.5).set_trans(Tween.TRANS_LINEAR)
+ tween.tween_method(_set_vignette, 1.5, 0.0, 0.5).set_trans(Tween.TRANS_LINEAR).set_delay(0.5)
+ tween.set_loops()
+
+func _set_vignette(value: float):
+ var mat: ShaderMaterial = material
+ mat.set_shader_parameter("vignette_strength", value * intensity)
diff --git a/scripts/end_card.gd b/scripts/end_card.gd
new file mode 100644
index 0000000..9f025e9
--- /dev/null
+++ b/scripts/end_card.gd
@@ -0,0 +1,16 @@
+extends Control
+
+
+func _ready():
+ Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ if Input.is_action_just_pressed("BTN_1") or \
+ Input.is_action_just_pressed("BTN_2") or \
+ Input.is_action_just_pressed("BTN_3") or \
+ Input.is_action_just_pressed("BTN_4") or \
+ Input.is_action_just_pressed("BTN_5") or \
+ Input.is_action_just_pressed("BTN_6"):
+ get_tree().change_scene_to_file("res://scenes/titile.tscn")
diff --git a/scripts/event.gd b/scripts/event.gd
new file mode 100644
index 0000000..0864ff7
--- /dev/null
+++ b/scripts/event.gd
@@ -0,0 +1,16 @@
+extends Node
+
+signal event_completed
+signal event_failed
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ pass # Replace with function body.
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(_delta):
+ if (Input.is_action_just_pressed("ui_accept")):
+ event_completed.emit()
+ if (Input.is_action_just_pressed("ui_cancel")):
+ event_failed.emit()
diff --git a/scripts/events/dialog_event_01.gd b/scripts/events/dialog_event_01.gd
new file mode 100644
index 0000000..11fc7fa
--- /dev/null
+++ b/scripts/events/dialog_event_01.gd
@@ -0,0 +1,4 @@
+extends Node
+
+var dialogue = "hewwo... hewwo?" # Text to display.
+var time = 8 # How long it should be on screen.
diff --git a/scripts/events/event_01.gd b/scripts/events/event_01.gd
new file mode 100644
index 0000000..e67f315
--- /dev/null
+++ b/scripts/events/event_01.gd
@@ -0,0 +1,16 @@
+extends Node
+
+# Inputs
+var hold = []
+var press = ["BTN_1"]
+var shake = [] # Needs to be all 4 axis of a stick.
+var shake_b = [] # Fill if a second stick is necessary, uses second pos in shake_ok array.
+
+# Goals
+var hold_ok = [] # For hold and press true is considered a success.
+var press_ok = [false]
+var shake_ok = [] # For shake any value below zero is considered a success.
+
+#Other
+var dialogue = "Pulsa el botón de panico. Y mantén la dinamo girando o te quedaras sin energia."
+var time = 10
diff --git a/scripts/events/event_02.gd b/scripts/events/event_02.gd
new file mode 100644
index 0000000..caf04a3
--- /dev/null
+++ b/scripts/events/event_02.gd
@@ -0,0 +1,16 @@
+extends Node
+
+# Inputs
+var hold = ["LJ_UP"]
+var press = ["BTN_3"]
+var shake = [] # Needs to be all 4 axis of a stick.
+var shake_b = [] # Fill if a second stick is necessary, uses second pos in shake_ok array.
+
+# Goals
+var hold_ok = [false] # For hold and press true is considered a success.
+var press_ok = [false]
+var shake_ok = [] # For shake any value below zero is considered a success.
+
+#Other
+var dialogue = "Ahora mantén la palanca izquierda subida y pulsa el botón de peligro!"
+var time = 10
diff --git a/scripts/events/event_03.gd b/scripts/events/event_03.gd
new file mode 100644
index 0000000..5b3af16
--- /dev/null
+++ b/scripts/events/event_03.gd
@@ -0,0 +1,15 @@
+extends Node
+
+var hold = []
+var press = ["BTN_1", "BTN_2", "BTN_3", "BTN_4"]
+var shake = ["LJ_UP", "LJ_DOWN", "LJ_LEFT", "LJ_RIGHT"] # Needs to be all 4 axis of a stick.
+var shake_b = [] # Fill if a second stick is necessary, uses second pos in shake_ok array.
+
+# Goals
+var hold_ok = [] # For hold and press true is considered a success.
+var press_ok = [false, false, false, false]
+var shake_ok = [12] # For shake any value below zero is considered a success.
+
+#Other
+var dialogue = "Pulsa los cuatro botones y menea el motor izquierdo!"
+var time = 12
diff --git a/scripts/events/event_04.gd b/scripts/events/event_04.gd
new file mode 100644
index 0000000..669aa64
--- /dev/null
+++ b/scripts/events/event_04.gd
@@ -0,0 +1,15 @@
+extends Node
+
+var hold = []
+var press = []
+var shake = ["RJ_UP", "RJ_DOWN", "RJ_LEFT", "RJ_RIGHT"] # Needs to be all 4 axis of a stick.
+var shake_b = [] # Fill if a second stick is necessary, uses second pos in shake_ok array.
+
+# Goals
+var hold_ok = [] # For hold and press true is considered a success.
+var press_ok = []
+var shake_ok = [20] # For shake any value below zero is considered a success.
+
+#Other
+var dialogue = "Menea tambien el motor derecho!"
+var time = 10
diff --git a/scripts/events/event_05.gd b/scripts/events/event_05.gd
new file mode 100644
index 0000000..8036ac6
--- /dev/null
+++ b/scripts/events/event_05.gd
@@ -0,0 +1,15 @@
+extends Node
+
+var hold = []
+var press = ["BTN_3"]
+var shake = [] # Needs to be all 4 axis of a stick.
+var shake_b = [] # Fill if a second stick is necessary, uses second pos in shake_ok array.
+
+# Goals
+var hold_ok = [] # For hold and press true is considered a success.
+var press_ok = [false]
+var shake_ok = [] # For shake any value below zero is considered a success.
+
+#Other
+var dialogue = "Vale. Ahora pulsa el boton de crisis... el izquierdo creo. No, perdon, prueba con el derecho."
+var time = 10
diff --git a/scripts/events/event_06.gd b/scripts/events/event_06.gd
new file mode 100644
index 0000000..2cf93de
--- /dev/null
+++ b/scripts/events/event_06.gd
@@ -0,0 +1,16 @@
+extends Node
+
+# Inputs
+var hold = ["LJ_UP", "RJ_UP"]
+var press = ["BTN_2", "BTN_3"]
+var shake = [] # Needs to be all 4 axis of a stick.
+var shake_b = [] # Fill if a second stick is necessary, uses second pos in shake_ok array.
+
+# Goals
+var hold_ok = [false, false] # For hold and press true is considered a success.
+var press_ok = [false, false]
+var shake_ok = [] # For shake any value below zero is considered a success.
+
+#Other
+var dialogue = "Ahora manten las dos palancas hacia arriba y pulsa los botones de crisis!"
+var time = 8
diff --git a/scripts/events/event_07.gd b/scripts/events/event_07.gd
new file mode 100644
index 0000000..d40dfb1
--- /dev/null
+++ b/scripts/events/event_07.gd
@@ -0,0 +1,16 @@
+extends Node
+
+# Inputs
+var hold = ["LJ_LEFT", "RJ_RIGHT"]
+var press = ["BTN_1"]
+var shake = [] # Needs to be all 4 axis of a stick.
+var shake_b = [] # Fill if a second stick is necessary, uses second pos in shake_ok array.
+
+# Goals
+var hold_ok = [false, false] # For hold and press true is considered a success.
+var press_ok = [false]
+var shake_ok = [] # For shake any value below zero is considered a success.
+
+#Other
+var dialogue = "Mueve las palancas a la izquierda y derecha, y pulsa el botón de panico!"
+var time = 10
diff --git a/scripts/events/event_08.gd b/scripts/events/event_08.gd
new file mode 100644
index 0000000..eb72eb3
--- /dev/null
+++ b/scripts/events/event_08.gd
@@ -0,0 +1,16 @@
+extends Node
+
+# Inputs
+var hold = []
+var press = []
+var shake = ["RJ_UP", "RJ_DOWN", "RJ_LEFT", "RJ_RIGHT"] # Needs to be all 4 axis of a stick.
+var shake_b = [] # Fill if a second stick is necessary, uses second pos in shake_ok array.
+
+# Goals
+var hold_ok = [] # For hold and press true is considered a success.
+var press_ok = []
+var shake_ok = [999] # For shake any value below zero is considered a success.
+
+#Other
+var dialogue = "Menea el motor derecho, RAPIDO!"
+var time = 6
diff --git a/scripts/events/event_09.gd b/scripts/events/event_09.gd
new file mode 100644
index 0000000..79fb518
--- /dev/null
+++ b/scripts/events/event_09.gd
@@ -0,0 +1,16 @@
+extends Node
+
+# Inputs
+var hold = ["LJ_UP"]
+var press = ["BTN_1"]
+var shake = ["RJ_UP", "RJ_DOWN", "RJ_LEFT", "RJ_RIGHT"] # Needs to be all 4 axis of a stick.
+var shake_b = [] # Fill if a second stick is necessary, uses second pos in shake_ok array.
+
+# Goals
+var hold_ok = [false, false] # For hold and press true is considered a success.
+var press_ok = [false]
+var shake_ok = [12] # For shake any value below zero is considered a success.
+
+#Other
+var dialogue = "Mantén la palanca izquierda arriba, menea la derecha y pulsa el boton de panico!"
+var time = 10
diff --git a/scripts/events/event_10.gd b/scripts/events/event_10.gd
new file mode 100644
index 0000000..ec3c689
--- /dev/null
+++ b/scripts/events/event_10.gd
@@ -0,0 +1,15 @@
+extends Node
+# Inputs
+var hold = []
+var press = []
+var shake = ["LJ_UP", "LJ_DOWN", "LJ_LEFT", "LJ_RIGHT"] # Needs to be all 4 axis of a stick.
+var shake_b = ["RJ_UP", "RJ_DOWN", "RJ_LEFT", "RJ_RIGHT"] # Fill if a second stick is necessary, uses second pos in shake_ok array.
+
+# Goals
+var hold_ok = [] # For hold and press true is considered a success.
+var press_ok = []
+var shake_ok = [999, 999] # For shake any value below zero is considered a success.
+
+#Other
+var dialogue = "Dale a los dos motores, se nos estan rompiendo!!"
+var time = 8
diff --git a/scripts/events/event_11.gd b/scripts/events/event_11.gd
new file mode 100644
index 0000000..17ce1b7
--- /dev/null
+++ b/scripts/events/event_11.gd
@@ -0,0 +1,15 @@
+extends Node
+# Inputs
+var hold = []
+var press = []
+var shake = ["LJ_UP", "LJ_DOWN", "LJ_LEFT", "LJ_RIGHT"] # Needs to be all 4 axis of a stick.
+var shake_b = ["RJ_UP", "RJ_DOWN", "RJ_LEFT", "RJ_RIGHT"] # Fill if a second stick is necessary, uses second pos in shake_ok array.
+
+# Goals
+var hold_ok = [] # For hold and press true is considered a success.
+var press_ok = []
+var shake_ok = [999, 999] # For shake any value below zero is considered a success.
+
+#Other
+var dialogue = "PULSALO TODO MALDITA SEA, TODO!!"
+var time = 8
diff --git a/scripts/explosion_player.gd b/scripts/explosion_player.gd
new file mode 100644
index 0000000..21c0cc7
--- /dev/null
+++ b/scripts/explosion_player.gd
@@ -0,0 +1,13 @@
+extends Node
+
+@export var explosions: Array[AudioStream]
+@export var alarms: Array[AudioStream]
+
+
+func play_explosion():
+ var sound = explosions.pick_random()
+ SoundManager.play_sound(sound)
+
+func play_alarm():
+ var sound = alarms.pick_random()
+ SoundManager.play_sound(sound)
diff --git a/scripts/game_flow.gd b/scripts/game_flow.gd
new file mode 100644
index 0000000..db703b9
--- /dev/null
+++ b/scripts/game_flow.gd
@@ -0,0 +1,72 @@
+extends Node
+
+@onready var manager = $".."
+@onready var vfx = $"../VFX"
+@onready var end_card = load("res://scenes/end_card.tscn")
+@export var crt: CRT
+
+func mishap1():
+ var inst = manager.res_ev01.instantiate()
+ manager.insert_event(inst)
+ print("mishap 1 triggered")
+
+func mishap2():
+ var inst = manager.res_ev02.instantiate()
+ manager.insert_event(inst)
+ print("mishap 2 triggered")
+
+func mishap3():
+ var inst = manager.res_ev03.instantiate()
+ manager.insert_event(inst)
+ print("mishap 3 triggered")
+
+func mishap4():
+ var inst = manager.res_ev04.instantiate()
+ manager.insert_event(inst)
+ print("mishap 4 triggered")
+
+func mishap5():
+ var inst = manager.res_ev05.instantiate()
+ manager.insert_event(inst)
+ print("mishap 5 triggered")
+
+func mishap6():
+ var inst = manager.res_ev06.instantiate()
+ manager.insert_event(inst)
+ print("mishap 6 triggered")
+
+func mishap7():
+ var inst = manager.res_ev07.instantiate()
+ manager.insert_event(inst)
+ print("mishap 7 triggered")
+
+func mishap8():
+ var inst = manager.res_ev08.instantiate()
+ manager.insert_event(inst)
+ print("mishap 8 triggered")
+
+func mishap9():
+ var inst = manager.res_ev09.instantiate()
+ manager.insert_event(inst)
+ print("mishap 9 triggered")
+
+func mishap10():
+ var inst = manager.res_ev10.instantiate()
+ manager.insert_event(inst)
+ print("mishap 10 triggered")
+
+func mishap11():
+ var inst = manager.res_ev11.instantiate()
+ manager.insert_event(inst)
+ print("mishap 11 triggered")
+
+func play_5s_shake():
+ if manager.event_running:
+ vfx.play("shake 5s")
+
+func distort(clicks: int):
+ crt.enable_distortion(clicks)
+
+func end_game():
+ print("Called end game.")
+ get_tree().change_scene_to_packed(end_card)
diff --git a/scripts/game_manager.gd b/scripts/game_manager.gd
new file mode 100644
index 0000000..93291cc
--- /dev/null
+++ b/scripts/game_manager.gd
@@ -0,0 +1,188 @@
+extends Node
+class_name GameManager
+
+@onready var grace_period: Timer = $GracePeriod
+@onready var event_timer: Timer = $EventTimer
+@onready var vfx = $VFX
+@onready var res_ev01 = load("res://events/event_01.tscn")
+@onready var res_ev02 = load("res://events/event_02.tscn")
+@onready var res_ev03 = load("res://events/event_03.tscn")
+@onready var res_ev04 = load("res://events/event_04.tscn")
+@onready var res_ev05 = load("res://events/event_05.tscn")
+@onready var res_ev06 = load("res://events/event_06.tscn")
+@onready var res_ev07 = load("res://events/event_07.tscn")
+@onready var res_ev08 = load("res://events/event_08.tscn")
+@onready var res_ev09 = load("res://events/event_09.tscn")
+@onready var res_ev10 = load("res://events/event_10.tscn")
+@onready var res_ev11 = load("res://events/event_11.tscn")
+@export var spinner_deadzone: float = 15 # Bad placeholder value, PLEASE TEST & FINETUNE!
+@export var text_typer: TextTyper
+
+@export var dinamo: AudioStreamPlayer
+
+var current_event: Node = null
+var event_running: bool = false
+var spinner_mechanic: bool = true
+var dead_spinner: bool = false
+var no_energy: bool = false
+var spinner_speed: float = 0
+var time_since_last_motion: float = 0
+
+signal event_complete
+signal event_fail
+signal lights_out
+signal lights_in
+signal left_engine_on
+signal left_engine_off
+signal right_engine_on
+signal right_engine_off
+
+func _ready():
+ Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
+
+func _process(delta):
+ time_since_last_motion += delta
+ if (abs(spinner_speed) > 0 and time_since_last_motion >= .2):
+ spinner_speed = 0
+ #print(spinner_speed)
+ if event_running:
+ event_process()
+ verify_event()
+ if (abs(spinner_speed) < spinner_deadzone and !dead_spinner):
+ grace_period.start()
+ if dinamo:
+ dinamo.volume_db = -80
+ dead_spinner = true
+ if (abs(spinner_speed) >= spinner_deadzone and dead_spinner):
+ grace_period.stop()
+ dead_spinner = false
+ if dinamo:
+ dinamo.volume_db = -10
+ if (no_energy):
+ lights_in.emit()
+ no_energy = false
+ feedbacks()
+ # DEBUG STUFF - REMOVE FOR RELEASE
+ if Input.is_action_just_pressed("DEBUG_Lock_Cursor"):
+ Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
+ if Input.is_action_just_pressed("DEBUG_Unlock_Cursor"):
+ Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
+
+func _input(event):
+ if event is InputEventMouseMotion:
+ spinner_speed = event.get_relative().x
+ #print(spinner_speed)
+ time_since_last_motion = 0
+
+func feedbacks():
+ if Input.is_action_just_pressed("LJ_UP") or Input.is_action_just_pressed("LJ_DOWN") \
+ or Input.is_action_just_pressed("LJ_LEFT") or Input.is_action_just_pressed("LJ_RIGHT"):
+ left_engine_on.emit()
+ print("left engine on")
+ if Input.is_action_just_pressed("RJ_UP") or Input.is_action_just_pressed("RJ_DOWN") \
+ or Input.is_action_just_pressed("RJ_LEFT") or Input.is_action_just_pressed("RJ_RIGHT"):
+ right_engine_on.emit()
+ print("right engine on")
+ if Input.is_action_just_released("LJ_UP") or Input.is_action_just_released("LJ_DOWN") \
+ or Input.is_action_just_released("LJ_LEFT") or Input.is_action_just_released("LJ_RIGHT"):
+ left_engine_off.emit()
+ print("left engine off")
+ if Input.is_action_just_released("RJ_UP") or Input.is_action_just_released("RJ_DOWN") \
+ or Input.is_action_just_released("RJ_LEFT") or Input.is_action_just_released("RJ_RIGHT"):
+ right_engine_off.emit()
+ print("right engine off")
+
+# Change the current event to "n_event".
+func insert_event(n_event: Node):
+ current_event = n_event
+ event_timer.wait_time = current_event.time
+ event_running = true
+ event_timer.start()
+ print("time: " + str(event_timer.time_left))
+ print(n_event.hold)
+ print(n_event.press)
+ print(n_event.shake)
+
+ if text_typer:
+ text_typer.animate_text_in(n_event.dialogue)
+
+func check_if_held():
+ if current_event.hold.is_empty():
+ return true
+ var hold_ok_target = current_event.hold_ok.size()
+ var hold_ok_current = 0
+ for check in current_event.hold_ok:
+ if check == true:
+ hold_ok_current += 1
+ if hold_ok_current == hold_ok_target:
+ return true
+ else:
+ return false
+
+func verify_event():
+ # Goals and progress.
+ var press_ok_target = current_event.press_ok.size()
+ var hold_ok_target = current_event.hold_ok.size()
+ var shake_ok_target = current_event.shake_ok.size()
+ var press_ok_current = 0
+ var hold_ok_current = 0
+ var shake_ok_current = 0
+ # Verify arrays only if they're used.
+ if !current_event.press_ok.is_empty():
+ for check in current_event.press_ok:
+ if check == true:
+ press_ok_current += 1
+ if !current_event.hold_ok.is_empty():
+ for check in current_event.hold_ok:
+ if check == true:
+ hold_ok_current += 1
+ if !current_event.shake_ok.is_empty():
+ for check in current_event.shake_ok:
+ if check <= 0:
+ shake_ok_current += 1
+
+ if press_ok_current == press_ok_target and hold_ok_current == hold_ok_target\
+ and shake_ok_current == shake_ok_target:
+ print("Success!")
+ event_complete.emit()
+ event_timer.stop()
+ vfx.stop()
+ vfx.play("RESET")
+ event_running = false
+
+func event_process():
+ if !current_event.press.is_empty() and check_if_held():
+ var i = 0
+ for action in current_event.press:
+ if Input.is_action_just_pressed(action):
+ print(action + " was pressed")
+ current_event.press_ok[i] = true
+ i += 1
+ if !current_event.hold.is_empty():
+ var i = 0
+ for action in current_event.hold:
+ if Input.is_action_pressed(action):
+ current_event.hold_ok[i] = true
+ else:
+ current_event.hold_ok[i] = false
+ i += 1
+ if !current_event.shake.is_empty() and check_if_held():
+ for action in current_event.shake:
+ if Input.is_action_just_pressed(action):
+ current_event.shake_ok[0] -= 1
+ if !current_event.shake_b.is_empty() and check_if_held():
+ for action in current_event.shake_b:
+ if Input.is_action_just_pressed(action):
+ current_event.shake_ok[1] -= 1
+
+func _on_grace_period_timeout():
+ print("Lights out!")
+ lights_out.emit()
+ no_energy = true
+
+func _on_event_timer_timeout():
+ print("Failure!")
+ event_fail.emit()
+ vfx.stop()
+ vfx.play("RESET")
+ event_running = false
diff --git a/scripts/input_tester.gd b/scripts/input_tester.gd
new file mode 100644
index 0000000..4e93f34
--- /dev/null
+++ b/scripts/input_tester.gd
@@ -0,0 +1,24 @@
+extends TextureRect
+
+@onready var manager = $"../GameManager"
+@export var press: bool = false
+@export var hold: bool = false
+@export var shake: bool = false
+@export var checkpos: int = 0
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ pass # Replace with function body.
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ if press:
+ if manager.current_event.press_ok[checkpos] == true:
+ visible = false
+ if hold:
+ if manager.current_event.hold_ok[checkpos] == true:
+ visible = false
+ else:
+ visible = true
+ if shake:
+ if manager.current_event.shake_ok[checkpos] <= 0:
+ visible = false
diff --git a/scripts/spinner_tester.gd b/scripts/spinner_tester.gd
new file mode 100644
index 0000000..825ec4e
--- /dev/null
+++ b/scripts/spinner_tester.gd
@@ -0,0 +1,12 @@
+extends TextureRect
+
+@onready var manager = $"../GameManager"
+
+func _ready():
+ pass # Replace with function body.
+
+func _process(delta):
+ if manager.dead_spinner:
+ visible = true
+ else:
+ visible = false
diff --git a/scripts/text_typing/typer.gd b/scripts/text_typing/typer.gd
new file mode 100644
index 0000000..e69b10f
--- /dev/null
+++ b/scripts/text_typing/typer.gd
@@ -0,0 +1,68 @@
+extends Control
+class_name TextTyper
+
+signal text_typing_started
+signal text_typing_finished
+
+@export var sound: AudioStream
+
+@export_range(0, 0.25) var speed: float = 0.02
+var currentAnimTime: float
+var animating: bool
+
+@export var imageField: Sprite2D
+@export var characterPool: Array[Texture2D]
+
+@onready var text = $RichTextLabel
+
+
+func _ready():
+ text.set_text("")
+ _hide_box()
+
+
+func animate_text_in(text: String):
+ text_typing_started.emit()
+ self.text.visible_characters = 0
+ self.text.set_text(text)
+
+ _show_box()
+
+ currentAnimTime = 0
+ animating = true
+
+ imageField.texture = characterPool.pick_random()
+
+
+func _process(delta):
+ if (not animating):
+ return
+
+ currentAnimTime += delta
+ if (currentAnimTime >= speed):
+ _show_next_character()
+ currentAnimTime = 0
+
+
+func _show_next_character():
+ text.visible_characters += 1
+ _play_sound()
+ if text.visible_characters == text.get_total_character_count():
+ animating = false
+ text_typing_finished.emit()
+
+
+func _play_sound():
+ SoundManager.play_sound_with_pitch(sound, randf_range(0.9, 1.1))
+
+
+func _hide_box():
+ visible = false
+func _show_box():
+ visible = true
+
+
+func _on_event_complete():
+ _hide_box()
+func _on_event_fail():
+ _hide_box()
diff --git a/scripts/title.gd b/scripts/title.gd
new file mode 100644
index 0000000..eb6b56c
--- /dev/null
+++ b/scripts/title.gd
@@ -0,0 +1,16 @@
+extends Node2D
+
+
+func _ready():
+ Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ if Input.is_action_just_pressed("BTN_1") or \
+ Input.is_action_just_pressed("BTN_2") or \
+ Input.is_action_just_pressed("BTN_3") or \
+ Input.is_action_just_pressed("BTN_4") or \
+ Input.is_action_just_pressed("BTN_5") or \
+ Input.is_action_just_pressed("BTN_6"):
+ get_tree().change_scene_to_file("res://scenes/spaceship.tscn")
diff --git a/shaders/crt.gdshader b/shaders/crt.gdshader
new file mode 100644
index 0000000..bbf36f3
--- /dev/null
+++ b/shaders/crt.gdshader
@@ -0,0 +1,231 @@
+/*
+Shader from Godot Shaders - the free shader library.
+godotshaders.com/shader/VHS-and-CRT-monitor-effect
+
+This shader is under CC0 license. Feel free to use, improve and
+change this shader according to your needs and consider sharing
+the modified result to godotshaders.com.
+*/
+
+shader_type canvas_item;
+
+//*** IMPORTANT! ***/
+// - If you are using this shader to affect the node it is applied to set 'overlay' to false (unchecked in the instepctor).
+// - If you are using this shader as an overlay, and want the shader to affect the nodes below in the Scene hierarchy,
+// set 'overlay' to true (checked in the inspector).
+// On Mac there is potentially a bug causing this to not work properly. If that is the case and you want to use the shader as an overlay
+// change all "overlay ? SCREEN_TEXTURE : TEXTURE" to only "SCREEN_TEXTURE" on lines 129-140, and "vec2 uv = overlay ? warp(SCREEN_UV) : warp(UV);"
+// to "vec2 uv = warp(SCREEN_UV);" on line 98.
+uniform bool overlay = false;
+
+uniform float scanlines_opacity : hint_range(0.0, 1.0) = 0.4;
+uniform float scanlines_width : hint_range(0.0, 0.5) = 0.25;
+uniform float grille_opacity : hint_range(0.0, 1.0) = 0.3;
+uniform vec2 resolution = vec2(640.0, 480.0); // Set the number of rows and columns the texture will be divided in. Scanlines and grille will make a square based on these values
+
+uniform bool pixelate = true; // Fill each square ("pixel") with a sampled color, creating a pixel look and a more accurate representation of how a CRT monitor would work.
+
+uniform bool roll = true;
+uniform float roll_speed = 8.0; // Positive values are down, negative are up
+uniform float roll_size : hint_range(0.0, 100.0) = 15.0;
+uniform float roll_variation : hint_range(0.1, 5.0) = 1.8; // This valie is not an exact science. You have to play around with the value to find a look you like. How this works is explained in the code below.
+uniform float distort_intensity : hint_range(0.0, 0.2) = 0.05; // The distortion created by the rolling effect.
+
+uniform float noise_opacity : hint_range(0.0, 1.0) = 0.4;
+uniform float noise_speed = 5.0; // There is a movement in the noise pattern that can be hard to see first. This sets the speed of that movement.
+
+uniform float static_noise_intensity : hint_range(0.0, 1.0) = 0.06;
+
+uniform float aberration : hint_range(-1.0, 1.0) = 0.03; // Chromatic aberration, a distortion on each color channel.
+uniform float brightness = 1.4; // When adding scanline gaps and grille the image can get very dark. Brightness tries to compensate for that.
+uniform bool discolor = true; // Add a discolor effect simulating a VHS
+
+uniform float warp_amount :hint_range(0.0, 5.0) = 1.0; // Warp the texture edges simulating the curved glass of a CRT monitor or old TV.
+uniform bool clip_warp = false;
+
+uniform float vignette_intensity = 0.4; // Size of the vignette, how far towards the middle it should go.
+uniform float vignette_opacity : hint_range(0.0, 1.0) = 0.5;
+
+uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
+
+// Used by the noise functin to generate a pseudo random value between 0.0 and 1.0
+vec2 random(vec2 uv){
+ uv = vec2( dot(uv, vec2(127.1,311.7) ),
+ dot(uv, vec2(269.5,183.3) ) );
+ return -1.0 + 2.0 * fract(sin(uv) * 43758.5453123);
+}
+
+// Generate a Perlin noise used by the distortion effects
+float noise(vec2 uv) {
+ vec2 uv_index = floor(uv);
+ vec2 uv_fract = fract(uv);
+
+ vec2 blur = smoothstep(0.0, 1.0, uv_fract);
+
+ return mix( mix( dot( random(uv_index + vec2(0.0,0.0) ), uv_fract - vec2(0.0,0.0) ),
+ dot( random(uv_index + vec2(1.0,0.0) ), uv_fract - vec2(1.0,0.0) ), blur.x),
+ mix( dot( random(uv_index + vec2(0.0,1.0) ), uv_fract - vec2(0.0,1.0) ),
+ dot( random(uv_index + vec2(1.0,1.0) ), uv_fract - vec2(1.0,1.0) ), blur.x), blur.y) * 0.5 + 0.5;
+}
+
+// Takes in the UV and warps the edges, creating the spherized effect
+vec2 warp(vec2 uv){
+ vec2 delta = uv - 0.5;
+ float delta2 = dot(delta.xy, delta.xy);
+ float delta4 = delta2 * delta2;
+ float delta_offset = delta4 * warp_amount;
+
+ return uv + delta * delta_offset;
+}
+
+// Adds a black border to hide stretched pixel created by the warp effect
+float border (vec2 uv){
+ float radius = min(warp_amount, 0.08);
+ radius = max(min(min(abs(radius * 2.0), abs(1.0)), abs(1.0)), 1e-5);
+ vec2 abs_uv = abs(uv * 2.0 - 1.0) - vec2(1.0, 1.0) + radius;
+ float dist = length(max(vec2(0.0), abs_uv)) / radius;
+ float square = smoothstep(0.96, 1.0, dist);
+ return clamp(1.0 - square, 0.0, 1.0);
+}
+
+// Adds a vignette shadow to the edges of the image
+float vignette(vec2 uv){
+ uv *= 1.0 - uv.xy;
+ float vignette = uv.x * uv.y * 15.0;
+ return pow(vignette, vignette_intensity * vignette_opacity);
+}
+
+void fragment()
+{
+ vec2 uv = overlay ? warp(SCREEN_UV) : warp(UV); // Warp the uv. uv will be used in most cases instead of UV to keep the warping
+ vec2 text_uv = uv;
+ vec2 roll_uv = vec2(0.0);
+ float time = roll ? TIME : 0.0;
+
+
+ // Pixelate the texture based on the given resolution.
+ if (pixelate)
+ {
+ text_uv = ceil(uv * resolution) / resolution;
+ }
+
+ // Create the rolling effect. We need roll_line a bit later to make the noise effect.
+ // That is why this runs if roll is true OR noise_opacity is over 0.
+ float roll_line = 0.0;
+ if (roll || noise_opacity > 0.0)
+ {
+ // Create the areas/lines where the texture will be distorted.
+ roll_line = smoothstep(0.3, 0.9, sin(uv.y * roll_size - (time * roll_speed) ) );
+ // Create more lines of a different size and apply to the first set of lines. This creates a bit of variation.
+ roll_line *= roll_line * smoothstep(0.3, 0.9, sin(uv.y * roll_size * roll_variation - (time * roll_speed * roll_variation) ) );
+ // Distort the UV where where the lines are
+ roll_uv = vec2(( roll_line * distort_intensity * (1.-UV.x)), 0.0);
+ }
+
+ vec4 text;
+ if (roll)
+ {
+ // If roll is true distort the texture with roll_uv. The texture is split up into RGB to
+ // make some chromatic aberration. We apply the aberration to the red and green channels accorging to the aberration parameter
+ // and intensify it a bit in the roll distortion.
+ text.r = texture(SCREEN_TEXTURE, text_uv + roll_uv * 0.8 + vec2(aberration, 0.0) * .1).r;
+ text.g = texture(SCREEN_TEXTURE, text_uv + roll_uv * 1.2 - vec2(aberration, 0.0) * .1 ).g;
+ text.b = texture(SCREEN_TEXTURE, text_uv + roll_uv).b;
+ text.a = 1.0;
+ }
+ else
+ {
+ // If roll is false only apply the aberration without any distorion. The aberration values are very small so the .1 is only
+ // to make the slider in the Inspector less sensitive.
+ text.r = texture(SCREEN_TEXTURE, text_uv + vec2(aberration, 0.0) * .1).r;
+ text.g = texture(SCREEN_TEXTURE, text_uv - vec2(aberration, 0.0) * .1).g;
+ text.b = texture(SCREEN_TEXTURE, text_uv).b;
+ text.a = 1.0;
+ }
+
+ float r = text.r;
+ float g = text.g;
+ float b = text.b;
+
+ uv = warp(UV);
+
+ // CRT monitors don't have pixels but groups of red, green and blue dots or lines, called grille. We isolate the texture's color channels
+ // and divide it up in 3 offsetted lines to show the red, green and blue colors next to each other, with a small black gap between.
+ if (grille_opacity > 0.0){
+
+ float g_r = smoothstep(0.85, 0.95, abs(sin(uv.x * (resolution.x * 3.14159265))));
+ r = mix(r, r * g_r, grille_opacity);
+
+ float g_g = smoothstep(0.85, 0.95, abs(sin(1.05 + uv.x * (resolution.x * 3.14159265))));
+ g = mix(g, g * g_g, grille_opacity);
+
+ float b_b = smoothstep(0.85, 0.95, abs(sin(2.1 + uv.x * (resolution.x * 3.14159265))));
+ b = mix(b, b * b_b, grille_opacity);
+
+ }
+
+ // Apply the grille to the texture's color channels and apply Brightness. Since the grille and the scanlines (below) make the image very dark you
+ // can compensate by increasing the brightness.
+ text.r = clamp(r * brightness, 0.0, 1.0);
+ text.g = clamp(g * brightness, 0.0, 1.0);
+ text.b = clamp(b * brightness, 0.0, 1.0);
+
+ // Scanlines are the horizontal lines that make up the image on a CRT monitor.
+ // Here we are actual setting the black gap between each line, which I guess is not the right definition of the word, but you get the idea
+ float scanlines = 0.5;
+ if (scanlines_opacity > 0.0)
+ {
+ // Same technique as above, create lines with sine and applying it to the texture. Smoothstep to allow setting the line size.
+ scanlines = smoothstep(scanlines_width, scanlines_width + 0.5, abs(sin(uv.y * (resolution.y * 3.14159265))));
+ text.rgb = mix(text.rgb, text.rgb * vec3(scanlines), scanlines_opacity);
+ }
+
+ // Apply the banded noise.
+ if (noise_opacity > 0.0)
+ {
+ // Generate a noise pattern that is very stretched horizontally, and animate it with noise_speed
+ float noise = smoothstep(0.4, 0.5, noise(uv * vec2(2.0, 200.0) + vec2(10.0, (TIME * (noise_speed))) ) );
+
+ // We use roll_line (set above) to define how big the noise should be vertically (multiplying cuts off all black parts).
+ // We also add in some basic noise with random() to break up the noise pattern above. The noise is sized according to
+ // the resolution value set in the inspector. If you don't like this look you can
+ // change "ceil(uv * resolution) / resolution" to only "uv" to make it less pixelated. Or multiply resolution with som value
+ // greater than 1.0 to make them smaller.
+ roll_line *= noise * scanlines * clamp(random((ceil(uv * resolution) / resolution) + vec2(TIME * 0.8, 0.0)).x + 0.8, 0.0, 1.0);
+ // Add it to the texture based on noise_opacity
+ text.rgb = clamp(mix(text.rgb, text.rgb + roll_line, noise_opacity), vec3(0.0), vec3(1.0));
+ }
+
+ // Apply static noise by generating it over the whole screen in the same way as above
+ if (static_noise_intensity > 0.0)
+ {
+ text.rgb += clamp(random((ceil(uv * resolution) / resolution) + fract(TIME)).x, 0.0, 1.0) * static_noise_intensity;
+ }
+
+ // Apply a black border to hide imperfections caused by the warping.
+ // Also apply the vignette
+ text.rgb *= border(uv);
+ text.rgb *= vignette(uv);
+ // Hides the black border and make that area transparent. Good if you want to add the the texture on top an image of a TV or monitor.
+ if (clip_warp)
+ {
+ text.a = border(uv);
+ }
+
+ // Apply discoloration to get a VHS look (lower saturation and higher contrast)
+ // You can play with the values below or expose them in the Inspector.
+ float saturation = 0.5;
+ float contrast = 1.2;
+ if (discolor)
+ {
+ // Saturation
+ vec3 greyscale = vec3(text.r + text.g + text.b) / 3.;
+ text.rgb = mix(text.rgb, greyscale, saturation);
+
+ // Contrast
+ float midpoint = pow(0.5, 2.2);
+ text.rgb = (text.rgb - vec3(midpoint)) * contrast + midpoint;
+ }
+
+ COLOR = text;
+}
\ No newline at end of file
diff --git a/shaders/crt_glitch.gdshader b/shaders/crt_glitch.gdshader
new file mode 100644
index 0000000..52058a1
--- /dev/null
+++ b/shaders/crt_glitch.gdshader
@@ -0,0 +1,231 @@
+/*
+Shader from Godot Shaders - the free shader library.
+godotshaders.com/shader/VHS-and-CRT-monitor-effect
+
+This shader is under CC0 license. Feel free to use, improve and
+change this shader according to your needs and consider sharing
+the modified result to godotshaders.com.
+*/
+
+shader_type canvas_item;
+
+//*** IMPORTANT! ***/
+// - If you are using this shader to affect the node it is applied to set 'overlay' to false (unchecked in the instepctor).
+// - If you are using this shader as an overlay, and want the shader to affect the nodes below in the Scene hierarchy,
+// set 'overlay' to true (checked in the inspector).
+// On Mac there is potentially a bug causing this to not work properly. If that is the case and you want to use the shader as an overlay
+// change all "overlay ? SCREEN_TEXTURE : TEXTURE" to only "SCREEN_TEXTURE" on lines 129-140, and "vec2 uv = overlay ? warp(SCREEN_UV) : warp(UV);"
+// to "vec2 uv = warp(SCREEN_UV);" on line 98.
+uniform bool overlay = false;
+
+uniform float scanlines_opacity : hint_range(0.0, 1.0) = 0.4;
+uniform float scanlines_width : hint_range(0.0, 0.5) = 0.25;
+uniform float grille_opacity : hint_range(0.0, 1.0) = 0.3;
+uniform vec2 resolution = vec2(640.0, 480.0); // Set the number of rows and columns the texture will be divided in. Scanlines and grille will make a square based on these values
+
+uniform bool pixelate = true; // Fill each square ("pixel") with a sampled color, creating a pixel look and a more accurate representation of how a CRT monitor would work.
+
+uniform bool roll = true;
+uniform float roll_speed = 8.0; // Positive values are down, negative are up
+uniform float roll_size : hint_range(0.0, 100.0) = 15.0;
+uniform float roll_variation : hint_range(0.1, 5.0) = 1.8; // This valie is not an exact science. You have to play around with the value to find a look you like. How this works is explained in the code below.
+uniform float distort_intensity : hint_range(0.0, 0.2) = 0.05; // The distortion created by the rolling effect.
+
+uniform float noise_opacity : hint_range(0.0, 1.0) = 0.4;
+uniform float noise_speed = 5.0; // There is a movement in the noise pattern that can be hard to see first. This sets the speed of that movement.
+
+uniform float static_noise_intensity : hint_range(0.0, 1.0) = 0.06;
+
+uniform float aberration : hint_range(-1.0, 1.0) = 0.03; // Chromatic aberration, a distortion on each color channel.
+uniform float brightness = 1.4; // When adding scanline gaps and grille the image can get very dark. Brightness tries to compensate for that.
+uniform bool discolor = true; // Add a discolor effect simulating a VHS
+
+uniform float warp_amount :hint_range(0.0, 5.0) = 1.0; // Warp the texture edges simulating the curved glass of a CRT monitor or old TV.
+uniform bool clip_warp = false;
+
+uniform float vignette_intensity = 0.4; // Size of the vignette, how far towards the middle it should go.
+uniform float vignette_opacity : hint_range(0.0, 1.0) = 0.5;
+
+uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
+
+// Used by the noise functin to generate a pseudo random value between 0.0 and 1.0
+vec2 random(vec2 uv){
+ uv = vec2( dot(uv, vec2(127.1,311.7) ),
+ dot(uv, vec2(269.5,183.3) ) );
+ return -1.0 + 2.0 * fract(sin(uv) * 43758.5453123);
+}
+
+// Generate a Perlin noise used by the distortion effects
+float noise(vec2 uv) {
+ vec2 uv_index = floor(uv);
+ vec2 uv_fract = fract(uv);
+
+ vec2 blur = smoothstep(0.0, 1.0, uv_fract);
+
+ return mix( mix( dot( random(uv_index + vec2(0.0,0.0) ), uv_fract - vec2(0.0,0.0) ),
+ dot( random(uv_index + vec2(1.0,0.0) ), uv_fract - vec2(1.0,0.0) ), blur.x),
+ mix( dot( random(uv_index + vec2(0.0,1.0) ), uv_fract - vec2(0.0,1.0) ),
+ dot( random(uv_index + vec2(1.0,1.0) ), uv_fract - vec2(1.0,1.0) ), blur.x), blur.y) * 0.5 + 0.5;
+}
+
+// Takes in the UV and warps the edges, creating the spherized effect
+vec2 warp(vec2 uv){
+ vec2 delta = uv - 0.5;
+ float delta2 = dot(delta.xy, delta.xy);
+ float delta4 = delta2 * delta2;
+ float delta_offset = delta4 * warp_amount;
+
+ return uv + delta * delta_offset;
+}
+
+// Adds a black border to hide stretched pixel created by the warp effect
+float border (vec2 uv){
+ float radius = min(warp_amount, 0.08);
+ radius = max(min(min(abs(radius * 2.0), abs(1.0)), abs(1.0)), 1e-5);
+ vec2 abs_uv = abs(uv * 2.0 - 1.0) - vec2(1.0, 1.0) + radius;
+ float dist = length(max(vec2(0.0), abs_uv)) / radius;
+ float square = smoothstep(0.96, 1.0, dist);
+ return clamp(1.0 - square, 0.0, 1.0);
+}
+
+// Adds a vignette shadow to the edges of the image
+float vignette(vec2 uv){
+ uv *= 1.0 - uv.xy;
+ float vignette = uv.x * uv.y * 15.0;
+ return pow(vignette, vignette_intensity * vignette_opacity);
+}
+
+void fragment()
+{
+ vec2 uv = overlay ? warp(SCREEN_UV) : warp(UV); // Warp the uv. uv will be used in most cases instead of UV to keep the warping
+ vec2 text_uv = uv;
+ vec2 roll_uv = vec2(0.0);
+ float time = roll ? TIME : 0.0;
+
+
+ // Pixelate the texture based on the given resolution.
+ if (pixelate)
+ {
+ text_uv = ceil(uv * resolution) / resolution;
+ }
+
+ // Create the rolling effect. We need roll_line a bit later to make the noise effect.
+ // That is why this runs if roll is true OR noise_opacity is over 0.
+ float roll_line = 0.0;
+ if (roll || noise_opacity > 0.0)
+ {
+ // Create the areas/lines where the texture will be distorted.
+ roll_line = smoothstep(0.3, 0.9, sin(uv.y * roll_size - (time * roll_speed) ) );
+ // Create more lines of a different size and apply to the first set of lines. This creates a bit of variation.
+ roll_line *= roll_line * smoothstep(0.3, 0.9, sin(uv.y * roll_size * roll_variation - (time * roll_speed * roll_variation) ) );
+ // Distort the UV where where the lines are
+ roll_uv = vec2(( noise(vec2(time * 10.0 + uv.y * 15.0, 0.0)) * distort_intensity * (1.-UV.x)), 0.0);
+ }
+
+ vec4 text;
+ if (roll)
+ {
+ // If roll is true distort the texture with roll_uv. The texture is split up into RGB to
+ // make some chromatic aberration. We apply the aberration to the red and green channels accorging to the aberration parameter
+ // and intensify it a bit in the roll distortion.
+ text.r = texture(SCREEN_TEXTURE, text_uv + roll_uv * 0.8 + vec2(aberration, 0.0) * .1).r;
+ text.g = texture(SCREEN_TEXTURE, text_uv + roll_uv * 1.2 - vec2(aberration, 0.0) * .1 ).g;
+ text.b = texture(SCREEN_TEXTURE, text_uv + roll_uv).b;
+ text.a = 1.0;
+ }
+ else
+ {
+ // If roll is false only apply the aberration without any distorion. The aberration values are very small so the .1 is only
+ // to make the slider in the Inspector less sensitive.
+ text.r = texture(SCREEN_TEXTURE, text_uv + vec2(aberration, 0.0) * .1).r;
+ text.g = texture(SCREEN_TEXTURE, text_uv - vec2(aberration, 0.0) * .1).g;
+ text.b = texture(SCREEN_TEXTURE, text_uv).b;
+ text.a = 1.0;
+ }
+
+ float r = text.r;
+ float g = text.g;
+ float b = text.b;
+
+ uv = warp(UV);
+
+ // CRT monitors don't have pixels but groups of red, green and blue dots or lines, called grille. We isolate the texture's color channels
+ // and divide it up in 3 offsetted lines to show the red, green and blue colors next to each other, with a small black gap between.
+ if (grille_opacity > 0.0){
+
+ float g_r = smoothstep(0.85, 0.95, abs(sin(uv.x * (resolution.x * 3.14159265))));
+ r = mix(r, r * g_r, grille_opacity);
+
+ float g_g = smoothstep(0.85, 0.95, abs(sin(1.05 + uv.x * (resolution.x * 3.14159265))));
+ g = mix(g, g * g_g, grille_opacity);
+
+ float b_b = smoothstep(0.85, 0.95, abs(sin(2.1 + uv.x * (resolution.x * 3.14159265))));
+ b = mix(b, b * b_b, grille_opacity);
+
+ }
+
+ // Apply the grille to the texture's color channels and apply Brightness. Since the grille and the scanlines (below) make the image very dark you
+ // can compensate by increasing the brightness.
+ text.r = clamp(r * brightness, 0.0, 1.0);
+ text.g = clamp(g * brightness, 0.0, 1.0);
+ text.b = clamp(b * brightness, 0.0, 1.0);
+
+ // Scanlines are the horizontal lines that make up the image on a CRT monitor.
+ // Here we are actual setting the black gap between each line, which I guess is not the right definition of the word, but you get the idea
+ float scanlines = 0.5;
+ if (scanlines_opacity > 0.0)
+ {
+ // Same technique as above, create lines with sine and applying it to the texture. Smoothstep to allow setting the line size.
+ scanlines = smoothstep(scanlines_width, scanlines_width + 0.5, abs(sin(uv.y * (resolution.y * 3.14159265))));
+ text.rgb = mix(text.rgb, text.rgb * vec3(scanlines), scanlines_opacity);
+ }
+
+ // Apply the banded noise.
+ if (noise_opacity > 0.0)
+ {
+ // Generate a noise pattern that is very stretched horizontally, and animate it with noise_speed
+ float noise = smoothstep(0.4, 0.5, noise(uv * vec2(2.0, 200.0) + vec2(10.0, (TIME * (noise_speed))) ) );
+
+ // We use roll_line (set above) to define how big the noise should be vertically (multiplying cuts off all black parts).
+ // We also add in some basic noise with random() to break up the noise pattern above. The noise is sized according to
+ // the resolution value set in the inspector. If you don't like this look you can
+ // change "ceil(uv * resolution) / resolution" to only "uv" to make it less pixelated. Or multiply resolution with som value
+ // greater than 1.0 to make them smaller.
+ roll_line *= noise * scanlines * clamp(random((ceil(uv * resolution) / resolution) + vec2(TIME * 0.8, 0.0)).x + 0.8, 0.0, 1.0);
+ // Add it to the texture based on noise_opacity
+ text.rgb = clamp(mix(text.rgb, text.rgb + roll_line, noise_opacity), vec3(0.0), vec3(1.0));
+ }
+
+ // Apply static noise by generating it over the whole screen in the same way as above
+ if (static_noise_intensity > 0.0)
+ {
+ text.rgb += clamp(random((ceil(uv * resolution) / resolution) + fract(TIME)).x, 0.0, 1.0) * static_noise_intensity;
+ }
+
+ // Apply a black border to hide imperfections caused by the warping.
+ // Also apply the vignette
+ text.rgb *= border(uv);
+ text.rgb *= vignette(uv);
+ // Hides the black border and make that area transparent. Good if you want to add the the texture on top an image of a TV or monitor.
+ if (clip_warp)
+ {
+ text.a = border(uv);
+ }
+
+ // Apply discoloration to get a VHS look (lower saturation and higher contrast)
+ // You can play with the values below or expose them in the Inspector.
+ float saturation = 0.5;
+ float contrast = 1.2;
+ if (discolor)
+ {
+ // Saturation
+ vec3 greyscale = vec3(text.r + text.g + text.b) / 3.;
+ text.rgb = mix(text.rgb, greyscale, saturation);
+
+ // Contrast
+ float midpoint = pow(0.5, 2.2);
+ text.rgb = (text.rgb - vec3(midpoint)) * contrast + midpoint;
+ }
+
+ COLOR = text;
+}
\ No newline at end of file
diff --git a/shaders/vignette.gdshader b/shaders/vignette.gdshader
new file mode 100644
index 0000000..9edb280
--- /dev/null
+++ b/shaders/vignette.gdshader
@@ -0,0 +1,17 @@
+shader_type canvas_item;
+
+uniform float inner_radius = 0.1;
+uniform float outer_radius = 1;
+uniform float vignette_strength = 1.0;
+uniform float dither_strength = 0.03;
+uniform vec4 vignette_color: source_color;
+
+
+void fragment() {
+ float dist = distance(UV, vec2(0.5));
+
+ float vignette = smoothstep(inner_radius, outer_radius, dist) * vignette_strength;
+ float dither = fract(sin(dot(UV, vec2(12.9898, 78.233))) * 43758.5453123) * dither_strength;
+
+ COLOR = vec4(vignette_color.rgb, vignette + dither);
+}
\ No newline at end of file
diff --git a/sprites/Aporrea_algo_para_empezar.png b/sprites/Aporrea_algo_para_empezar.png
new file mode 100644
index 0000000..6811d75
Binary files /dev/null and b/sprites/Aporrea_algo_para_empezar.png differ
diff --git a/sprites/Aporrea_algo_para_empezar.png.import b/sprites/Aporrea_algo_para_empezar.png.import
new file mode 100644
index 0000000..87a4628
--- /dev/null
+++ b/sprites/Aporrea_algo_para_empezar.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://l7fftjlr2sqo"
+path="res://.godot/imported/Aporrea_algo_para_empezar.png-779ad8bff3fd32e9d17011ce1fdf107b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/Aporrea_algo_para_empezar.png"
+dest_files=["res://.godot/imported/Aporrea_algo_para_empezar.png-779ad8bff3fd32e9d17011ce1fdf107b.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/Logo_Astromovida.png b/sprites/Logo_Astromovida.png
new file mode 100644
index 0000000..641ca29
Binary files /dev/null and b/sprites/Logo_Astromovida.png differ
diff --git a/sprites/Logo_Astromovida.png.import b/sprites/Logo_Astromovida.png.import
new file mode 100644
index 0000000..58f1c63
--- /dev/null
+++ b/sprites/Logo_Astromovida.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://def0yc5mp8ocq"
+path="res://.godot/imported/Logo_Astromovida.png-c31f20e42fcdf8b799502c4d58a1eaef.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/Logo_Astromovida.png"
+dest_files=["res://.godot/imported/Logo_Astromovida.png-c31f20e42fcdf8b799502c4d58a1eaef.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/altavoz apagado.png b/sprites/altavoz apagado.png
new file mode 100644
index 0000000..4e5f5d2
Binary files /dev/null and b/sprites/altavoz apagado.png differ
diff --git a/sprites/altavoz apagado.png.import b/sprites/altavoz apagado.png.import
new file mode 100644
index 0000000..6c83530
--- /dev/null
+++ b/sprites/altavoz apagado.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://chem1yo0ossu1"
+path="res://.godot/imported/altavoz apagado.png-f99c66f0e02ca88b5b2907c7ca3fbfba.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/altavoz apagado.png"
+dest_files=["res://.godot/imported/altavoz apagado.png-f99c66f0e02ca88b5b2907c7ca3fbfba.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/altavoz encendido.png b/sprites/altavoz encendido.png
new file mode 100644
index 0000000..612cdfb
Binary files /dev/null and b/sprites/altavoz encendido.png differ
diff --git a/sprites/altavoz encendido.png.import b/sprites/altavoz encendido.png.import
new file mode 100644
index 0000000..0078b6c
--- /dev/null
+++ b/sprites/altavoz encendido.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cymf1kthfn0am"
+path="res://.godot/imported/altavoz encendido.png-445fa39e3bc2eb475a60d7fffc554086.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/altavoz encendido.png"
+dest_files=["res://.godot/imported/altavoz encendido.png-445fa39e3bc2eb475a60d7fffc554086.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/background.png b/sprites/background.png
new file mode 100644
index 0000000..8492394
Binary files /dev/null and b/sprites/background.png differ
diff --git a/sprites/background.png.import b/sprites/background.png.import
new file mode 100644
index 0000000..40ccb7f
--- /dev/null
+++ b/sprites/background.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bfuksp220ejmv"
+path="res://.godot/imported/background.png-0cfaafa94fbfb5267bc500b34e5eeb6d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/background.png"
+dest_files=["res://.godot/imported/background.png-0cfaafa94fbfb5267bc500b34e5eeb6d.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/burbuja_Blur.png b/sprites/burbuja_Blur.png
new file mode 100644
index 0000000..52c2771
Binary files /dev/null and b/sprites/burbuja_Blur.png differ
diff --git a/sprites/burbuja_Blur.png.import b/sprites/burbuja_Blur.png.import
new file mode 100644
index 0000000..351c29f
--- /dev/null
+++ b/sprites/burbuja_Blur.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cfj7novxcpont"
+path="res://.godot/imported/burbuja_Blur.png-d3b594a94e4bb3c70e442a90b3e6bbdb.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/burbuja_Blur.png"
+dest_files=["res://.godot/imported/burbuja_Blur.png-d3b594a94e4bb3c70e442a90b3e6bbdb.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/burbuja_conversacion.png b/sprites/burbuja_conversacion.png
new file mode 100644
index 0000000..6c6c1ef
Binary files /dev/null and b/sprites/burbuja_conversacion.png differ
diff --git a/sprites/burbuja_conversacion.png.import b/sprites/burbuja_conversacion.png.import
new file mode 100644
index 0000000..48f058d
--- /dev/null
+++ b/sprites/burbuja_conversacion.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bxs6vawsjx4oc"
+path="res://.godot/imported/burbuja_conversacion.png-654879fef5154e3b4cb353f9acd67385.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/burbuja_conversacion.png"
+dest_files=["res://.godot/imported/burbuja_conversacion.png-654879fef5154e3b4cb353f9acd67385.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/cara feliz.png b/sprites/cara feliz.png
new file mode 100644
index 0000000..382670a
Binary files /dev/null and b/sprites/cara feliz.png differ
diff --git a/sprites/cara feliz.png.import b/sprites/cara feliz.png.import
new file mode 100644
index 0000000..fabac06
--- /dev/null
+++ b/sprites/cara feliz.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c5p8vhabiwx3d"
+path="res://.godot/imported/cara feliz.png-caf62755c44f0bf1e3a9eb479a4be763.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/cara feliz.png"
+dest_files=["res://.godot/imported/cara feliz.png-caf62755c44f0bf1e3a9eb479a4be763.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/cara panico.png b/sprites/cara panico.png
new file mode 100644
index 0000000..ecd7cc3
Binary files /dev/null and b/sprites/cara panico.png differ
diff --git a/sprites/cara panico.png.import b/sprites/cara panico.png.import
new file mode 100644
index 0000000..84fb5ab
--- /dev/null
+++ b/sprites/cara panico.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://hjwhjwfpabnj"
+path="res://.godot/imported/cara panico.png-9ee825b10aa28cef3841756890bd29d2.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/cara panico.png"
+dest_files=["res://.godot/imported/cara panico.png-9ee825b10aa28cef3841756890bd29d2.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/cara tieso.png b/sprites/cara tieso.png
new file mode 100644
index 0000000..acf0950
Binary files /dev/null and b/sprites/cara tieso.png differ
diff --git a/sprites/cara tieso.png.import b/sprites/cara tieso.png.import
new file mode 100644
index 0000000..b3309c3
--- /dev/null
+++ b/sprites/cara tieso.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://d0fbphqlv1pcp"
+path="res://.godot/imported/cara tieso.png-259a7415c36d7cda11416540a9e9701f.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/cara tieso.png"
+dest_files=["res://.godot/imported/cara tieso.png-259a7415c36d7cda11416540a9e9701f.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/fondo general.png b/sprites/fondo general.png
new file mode 100644
index 0000000..5211c6c
Binary files /dev/null and b/sprites/fondo general.png differ
diff --git a/sprites/fondo general.png.import b/sprites/fondo general.png.import
new file mode 100644
index 0000000..3deede8
--- /dev/null
+++ b/sprites/fondo general.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://hwdnd10qvxn4"
+path="res://.godot/imported/fondo general.png-4ecbd56b8adf39a71c406419d7481a54.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/fondo general.png"
+dest_files=["res://.godot/imported/fondo general.png-4ecbd56b8adf39a71c406419d7481a54.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/fx/estrellacutre2.png b/sprites/fx/estrellacutre2.png
new file mode 100644
index 0000000..7b98014
Binary files /dev/null and b/sprites/fx/estrellacutre2.png differ
diff --git a/sprites/fx/estrellacutre2.png.import b/sprites/fx/estrellacutre2.png.import
new file mode 100644
index 0000000..c372c89
--- /dev/null
+++ b/sprites/fx/estrellacutre2.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c2jto675n6weg"
+path="res://.godot/imported/estrellacutre2.png-25ae2ea1d1af63724d4a4ea02324c07e.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/fx/estrellacutre2.png"
+dest_files=["res://.godot/imported/estrellacutre2.png-25ae2ea1d1af63724d4a4ea02324c07e.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/fx/estrellita_cutre.png b/sprites/fx/estrellita_cutre.png
new file mode 100644
index 0000000..89b22d1
Binary files /dev/null and b/sprites/fx/estrellita_cutre.png differ
diff --git a/sprites/fx/estrellita_cutre.png.import b/sprites/fx/estrellita_cutre.png.import
new file mode 100644
index 0000000..47192be
--- /dev/null
+++ b/sprites/fx/estrellita_cutre.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b02f0labhmgac"
+path="res://.godot/imported/estrellita_cutre.png-9fdfdfd667f5ae989527dc4da110d4f4.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/fx/estrellita_cutre.png"
+dest_files=["res://.godot/imported/estrellita_cutre.png-9fdfdfd667f5ae989527dc4da110d4f4.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/fx/whitePuff00.png b/sprites/fx/whitePuff00.png
new file mode 100644
index 0000000..d719d86
Binary files /dev/null and b/sprites/fx/whitePuff00.png differ
diff --git a/sprites/fx/whitePuff00.png.import b/sprites/fx/whitePuff00.png.import
new file mode 100644
index 0000000..310ecb3
--- /dev/null
+++ b/sprites/fx/whitePuff00.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://ctlhowug3qhm3"
+path="res://.godot/imported/whitePuff00.png-c810b31e0d97a42984b017c6461c9ed7.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/fx/whitePuff00.png"
+dest_files=["res://.godot/imported/whitePuff00.png-c810b31e0d97a42984b017c6461c9ed7.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/luz 1.png b/sprites/luz 1.png
new file mode 100644
index 0000000..e029020
Binary files /dev/null and b/sprites/luz 1.png differ
diff --git a/sprites/luz 1.png.import b/sprites/luz 1.png.import
new file mode 100644
index 0000000..dad7afa
--- /dev/null
+++ b/sprites/luz 1.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bn160j1ao7da5"
+path="res://.godot/imported/luz 1.png-03a952f280a2850b3f3b10cf72ebc7ed.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/luz 1.png"
+dest_files=["res://.godot/imported/luz 1.png-03a952f280a2850b3f3b10cf72ebc7ed.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/luz 2.png b/sprites/luz 2.png
new file mode 100644
index 0000000..c2ea131
Binary files /dev/null and b/sprites/luz 2.png differ
diff --git a/sprites/luz 2.png.import b/sprites/luz 2.png.import
new file mode 100644
index 0000000..ed7651d
--- /dev/null
+++ b/sprites/luz 2.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://d33s6pef40flk"
+path="res://.godot/imported/luz 2.png-7964a0944ea04bf87e30bf1d89d42874.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/luz 2.png"
+dest_files=["res://.godot/imported/luz 2.png-7964a0944ea04bf87e30bf1d89d42874.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/luz 3.png b/sprites/luz 3.png
new file mode 100644
index 0000000..392e6d6
Binary files /dev/null and b/sprites/luz 3.png differ
diff --git a/sprites/luz 3.png.import b/sprites/luz 3.png.import
new file mode 100644
index 0000000..38d2ea7
--- /dev/null
+++ b/sprites/luz 3.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://3jt08tccjv7p"
+path="res://.godot/imported/luz 3.png-d0b53e815f42b723df957ac5b796d02b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/luz 3.png"
+dest_files=["res://.godot/imported/luz 3.png-d0b53e815f42b723df957ac5b796d02b.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/luz 4.png b/sprites/luz 4.png
new file mode 100644
index 0000000..2b90f03
Binary files /dev/null and b/sprites/luz 4.png differ
diff --git a/sprites/luz 4.png.import b/sprites/luz 4.png.import
new file mode 100644
index 0000000..1647ffb
--- /dev/null
+++ b/sprites/luz 4.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c3s7ahkssti82"
+path="res://.godot/imported/luz 4.png-0a4ea96adb28aaaedf90a37adf7fbc76.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/luz 4.png"
+dest_files=["res://.godot/imported/luz 4.png-0a4ea96adb28aaaedf90a37adf7fbc76.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/mascara sombra.png b/sprites/mascara sombra.png
new file mode 100644
index 0000000..c7a57c5
Binary files /dev/null and b/sprites/mascara sombra.png differ
diff --git a/sprites/mascara sombra.png.import b/sprites/mascara sombra.png.import
new file mode 100644
index 0000000..ed3093e
--- /dev/null
+++ b/sprites/mascara sombra.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c603gx7lecrxq"
+path="res://.godot/imported/mascara sombra.png-d55309f95d9a2d67683592d17c11272a.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/mascara sombra.png"
+dest_files=["res://.godot/imported/mascara sombra.png-d55309f95d9a2d67683592d17c11272a.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/mascara.png b/sprites/mascara.png
new file mode 100644
index 0000000..f767bb6
Binary files /dev/null and b/sprites/mascara.png differ
diff --git a/sprites/mascara.png.import b/sprites/mascara.png.import
new file mode 100644
index 0000000..7b68737
--- /dev/null
+++ b/sprites/mascara.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dfwqex0goxj5j"
+path="res://.godot/imported/mascara.png-ed30c3c3c364cbc59a0b59718b83f147.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/mascara.png"
+dest_files=["res://.godot/imported/mascara.png-ed30c3c3c364cbc59a0b59718b83f147.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/motor derecho.png b/sprites/motor derecho.png
new file mode 100644
index 0000000..9ebe2e1
Binary files /dev/null and b/sprites/motor derecho.png differ
diff --git a/sprites/motor derecho.png.import b/sprites/motor derecho.png.import
new file mode 100644
index 0000000..9e0f6f6
--- /dev/null
+++ b/sprites/motor derecho.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bmwvo4wau13e8"
+path="res://.godot/imported/motor derecho.png-5643f59bddebaa9dddb79cade03253ed.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/motor derecho.png"
+dest_files=["res://.godot/imported/motor derecho.png-5643f59bddebaa9dddb79cade03253ed.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/motor izquierdo.png b/sprites/motor izquierdo.png
new file mode 100644
index 0000000..35f152d
Binary files /dev/null and b/sprites/motor izquierdo.png differ
diff --git a/sprites/motor izquierdo.png.import b/sprites/motor izquierdo.png.import
new file mode 100644
index 0000000..e693193
--- /dev/null
+++ b/sprites/motor izquierdo.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://4abm8qv3y12q"
+path="res://.godot/imported/motor izquierdo.png-df40f1c2e394e129ae413ef618c56980.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/motor izquierdo.png"
+dest_files=["res://.godot/imported/motor izquierdo.png-df40f1c2e394e129ae413ef618c56980.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/ondas.png b/sprites/ondas.png
new file mode 100644
index 0000000..0d8c45e
Binary files /dev/null and b/sprites/ondas.png differ
diff --git a/sprites/ondas.png.import b/sprites/ondas.png.import
new file mode 100644
index 0000000..345a031
--- /dev/null
+++ b/sprites/ondas.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://r1vlkamrdvut"
+path="res://.godot/imported/ondas.png-2e312dcd02ec60329d095a5890fc67cb.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/ondas.png"
+dest_files=["res://.godot/imported/ondas.png-2e312dcd02ec60329d095a5890fc67cb.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/ondas1.png b/sprites/ondas1.png
new file mode 100644
index 0000000..38573b2
Binary files /dev/null and b/sprites/ondas1.png differ
diff --git a/sprites/ondas1.png.import b/sprites/ondas1.png.import
new file mode 100644
index 0000000..7603b1a
--- /dev/null
+++ b/sprites/ondas1.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cd7ebcxsui4c3"
+path="res://.godot/imported/ondas1.png-b6afca2e34ac3a312328f5b7c3e2436d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/ondas1.png"
+dest_files=["res://.godot/imported/ondas1.png-b6afca2e34ac3a312328f5b7c3e2436d.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/ondas2.png b/sprites/ondas2.png
new file mode 100644
index 0000000..f6bb726
Binary files /dev/null and b/sprites/ondas2.png differ
diff --git a/sprites/ondas2.png.import b/sprites/ondas2.png.import
new file mode 100644
index 0000000..818714a
--- /dev/null
+++ b/sprites/ondas2.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://d35eui04v3k80"
+path="res://.godot/imported/ondas2.png-5b493f762afc6b00c79a8e212fb46a97.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/ondas2.png"
+dest_files=["res://.godot/imported/ondas2.png-5b493f762afc6b00c79a8e212fb46a97.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/retrato.png b/sprites/retrato.png
new file mode 100644
index 0000000..9eb2949
Binary files /dev/null and b/sprites/retrato.png differ
diff --git a/sprites/retrato.png.import b/sprites/retrato.png.import
new file mode 100644
index 0000000..67566d1
--- /dev/null
+++ b/sprites/retrato.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://gh06fhvhmn35"
+path="res://.godot/imported/retrato.png-8951a411a4fd255d21b6015712d36da2.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/retrato.png"
+dest_files=["res://.godot/imported/retrato.png-8951a411a4fd255d21b6015712d36da2.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/retrato2.png b/sprites/retrato2.png
new file mode 100644
index 0000000..dc1edd1
Binary files /dev/null and b/sprites/retrato2.png differ
diff --git a/sprites/retrato2.png.import b/sprites/retrato2.png.import
new file mode 100644
index 0000000..cb79cf3
--- /dev/null
+++ b/sprites/retrato2.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dbq3yme5m8th8"
+path="res://.godot/imported/retrato2.png-817adf9af1d00663ff54bb0fcb822a68.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/retrato2.png"
+dest_files=["res://.godot/imported/retrato2.png-817adf9af1d00663ff54bb0fcb822a68.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/sprites/retrato3.png b/sprites/retrato3.png
new file mode 100644
index 0000000..0528dac
Binary files /dev/null and b/sprites/retrato3.png differ
diff --git a/sprites/retrato3.png.import b/sprites/retrato3.png.import
new file mode 100644
index 0000000..e19c674
--- /dev/null
+++ b/sprites/retrato3.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dtr13fgmo5i3n"
+path="res://.godot/imported/retrato3.png-0e06acac76620c35c383d678e8d0ab43.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://sprites/retrato3.png"
+dest_files=["res://.godot/imported/retrato3.png-0e06acac76620c35c383d678e8d0ab43.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1