├── Audio ├── SFX │ ├── Pause.wav │ ├── Capsule.wav │ ├── LevelUp.wav │ ├── MenuBip.wav │ ├── CharHurt.wav │ ├── CharPunch.wav │ ├── MothraRoar.wav │ ├── MothraStep.wav │ ├── GodzillaRoar.wav │ ├── GodzillaStep.wav │ ├── BlockDestruct.wav │ ├── GodzillaHeatBeam.wav │ ├── Pause.wav.import │ ├── Capsule.wav.import │ ├── LevelUp.wav.import │ ├── MenuBip.wav.import │ ├── CharHurt.wav.import │ ├── CharPunch.wav.import │ ├── MothraRoar.wav.import │ ├── MothraStep.wav.import │ ├── GodzillaRoar.wav.import │ ├── GodzillaStep.wav.import │ ├── BlockDestruct.wav.import │ └── GodzillaHeatBeam.wav.import └── Soundtrack │ ├── Earth.ogg │ ├── Mars.ogg │ ├── Credits.ogg │ ├── GameOver.ogg │ ├── MainMenu.ogg │ ├── Victory.ogg │ ├── MogueraTheme.ogg │ ├── PassWordGame.ogg │ ├── PlayerDeath.ogg │ ├── TitleScreen.ogg │ ├── Earth.ogg.import │ ├── Mars.ogg.import │ ├── Credits.ogg.import │ ├── MainMenu.ogg.import │ ├── Victory.ogg.import │ ├── GameOver.ogg.import │ ├── PlayerDeath.ogg.import │ ├── TitleScreen.ogg.import │ ├── MogueraTheme.ogg.import │ └── PassWordGame.ogg.import ├── Sprites ├── font1.png ├── font2.png ├── hudbar.png ├── BoardSprites.png ├── EditorBoard.png ├── PassWordGame.png ├── TitleScreen.png ├── controller.png ├── GameIntro │ ├── font.png │ ├── images.png │ ├── planets.png │ ├── earthships.png │ ├── gohtenjets.png │ ├── font.png.import │ ├── images.png.import │ ├── planets.png.import │ ├── earthships.png.import │ └── gohtenjets.png.import ├── Levels │ ├── explosion.png │ ├── PlanetIcons.png │ ├── Jupiter │ │ ├── board.png │ │ └── board.png.import │ ├── TestLevel │ │ ├── board.png │ │ ├── floor.png │ │ ├── hills.png │ │ ├── sky.png │ │ ├── YellowShip.png │ │ ├── GodzillaMoMWilderness.png │ │ ├── sky.png.import │ │ ├── board.png.import │ │ ├── floor.png.import │ │ ├── hills.png.import │ │ ├── YellowShip.png.import │ │ └── GodzillaMoMWilderness.png.import │ ├── explosion.png.import │ └── PlanetIcons.png.import ├── Objects │ ├── capsules.png │ ├── Enemies │ │ ├── Jet.png │ │ ├── RocketLauncher.png │ │ ├── RocketLauncherRocket.png │ │ ├── Jet.png.import │ │ ├── RocketLauncher.png.import │ │ └── RocketLauncherRocket.png.import │ └── capsules.png.import ├── Characters │ ├── Mothra │ │ ├── hurt.png │ │ ├── idle.png │ │ ├── particles.png │ │ ├── hurt.png.import │ │ ├── idle.png.import │ │ └── particles.png.import │ └── Godzilla │ │ ├── hurt.png │ │ ├── crouch.png │ │ ├── kick1.png │ │ ├── kick2.png │ │ ├── punch1.png │ │ ├── punch2.png │ │ ├── heat_beam.png │ │ ├── tail_whip.png │ │ ├── walk_body.png │ │ ├── walk_head.png │ │ ├── heat_beaming.png │ │ ├── hurt.png.import │ │ ├── kick1.png.import │ │ ├── kick2.png.import │ │ ├── crouch.png.import │ │ ├── punch1.png.import │ │ ├── punch2.png.import │ │ ├── heat_beam.png.import │ │ ├── tail_whip.png.import │ │ ├── walk_body.png.import │ │ ├── walk_head.png.import │ │ └── heat_beaming.png.import ├── font1.png.import ├── font2.png.import ├── hudbar.png.import ├── controller.png.import ├── EditorBoard.png.import ├── TitleScreen.png.import ├── BoardSprites.png.import └── PassWordGame.png.import ├── Tutorials ├── Framework overview.pdf ├── How to create a new board.pdf ├── How to create a new character.pdf └── How to create a new character (part 2).pdf ├── Scripts ├── GameIntro │ ├── Gohten.gd │ ├── SolarSystem.gd │ ├── EarthInvasion.gd │ └── GameIntro.gd ├── Boards │ └── BoardDescription.gd ├── Objects │ ├── Explosion.gd │ ├── Enemies │ │ ├── BaseEnemy.gd │ │ ├── JetProjectile.gd │ │ ├── YellowShip.gd │ │ ├── RocketLauncherRocket.gd │ │ ├── RocketLauncher.gd │ │ └── Jet.gd │ ├── Characters │ │ ├── Dead.gd │ │ ├── Hurt.gd │ │ ├── GodzillaHeatBeam.gd │ │ ├── LevelIntro.gd │ │ ├── MothraParticle.gd │ │ ├── Fly.gd │ │ └── Walk.gd │ ├── State.gd │ ├── PowerComponent.gd │ ├── StateMachine.gd │ ├── Levels │ │ └── TestLevel │ │ │ └── BreakableMountain.gd │ ├── Capsule.gd │ ├── HealthComponent.gd │ ├── Bar.gd │ └── AttackComponent.gd ├── MainMenu │ ├── Menu.gd │ ├── SaveSlot.gd │ ├── BaseMenu.gd │ ├── SoundSettings.gd │ ├── VideoSettings.gd │ └── Saves.gd ├── GameOver.gd ├── Levels │ ├── Camera.gd │ └── Bosses │ │ ├── Mothra.gd │ │ └── BaseBoss.gd ├── TitleScreen.gd ├── PauseManager.gd ├── Main.gd ├── SaveManager.gd └── Credits.gd ├── Other ├── GameIntroText.txt └── Credits.txt ├── Objects ├── StateMachine.tscn ├── HealthComponent.tscn ├── PowerComponent.tscn ├── Boards │ ├── Selector.tscn │ ├── Piece.tscn │ └── MessageWindow.tscn ├── AttackComponent.tscn ├── Levels │ ├── Sky.tscn │ ├── Enemies │ │ ├── BaseEnemy.tscn │ │ ├── JetProjectile.tscn │ │ ├── YellowShip.tscn │ │ ├── RocketLauncherRocket.tscn │ │ └── RocketLauncher.tscn │ ├── Floor.tscn │ ├── Explosion.tscn │ ├── TestLevel │ │ └── BreakableMountain.tscn │ └── Capsule.tscn ├── Bar.tscn └── Characters │ └── MothraParticle.tscn ├── .gitignore ├── default_bus_layout.tres ├── Scenes ├── Bosses │ ├── Mothra.tscn │ └── BaseBoss.tscn ├── GameOver.tscn ├── MainMenu │ ├── BaseMenu.tscn │ ├── VideoSettings.tscn │ ├── SoundSettings.tscn │ ├── Settings.tscn │ ├── Controls.tscn │ ├── SaveSlot.tscn │ ├── PauseMenu.tscn │ ├── Saves.tscn │ └── MainMenu.tscn ├── Levels │ ├── TransitionLevel.tscn │ └── BaseLevel.tscn ├── Boards │ ├── Jupiter.tscn │ └── TheEarth.tscn ├── Credits.tscn ├── TitleScreen.tscn ├── Main.tscn └── PassWordGame.tscn ├── icon.svg ├── icon.svg.import ├── LICENSE └── README.md /Audio/SFX/Pause.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/Pause.wav -------------------------------------------------------------------------------- /Sprites/font1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/font1.png -------------------------------------------------------------------------------- /Sprites/font2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/font2.png -------------------------------------------------------------------------------- /Sprites/hudbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/hudbar.png -------------------------------------------------------------------------------- /Audio/SFX/Capsule.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/Capsule.wav -------------------------------------------------------------------------------- /Audio/SFX/LevelUp.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/LevelUp.wav -------------------------------------------------------------------------------- /Audio/SFX/MenuBip.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/MenuBip.wav -------------------------------------------------------------------------------- /Audio/SFX/CharHurt.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/CharHurt.wav -------------------------------------------------------------------------------- /Audio/SFX/CharPunch.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/CharPunch.wav -------------------------------------------------------------------------------- /Audio/SFX/MothraRoar.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/MothraRoar.wav -------------------------------------------------------------------------------- /Audio/SFX/MothraStep.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/MothraStep.wav -------------------------------------------------------------------------------- /Sprites/BoardSprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/BoardSprites.png -------------------------------------------------------------------------------- /Sprites/EditorBoard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/EditorBoard.png -------------------------------------------------------------------------------- /Sprites/PassWordGame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/PassWordGame.png -------------------------------------------------------------------------------- /Sprites/TitleScreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/TitleScreen.png -------------------------------------------------------------------------------- /Sprites/controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/controller.png -------------------------------------------------------------------------------- /Audio/SFX/GodzillaRoar.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/GodzillaRoar.wav -------------------------------------------------------------------------------- /Audio/SFX/GodzillaStep.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/GodzillaStep.wav -------------------------------------------------------------------------------- /Audio/Soundtrack/Earth.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/Soundtrack/Earth.ogg -------------------------------------------------------------------------------- /Audio/Soundtrack/Mars.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/Soundtrack/Mars.ogg -------------------------------------------------------------------------------- /Sprites/GameIntro/font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/GameIntro/font.png -------------------------------------------------------------------------------- /Audio/SFX/BlockDestruct.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/BlockDestruct.wav -------------------------------------------------------------------------------- /Audio/Soundtrack/Credits.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/Soundtrack/Credits.ogg -------------------------------------------------------------------------------- /Audio/Soundtrack/GameOver.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/Soundtrack/GameOver.ogg -------------------------------------------------------------------------------- /Audio/Soundtrack/MainMenu.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/Soundtrack/MainMenu.ogg -------------------------------------------------------------------------------- /Audio/Soundtrack/Victory.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/Soundtrack/Victory.ogg -------------------------------------------------------------------------------- /Sprites/GameIntro/images.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/GameIntro/images.png -------------------------------------------------------------------------------- /Sprites/GameIntro/planets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/GameIntro/planets.png -------------------------------------------------------------------------------- /Sprites/Levels/explosion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Levels/explosion.png -------------------------------------------------------------------------------- /Sprites/Objects/capsules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Objects/capsules.png -------------------------------------------------------------------------------- /Audio/SFX/GodzillaHeatBeam.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/SFX/GodzillaHeatBeam.wav -------------------------------------------------------------------------------- /Sprites/Levels/PlanetIcons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Levels/PlanetIcons.png -------------------------------------------------------------------------------- /Sprites/Objects/Enemies/Jet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Objects/Enemies/Jet.png -------------------------------------------------------------------------------- /Audio/Soundtrack/MogueraTheme.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/Soundtrack/MogueraTheme.ogg -------------------------------------------------------------------------------- /Audio/Soundtrack/PassWordGame.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/Soundtrack/PassWordGame.ogg -------------------------------------------------------------------------------- /Audio/Soundtrack/PlayerDeath.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/Soundtrack/PlayerDeath.ogg -------------------------------------------------------------------------------- /Audio/Soundtrack/TitleScreen.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Audio/Soundtrack/TitleScreen.ogg -------------------------------------------------------------------------------- /Sprites/Characters/Mothra/hurt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Mothra/hurt.png -------------------------------------------------------------------------------- /Sprites/Characters/Mothra/idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Mothra/idle.png -------------------------------------------------------------------------------- /Sprites/GameIntro/earthships.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/GameIntro/earthships.png -------------------------------------------------------------------------------- /Sprites/GameIntro/gohtenjets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/GameIntro/gohtenjets.png -------------------------------------------------------------------------------- /Sprites/Levels/Jupiter/board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Levels/Jupiter/board.png -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Levels/TestLevel/board.png -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/floor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Levels/TestLevel/floor.png -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/hills.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Levels/TestLevel/hills.png -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/sky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Levels/TestLevel/sky.png -------------------------------------------------------------------------------- /Tutorials/Framework overview.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Tutorials/Framework overview.pdf -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/hurt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Godzilla/hurt.png -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/crouch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Godzilla/crouch.png -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/kick1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Godzilla/kick1.png -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/kick2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Godzilla/kick2.png -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/punch1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Godzilla/punch1.png -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/punch2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Godzilla/punch2.png -------------------------------------------------------------------------------- /Sprites/Characters/Mothra/particles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Mothra/particles.png -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/YellowShip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Levels/TestLevel/YellowShip.png -------------------------------------------------------------------------------- /Tutorials/How to create a new board.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Tutorials/How to create a new board.pdf -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/heat_beam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Godzilla/heat_beam.png -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/tail_whip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Godzilla/tail_whip.png -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/walk_body.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Godzilla/walk_body.png -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/walk_head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Godzilla/walk_head.png -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/heat_beaming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Characters/Godzilla/heat_beaming.png -------------------------------------------------------------------------------- /Sprites/Objects/Enemies/RocketLauncher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Objects/Enemies/RocketLauncher.png -------------------------------------------------------------------------------- /Tutorials/How to create a new character.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Tutorials/How to create a new character.pdf -------------------------------------------------------------------------------- /Sprites/Objects/Enemies/RocketLauncherRocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Objects/Enemies/RocketLauncherRocket.png -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/GodzillaMoMWilderness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Sprites/Levels/TestLevel/GodzillaMoMWilderness.png -------------------------------------------------------------------------------- /Tutorials/How to create a new character (part 2).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nintorch/Godotzilla/HEAD/Tutorials/How to create a new character (part 2).pdf -------------------------------------------------------------------------------- /Scripts/GameIntro/Gohten.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | const JETS_SPEED := 0.25 * 60 4 | @onready var jets: TextureRect = $Jets 5 | 6 | func _process(delta: float) -> void: 7 | jets.position.x += JETS_SPEED * delta 8 | -------------------------------------------------------------------------------- /Scripts/Boards/BoardDescription.gd: -------------------------------------------------------------------------------- 1 | class_name BoardDescription 2 | extends Resource 3 | 4 | @export var name: String 5 | @export var board_id: String 6 | @export var icon: Texture2D 7 | @export var scene: PackedScene 8 | -------------------------------------------------------------------------------- /Other/GameIntroText.txt: -------------------------------------------------------------------------------- 1 | In 2XXX A.D., the earth receives a declaration of war from Planet X. 2 | With the entire solar system as the battlefield, bloody combat begins 3 | between space monsters and our guardians, Godzilla and Mothra! 4 | -------------------------------------------------------------------------------- /Objects/StateMachine.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://bffduqvb2xwju"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/Objects/StateMachine.gd" id="1_448rr"] 4 | 5 | [node name="StateMachine" type="Node"] 6 | script = ExtResource("1_448rr") 7 | -------------------------------------------------------------------------------- /Objects/HealthComponent.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://camascwoory5h"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/Objects/HealthComponent.gd" id="1_lfj1s"] 4 | 5 | [node name="HealthComponent" type="Node"] 6 | script = ExtResource("1_lfj1s") 7 | -------------------------------------------------------------------------------- /Objects/PowerComponent.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://bdrpwa8gyr6lc"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/Objects/PowerComponent.gd" id="1_hohs7"] 4 | 5 | [node name="PowerComponent" type="Node"] 6 | script = ExtResource("1_hohs7") 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Godot 4+ specific ignores 2 | .godot/ 3 | 4 | # Godot-specific ignores 5 | .import/ 6 | export.cfg 7 | export_presets.cfg 8 | 9 | # Imported translations (automatically generated from CSV files) 10 | *.translation 11 | 12 | # Mono-specific ignores 13 | .mono/ 14 | data_*/ 15 | mono_crash.*.json 16 | 17 | Godotzilla.zip 18 | *.tmp 19 | -------------------------------------------------------------------------------- /Scripts/Objects/Explosion.gd: -------------------------------------------------------------------------------- 1 | extends Sprite2D 2 | 3 | @onready var animation_player: AnimationPlayer = $AnimationPlayer 4 | var velocity: Vector2 5 | 6 | func _ready() -> void: 7 | animation_player.play("animation") 8 | # From -2 to 2 9 | velocity = Vector2(-2 + randi() % 5, -2 + randi() % 5) * 60 10 | 11 | func _physics_process(delta: float) -> void: 12 | position += velocity * delta 13 | -------------------------------------------------------------------------------- /Scripts/MainMenu/Menu.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | @onready var main_menu: BaseMenu = get_parent() 4 | var options: Array[Control] 5 | 6 | func _ready() -> void: 7 | options.assign(get_children().filter(func(c: Node) -> bool: 8 | return c.is_in_group("option"))) 9 | 10 | func menu_enter() -> void: 11 | pass 12 | 13 | func menu_exit() -> void: 14 | pass 15 | 16 | func menu_select(_id: int) -> void: 17 | pass 18 | -------------------------------------------------------------------------------- /default_bus_layout.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="AudioBusLayout" format=3 uid="uid://bh6jt0ysom3i2"] 2 | 3 | [resource] 4 | bus/1/name = &"SFX" 5 | bus/1/solo = false 6 | bus/1/mute = false 7 | bus/1/bypass_fx = false 8 | bus/1/volume_db = 0.0 9 | bus/1/send = &"Master" 10 | bus/2/name = &"Music" 11 | bus/2/solo = false 12 | bus/2/mute = false 13 | bus/2/bypass_fx = false 14 | bus/2/volume_db = 0.0 15 | bus/2/send = &"Master" 16 | -------------------------------------------------------------------------------- /Objects/Boards/Selector.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://dtc8wqm5nbty2"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://wmgv6kcqcri0" path="res://Sprites/BoardSprites.png" id="1_hejr5"] 4 | [ext_resource type="Script" path="res://Scripts/Objects/Boards/Selector.gd" id="2_4q06p"] 5 | 6 | 7 | [node name="Selector" type="Sprite2D"] 8 | texture = ExtResource("1_hejr5") 9 | hframes = 3 10 | vframes = 3 11 | script = ExtResource("2_4q06p") 12 | -------------------------------------------------------------------------------- /Audio/Soundtrack/Earth.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://ij42lx3rq1l1" 6 | path="res://.godot/imported/Earth.ogg-e40f0afa4edfa647bf9098d181e4314e.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/Soundtrack/Earth.ogg" 11 | dest_files=["res://.godot/imported/Earth.ogg-e40f0afa4edfa647bf9098d181e4314e.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=true 16 | loop_offset=0 17 | bpm=0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /Audio/Soundtrack/Mars.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://dtdevd1wqdmom" 6 | path="res://.godot/imported/Mars.ogg-054f4390c562b36adc5c42a6d07ce4f8.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/Soundtrack/Mars.ogg" 11 | dest_files=["res://.godot/imported/Mars.ogg-054f4390c562b36adc5c42a6d07ce4f8.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=true 16 | loop_offset=0.0 17 | bpm=0.0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /Audio/Soundtrack/Credits.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://bw2ac1eh6npco" 6 | path="res://.godot/imported/Credits.ogg-cf96903ebcb373955562d4b09cca3e87.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/Soundtrack/Credits.ogg" 11 | dest_files=["res://.godot/imported/Credits.ogg-cf96903ebcb373955562d4b09cca3e87.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=true 16 | loop_offset=0.0 17 | bpm=0.0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /Audio/Soundtrack/MainMenu.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://nl06a7xp7bq7" 6 | path="res://.godot/imported/MainMenu.ogg-656f76c9ee02e978991d1060f4b83bbc.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/Soundtrack/MainMenu.ogg" 11 | dest_files=["res://.godot/imported/MainMenu.ogg-656f76c9ee02e978991d1060f4b83bbc.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=false 16 | loop_offset=0 17 | bpm=0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /Audio/Soundtrack/Victory.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://du1acm7e0olkd" 6 | path="res://.godot/imported/Victory.ogg-8c08ff34d09cbf02850bc7d8adb108a2.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/Soundtrack/Victory.ogg" 11 | dest_files=["res://.godot/imported/Victory.ogg-8c08ff34d09cbf02850bc7d8adb108a2.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=false 16 | loop_offset=0 17 | bpm=0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /Audio/Soundtrack/GameOver.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://cdcxf72g70g30" 6 | path="res://.godot/imported/GameOver.ogg-ffbf200824734427707666cfe9f48718.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/Soundtrack/GameOver.ogg" 11 | dest_files=["res://.godot/imported/GameOver.ogg-ffbf200824734427707666cfe9f48718.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=false 16 | loop_offset=0 17 | bpm=0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /Audio/Soundtrack/PlayerDeath.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://cav1id8a78ejn" 6 | path="res://.godot/imported/PlayerDeath.ogg-f301c85b79afda1432e2d468a384eadb.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/Soundtrack/PlayerDeath.ogg" 11 | dest_files=["res://.godot/imported/PlayerDeath.ogg-f301c85b79afda1432e2d468a384eadb.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=false 16 | loop_offset=0 17 | bpm=0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /Audio/Soundtrack/TitleScreen.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://dvs4g8yucjai4" 6 | path="res://.godot/imported/TitleScreen.ogg-cacaa4d8c2f8c4ece2a2a05e586b89bc.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/Soundtrack/TitleScreen.ogg" 11 | dest_files=["res://.godot/imported/TitleScreen.ogg-cacaa4d8c2f8c4ece2a2a05e586b89bc.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=true 16 | loop_offset=0 17 | bpm=0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /Audio/Soundtrack/MogueraTheme.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://by7wimbn2cemn" 6 | path="res://.godot/imported/MogueraTheme.ogg-f44a6ad6374977c5ab74800f98684771.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/Soundtrack/MogueraTheme.ogg" 11 | dest_files=["res://.godot/imported/MogueraTheme.ogg-f44a6ad6374977c5ab74800f98684771.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=true 16 | loop_offset=0.0 17 | bpm=0.0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /Audio/Soundtrack/PassWordGame.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://bv5227ls5ejej" 6 | path="res://.godot/imported/PassWordGame.ogg-eacee10c4f27d0e98d2dc88980d6034b.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/Soundtrack/PassWordGame.ogg" 11 | dest_files=["res://.godot/imported/PassWordGame.ogg-eacee10c4f27d0e98d2dc88980d6034b.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=true 16 | loop_offset=0 17 | bpm=0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /Scripts/Objects/Enemies/BaseEnemy.gd: -------------------------------------------------------------------------------- 1 | class_name Enemy 2 | extends StaticBody2D 3 | 4 | @onready var health_component := $HealthComponent 5 | @onready var attack_component := $AttackComponent 6 | 7 | func _on_health_component_damaged(_amount: float, _hurt_time: float) -> void: 8 | # print("Oh no, I was damaged!!11 Nooo1oo!O") 9 | pass 10 | 11 | func _on_health_component_dead() -> void: 12 | # print("I'm dead :((((") 13 | queue_free() 14 | 15 | func start_destroy_sfx() -> void: 16 | Global.play_global_sfx("Explosion") 17 | -------------------------------------------------------------------------------- /Audio/SFX/Pause.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://bgfupmtntcg8x" 6 | path="res://.godot/imported/Pause.wav-3d7806228ce97ebe65778e1f12d7da16.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/Pause.wav" 11 | dest_files=["res://.godot/imported/Pause.wav-3d7806228ce97ebe65778e1f12d7da16.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Objects/AttackComponent.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://bi7wq6b7la5ki"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/Objects/AttackComponent.gd" id="1_kmts1"] 4 | 5 | [sub_resource type="RectangleShape2D" id="RectangleShape2D_rhc2x"] 6 | size = Vector2(24, 16) 7 | 8 | [node name="AttackComponent" type="Node2D"] 9 | script = ExtResource("1_kmts1") 10 | 11 | [node name="Area2D" type="Area2D" parent="."] 12 | collision_layer = 8 13 | collision_mask = 9 14 | 15 | [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] 16 | shape = SubResource("RectangleShape2D_rhc2x") 17 | -------------------------------------------------------------------------------- /Audio/SFX/Capsule.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://btqycedtut0o6" 6 | path="res://.godot/imported/Capsule.wav-86a1b228791c2330b43100434f8ee156.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/Capsule.wav" 11 | dest_files=["res://.godot/imported/Capsule.wav-86a1b228791c2330b43100434f8ee156.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Audio/SFX/LevelUp.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://clfqyu3fby0tv" 6 | path="res://.godot/imported/LevelUp.wav-8633942711d1fc4e4fcc7d04fe565438.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/LevelUp.wav" 11 | dest_files=["res://.godot/imported/LevelUp.wav-8633942711d1fc4e4fcc7d04fe565438.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Audio/SFX/MenuBip.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://bq6ov0bep762q" 6 | path="res://.godot/imported/MenuBip.wav-43b16ae437adfcf7cb9f3df1b6690f8c.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/MenuBip.wav" 11 | dest_files=["res://.godot/imported/MenuBip.wav-43b16ae437adfcf7cb9f3df1b6690f8c.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Scenes/Bosses/Mothra.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://df3jptqtpl75u"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://cin1i4pomwy3a" path="res://Scenes/Bosses/BaseBoss.tscn" id="1_vvhpb"] 4 | [ext_resource type="Script" path="res://Scripts/Levels/Bosses/Mothra.gd" id="2_rggxb"] 5 | [ext_resource type="AudioStream" uid="uid://by7wimbn2cemn" path="res://Audio/Soundtrack/MogueraTheme.ogg" id="3_ab880"] 6 | 7 | [node name="Boss" instance=ExtResource("1_vvhpb")] 8 | script = ExtResource("2_rggxb") 9 | music = ExtResource("3_ab880") 10 | 11 | [node name="Boss" parent="." index="3"] 12 | character = 1 13 | -------------------------------------------------------------------------------- /Audio/SFX/CharHurt.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://dcy2jbwfd2no" 6 | path="res://.godot/imported/CharHurt.wav-a2087980c8d01033eaa8f422279e4e79.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/CharHurt.wav" 11 | dest_files=["res://.godot/imported/CharHurt.wav-a2087980c8d01033eaa8f422279e4e79.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Audio/SFX/CharPunch.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://deo2ts4xdwwce" 6 | path="res://.godot/imported/CharPunch.wav-07b208a899bd855134c3ab73337c24d6.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/CharPunch.wav" 11 | dest_files=["res://.godot/imported/CharPunch.wav-07b208a899bd855134c3ab73337c24d6.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Audio/SFX/MothraRoar.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://ccjlv2riqxvf3" 6 | path="res://.godot/imported/MothraRoar.wav-fc087c31970aa2da354eceababde3043.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/MothraRoar.wav" 11 | dest_files=["res://.godot/imported/MothraRoar.wav-fc087c31970aa2da354eceababde3043.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Audio/SFX/MothraStep.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://d3q5gj1fhphte" 6 | path="res://.godot/imported/MothraStep.wav-b777a260d2b32e7ca3d0d014f83d0ad7.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/MothraStep.wav" 11 | dest_files=["res://.godot/imported/MothraStep.wav-b777a260d2b32e7ca3d0d014f83d0ad7.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Objects/Boards/Piece.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://cavxehselt3he"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://wmgv6kcqcri0" path="res://Sprites/BoardSprites.png" id="1_vlmlk"] 4 | [ext_resource type="Script" path="res://Scripts/Objects/Boards/Piece.gd" id="2_f5xfm"] 5 | 6 | [node name="Piece" type="Sprite2D"] 7 | position = Vector2(0, 9) 8 | texture = ExtResource("1_vlmlk") 9 | region_enabled = true 10 | region_rect = Rect2(0, 48, 48, 48) 11 | script = ExtResource("2_f5xfm") 12 | 13 | [node name="NavigationAgent2D" type="NavigationAgent2D" parent="."] 14 | path_postprocessing = 1 15 | avoidance_mask = 2 16 | -------------------------------------------------------------------------------- /Audio/SFX/GodzillaRoar.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://cjhiq2x7oewnw" 6 | path="res://.godot/imported/GodzillaRoar.wav-d9f13163667a5c84368b1f05bd7f704c.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/GodzillaRoar.wav" 11 | dest_files=["res://.godot/imported/GodzillaRoar.wav-d9f13163667a5c84368b1f05bd7f704c.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Audio/SFX/GodzillaStep.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://d2qfi7m3jxc5r" 6 | path="res://.godot/imported/GodzillaStep.wav-2d9b2817cca0cc1ada20d52d90fe18af.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/GodzillaStep.wav" 11 | dest_files=["res://.godot/imported/GodzillaStep.wav-2d9b2817cca0cc1ada20d52d90fe18af.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Audio/SFX/BlockDestruct.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://byy8g0bpfb65s" 6 | path="res://.godot/imported/BlockDestruct.wav-6e639a1e840566287ca1bded07f5e75b.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/BlockDestruct.wav" 11 | dest_files=["res://.godot/imported/BlockDestruct.wav-6e639a1e840566287ca1bded07f5e75b.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Audio/SFX/GodzillaHeatBeam.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamWAV" 5 | uid="uid://bnpu85disxvis" 6 | path="res://.godot/imported/GodzillaHeatBeam.wav-4e7ef5147f00863ddf739082a10c4952.sample" 7 | 8 | [deps] 9 | 10 | source_file="res://Audio/SFX/GodzillaHeatBeam.wav" 11 | dest_files=["res://.godot/imported/GodzillaHeatBeam.wav-4e7ef5147f00863ddf739082a10c4952.sample"] 12 | 13 | [params] 14 | 15 | force/8_bit=false 16 | force/mono=false 17 | force/max_rate=false 18 | force/max_rate_hz=44100 19 | edit/trim=false 20 | edit/normalize=false 21 | edit/loop_mode=0 22 | edit/loop_begin=0 23 | edit/loop_end=-1 24 | compress/mode=0 25 | -------------------------------------------------------------------------------- /Scripts/Objects/Characters/Dead.gd: -------------------------------------------------------------------------------- 1 | extends State 2 | 3 | const EXPLOSION := preload("res://Objects/Levels/Explosion.tscn") 4 | 5 | func state_entered() -> void: 6 | parent.collision_mask = 0 7 | parent.velocity = Vector2(0, 0.3 * 60) 8 | parent.animation_player.play("Hurt", -1, 0) 9 | if parent.is_flying(): 10 | parent.get_node("MothraFloorChecking").collision_mask = 0 11 | 12 | func _physics_process(_delta: float) -> void: 13 | if Engine.get_physics_frames() % 5 == 0: 14 | var explosion := EXPLOSION.instantiate() 15 | explosion.global_position = parent.global_position 16 | add_child(explosion) 17 | Global.play_global_sfx("Explosion") 18 | -------------------------------------------------------------------------------- /Scripts/Objects/State.gd: -------------------------------------------------------------------------------- 1 | class_name State 2 | extends Node 3 | 4 | @onready var parent: Node = $"../.." 5 | 6 | ## The method that is called when the player is ready 7 | func state_init() -> void: 8 | pass 9 | 10 | ## The method that is called when the state is enabled 11 | func state_entered() -> void: 12 | pass 13 | 14 | ## The method that is called when the state is disabled 15 | func state_exited() -> void: 16 | pass 17 | 18 | func enable() -> void: 19 | set_process(true) 20 | set_physics_process(true) 21 | set_process_input(true) 22 | 23 | func disable() -> void: 24 | set_process(false) 25 | set_physics_process(false) 26 | set_process_input(false) 27 | -------------------------------------------------------------------------------- /Objects/Levels/Sky.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://bliqsom52mx1p"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://c0ixfjb2bb5p5" path="res://Sprites/Levels/TestLevel/sky.png" id="1_ugp5p"] 4 | 5 | [sub_resource type="GDScript" id="GDScript_4hac0"] 6 | resource_name = "SkyScript" 7 | script/source = "extends TextureRect 8 | 9 | func _ready() -> void: 10 | var resolution_x := Global.get_content_size().x 11 | position.x = (resolution_x - size.x) / 2 12 | " 13 | 14 | [node name="Sky" type="TextureRect"] 15 | offset_top = 48.0 16 | offset_right = 427.0 17 | offset_bottom = 99.0 18 | texture = ExtResource("1_ugp5p") 19 | script = SubResource("GDScript_4hac0") 20 | -------------------------------------------------------------------------------- /Sprites/font1.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="font_data_image" 4 | type="FontFile" 5 | uid="uid://dycfyvuoxfwc0" 6 | path="res://.godot/imported/font1.png-7ba8dc092517dcd1d45e236242645b2c.fontdata" 7 | 8 | [deps] 9 | 10 | source_file="res://Sprites/font1.png" 11 | dest_files=["res://.godot/imported/font1.png-7ba8dc092517dcd1d45e236242645b2c.fontdata"] 12 | 13 | [params] 14 | 15 | character_ranges=PackedStringArray("\'A\'-\'Z\'", "\'0\'-\'9\'", "\'.\'", "\',\'", "\'\"\'", "45", "\'!\'", "\'?\'", "\':\'", "\' \'") 16 | kerning_pairs=PackedStringArray() 17 | columns=26 18 | rows=2 19 | image_margin=Rect2i(0, 0, 0, 0) 20 | character_margin=Rect2i(0, 0, 0, 0) 21 | ascent=0 22 | descent=0 23 | fallbacks=[] 24 | compress=true 25 | scaling_mode=0 26 | -------------------------------------------------------------------------------- /Sprites/font2.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="font_data_image" 4 | type="FontFile" 5 | uid="uid://b4bp7sni8u0il" 6 | path="res://.godot/imported/font2.png-f1d125a5fb9203891c5726870b343fb5.fontdata" 7 | 8 | [deps] 9 | 10 | source_file="res://Sprites/font2.png" 11 | dest_files=["res://.godot/imported/font2.png-f1d125a5fb9203891c5726870b343fb5.fontdata"] 12 | 13 | [params] 14 | 15 | character_ranges=PackedStringArray("\'A\'-\'Z\'", "\'0\'-\'9\'", "\'.\'", "\',\'", "\'\"\'", "45", "\'!\'", "\'?\'", "\':\'", "\' \'") 16 | kerning_pairs=PackedStringArray() 17 | columns=26 18 | rows=2 19 | image_margin=Rect2i(0, 0, 0, 0) 20 | character_margin=Rect2i(0, 0, 0, 0) 21 | ascent=0 22 | descent=0 23 | fallbacks=[] 24 | compress=true 25 | scaling_mode=0 26 | -------------------------------------------------------------------------------- /Sprites/GameIntro/font.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="font_data_image" 4 | type="FontFile" 5 | uid="uid://blhghnyq5sxle" 6 | path="res://.godot/imported/font.png-49a670995c1eaafcd8a312ee09ca9c3e.fontdata" 7 | 8 | [deps] 9 | 10 | source_file="res://Sprites/GameIntro/font.png" 11 | dest_files=["res://.godot/imported/font.png-49a670995c1eaafcd8a312ee09ca9c3e.fontdata"] 12 | 13 | [params] 14 | 15 | character_ranges=PackedStringArray("\'A\'-\'Z\'", "\'a\'-\'z\'", "\'.\'", "\'2\'", "\',\'", "\' \'", "\'!\'", "\':\'", "\'\"\'") 16 | kerning_pairs=PackedStringArray() 17 | columns=26 18 | rows=3 19 | image_margin=Rect2i(0, 0, 0, 0) 20 | character_margin=Rect2i(0, 0, 0, 0) 21 | ascent=0 22 | descent=0 23 | fallbacks=[] 24 | compress=true 25 | scaling_mode=2 26 | -------------------------------------------------------------------------------- /Scripts/Objects/Enemies/JetProjectile.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | const VELOCITY := Vector2(-1 * 60, 0.5 * 60) 4 | const EXPLOSION := preload("res://Objects/Levels/Explosion.tscn") 5 | 6 | @onready var destroy_sfx: AudioStreamPlayer = $DestroySFX 7 | @onready var attack_component: Node2D = $AttackComponent 8 | 9 | func _process(delta: float) -> void: 10 | position += VELOCITY * delta 11 | 12 | func _on_attack_component_attacked(_body: Node2D, _amount: float) -> void: 13 | var explosion := EXPLOSION.instantiate() 14 | explosion.global_position = global_position 15 | 16 | destroy_sfx.play() 17 | destroy_sfx.reparent(get_parent()) 18 | destroy_sfx.finished.connect(func() -> void: destroy_sfx.queue_free()) 19 | get_parent().add_child(explosion) 20 | queue_free() 21 | -------------------------------------------------------------------------------- /Other/Credits.txt: -------------------------------------------------------------------------------- 1 | GODOTZILLA CREDITS 2 | 3 | == 4 | 5 | [color=yellow]PROGRAMMER[/color] 6 | 7 | NINTORCH 8 | 9 | == 10 | 11 | [color=yellow]SPRITES[/color] 12 | 13 | COMPILE 14 | CIOSS 15 | 16 | == 17 | 18 | [color=yellow]MUSIC[/color] 19 | 20 | MASATOMO MIYAMOTO 21 | AKIRA IFUKUBE 22 | TOHO 23 | 24 | == 25 | 26 | [color=yellow]SPECIAL THANKS TO[/color] 27 | 28 | MADZILLAKOTH 29 | DINO 30 | Z9-LURKER 31 | 32 | == 33 | 34 | [color=yellow]ORIGINAL GAME BY[/color] 35 | 36 | COMPILE 37 | TOHO 38 | 39 | == 40 | 41 | GODZILLA AND RELATED 42 | CHARACTERS 43 | COPYRIGHT BY TOHO CO., LTD. 44 | 45 | == 46 | 47 | NINTENDO ENTERTAINMENT SYSTEM 48 | COPYRIGHT BY NINTENDO 49 | 50 | == 51 | 52 | MADE WITH 53 | [color=Deepskyblue]GODOT ENGINE[/color] 54 | 55 | THANK YOU FOR PLAYING 56 | -------------------------------------------------------------------------------- /Scenes/GameOver.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://chlit8t7aajq7"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/GameOver.gd" id="1_43hv7"] 4 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="1_u30ip"] 5 | 6 | [sub_resource type="LabelSettings" id="LabelSettings_1gnhd"] 7 | line_spacing = 0.0 8 | 9 | [node name="GameOver" type="Node2D"] 10 | script = ExtResource("1_43hv7") 11 | 12 | [node name="CharacterName" type="Label" parent="."] 13 | offset_left = 88.0 14 | offset_top = 112.0 15 | offset_right = 160.0 16 | offset_bottom = 120.0 17 | theme_override_fonts/font = ExtResource("1_u30ip") 18 | text = "game over" 19 | label_settings = SubResource("LabelSettings_1gnhd") 20 | horizontal_alignment = 1 21 | uppercase = true 22 | -------------------------------------------------------------------------------- /Scripts/Objects/PowerComponent.gd: -------------------------------------------------------------------------------- 1 | class_name PowerComponent 2 | extends Node 3 | 4 | @export var value := 10.0 5 | @export var max_value := 10.0 6 | ## Power restoration speed (points per second) 7 | @export var restore_speed := 3.0 8 | 9 | @onready var old_value := value 10 | 11 | signal value_changed(new_value: float) 12 | 13 | func _process(delta: float) -> void: 14 | value = minf(value + restore_speed * delta, max_value) 15 | if value != old_value: 16 | old_value = value 17 | value_changed.emit(value) 18 | 19 | func use(amount: float) -> void: 20 | if value < amount: 21 | return 22 | value = maxf(value - amount, 0) 23 | 24 | func add(amount: float) -> void: 25 | value = minf(value + amount, max_value) 26 | 27 | func set_empty() -> void: 28 | value = 0.0 29 | max_value = 0.0 30 | restore_speed = 0.0 31 | -------------------------------------------------------------------------------- /Scripts/GameOver.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | var finished := false 4 | 5 | # Called when the node enters the scene tree for the first time. 6 | func _ready() -> void: 7 | Global.play_music(load("res://Audio/Soundtrack/GameOver.ogg")) 8 | Global.fade_in() 9 | 10 | Global.music.finished.connect(finish) 11 | 12 | # The board hasn't been freed yet 13 | if is_instance_valid(Global.board): 14 | Global.board.queue_free() 15 | Global.board = null 16 | 17 | func _process(_delta: float) -> void: 18 | if Global.any_action_button_pressed(): 19 | finish() 20 | 21 | func finish() -> void: 22 | if not finished: 23 | finished = true 24 | 25 | set_process(false) 26 | await Global.fade_out() 27 | Global.hide_fade() 28 | 29 | Global.music.finished.disconnect(finish) 30 | Global.change_scene(Global.main.initial_scene) 31 | -------------------------------------------------------------------------------- /Scenes/MainMenu/BaseMenu.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://bjcf4tfdeo6ta"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/MainMenu/BaseMenu.gd" id="1_5lji1"] 4 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="2_2t3ak"] 5 | 6 | [node name="MainMenu" type="Node2D"] 7 | script = ExtResource("1_5lji1") 8 | 9 | [node name="Selector" type="ColorRect" parent="."] 10 | offset_right = 8.0 11 | offset_bottom = 8.0 12 | color = Color(0.709804, 0.192157, 0.12549, 1) 13 | 14 | [node name="MenuMain" type="Node2D" parent="." groups=["menu"]] 15 | unique_name_in_owner = true 16 | 17 | [node name="Exit" type="Label" parent="MenuMain" groups=["option"]] 18 | offset_left = 72.0 19 | offset_top = 176.0 20 | offset_right = 184.0 21 | offset_bottom = 187.0 22 | theme_override_fonts/font = ExtResource("2_2t3ak") 23 | text = "exit" 24 | uppercase = true 25 | -------------------------------------------------------------------------------- /Sprites/hudbar.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://cdqaohmcc1tj1" 6 | path="res://.godot/imported/hudbar.png-34485a2648c952469e69bd916abf151d.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/hudbar.png" 14 | dest_files=["res://.godot/imported/hudbar.png-34485a2648c952469e69bd916abf151d.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Scripts/Objects/StateMachine.gd: -------------------------------------------------------------------------------- 1 | class_name StateMachine 2 | extends Node 3 | 4 | @export var initial_state: Node = null 5 | @onready var states_list: Array[State] = [] 6 | var current := 0: set = _set_state 7 | 8 | func _ready() -> void: 9 | states_list.assign(get_children().filter(func(c: Node) -> bool: return c is State)) 10 | current = states_list.find(initial_state) 11 | 12 | func init() -> void: 13 | for i in states_list: 14 | i.state_init() 15 | if i == states_list[current]: 16 | i.enable() 17 | i.state_entered() 18 | else: 19 | i.disable() 20 | 21 | func _set_state(new_state: int) -> void: 22 | if current == new_state: 23 | return 24 | 25 | var old_state_node := states_list[current] 26 | var new_state_node := states_list[new_state] 27 | 28 | old_state_node.state_exited() 29 | old_state_node.disable() 30 | new_state_node.enable() 31 | new_state_node.state_entered() 32 | 33 | current = new_state 34 | -------------------------------------------------------------------------------- /Sprites/controller.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dewcb08w13bxc" 6 | path="res://.godot/imported/controller.png-cb0f9d41953f03d392065756984a0dc0.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/controller.png" 14 | dest_files=["res://.godot/imported/controller.png-cb0f9d41953f03d392065756984a0dc0.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/EditorBoard.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dhod63htftwaw" 6 | path="res://.godot/imported/EditorBoard.png-dacee69496e3ef6b098dc372742f0496.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/EditorBoard.png" 14 | dest_files=["res://.godot/imported/EditorBoard.png-dacee69496e3ef6b098dc372742f0496.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/GameIntro/images.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dffrjrny86uku" 6 | path="res://.godot/imported/images.png-11da698fd558a4471099d7954e5c522f.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/GameIntro/images.png" 14 | dest_files=["res://.godot/imported/images.png-11da698fd558a4471099d7954e5c522f.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/sky.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://c0ixfjb2bb5p5" 6 | path="res://.godot/imported/sky.png-6fa9fed3aecf543d09708603bc851470.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Levels/TestLevel/sky.png" 14 | dest_files=["res://.godot/imported/sky.png-6fa9fed3aecf543d09708603bc851470.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Objects/Enemies/Jet.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dh1lle66u4pmf" 6 | path="res://.godot/imported/Jet.png-e88239870ea78312d95b8ecdfed95da1.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Objects/Enemies/Jet.png" 14 | dest_files=["res://.godot/imported/Jet.png-e88239870ea78312d95b8ecdfed95da1.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/TitleScreen.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://b0k23sbm3154y" 6 | path="res://.godot/imported/TitleScreen.png-24beef99f237e0898945b362978ee38b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/TitleScreen.png" 14 | dest_files=["res://.godot/imported/TitleScreen.png-24beef99f237e0898945b362978ee38b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/BoardSprites.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://wmgv6kcqcri0" 6 | path="res://.godot/imported/BoardSprites.png-f1180c207df21e623735d36612cd116b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/BoardSprites.png" 14 | dest_files=["res://.godot/imported/BoardSprites.png-f1180c207df21e623735d36612cd116b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Mothra/hurt.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://nhpib3frkqrg" 6 | path="res://.godot/imported/hurt.png-0a054c817b88bf654cbe5a4b7b37b1d4.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Mothra/hurt.png" 14 | dest_files=["res://.godot/imported/hurt.png-0a054c817b88bf654cbe5a4b7b37b1d4.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/GameIntro/planets.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://d1n056ela541l" 6 | path="res://.godot/imported/planets.png-35098b769f43f9b9bc5f982c23698fa0.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/GameIntro/planets.png" 14 | dest_files=["res://.godot/imported/planets.png-35098b769f43f9b9bc5f982c23698fa0.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Levels/Jupiter/board.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://56livh2aqxw0" 6 | path="res://.godot/imported/board.png-6913aaf44e9b1cbc0bdaeaa5cdd7fecc.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Levels/Jupiter/board.png" 14 | dest_files=["res://.godot/imported/board.png-6913aaf44e9b1cbc0bdaeaa5cdd7fecc.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Levels/explosion.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dbjki3nsg35x8" 6 | path="res://.godot/imported/explosion.png-ecdfd164a470cb03d2e5d8d04ddd309b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Levels/explosion.png" 14 | dest_files=["res://.godot/imported/explosion.png-ecdfd164a470cb03d2e5d8d04ddd309b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Objects/capsules.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://c1n8vhgw5br0w" 6 | path="res://.godot/imported/capsules.png-df80143b8db2490c23f8b5228933661e.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Objects/capsules.png" 14 | dest_files=["res://.godot/imported/capsules.png-df80143b8db2490c23f8b5228933661e.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/PassWordGame.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://c5trtmb05sfr4" 6 | path="res://.godot/imported/PassWordGame.png-71e07406097ea0bf4e128e9c37edfa71.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/PassWordGame.png" 14 | dest_files=["res://.godot/imported/PassWordGame.png-71e07406097ea0bf4e128e9c37edfa71.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/hurt.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://c7slof73fr1l6" 6 | path="res://.godot/imported/hurt.png-bb8a54b715c5729045c868e12b3d18d0.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Godzilla/hurt.png" 14 | dest_files=["res://.godot/imported/hurt.png-bb8a54b715c5729045c868e12b3d18d0.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Mothra/idle.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dh0gtj20jut25" 6 | path="res://.godot/imported/idle.png-7270b492ef3455328a5c44731b5cebd7.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Mothra/idle.png" 14 | dest_files=["res://.godot/imported/idle.png-7270b492ef3455328a5c44731b5cebd7.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/board.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dxfvrtpci8esq" 6 | path="res://.godot/imported/board.png-1b78ed14a91707b6976a5222ab837d64.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Levels/TestLevel/board.png" 14 | dest_files=["res://.godot/imported/board.png-1b78ed14a91707b6976a5222ab837d64.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/floor.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://b2vt2myb2u4qi" 6 | path="res://.godot/imported/floor.png-1dbb95ce4a82eced2997d41da1ac2385.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Levels/TestLevel/floor.png" 14 | dest_files=["res://.godot/imported/floor.png-1dbb95ce4a82eced2997d41da1ac2385.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/hills.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://d3vfgcp31ia42" 6 | path="res://.godot/imported/hills.png-12509577c43ca9488df8043636b90dcc.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Levels/TestLevel/hills.png" 14 | dest_files=["res://.godot/imported/hills.png-12509577c43ca9488df8043636b90dcc.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/kick1.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dr7cjajoy0wya" 6 | path="res://.godot/imported/kick1.png-58f6f9aa3212060f1e68e39b3323bf74.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Godzilla/kick1.png" 14 | dest_files=["res://.godot/imported/kick1.png-58f6f9aa3212060f1e68e39b3323bf74.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/kick2.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://b3aqq06ew63k8" 6 | path="res://.godot/imported/kick2.png-2c2563d7aa1fe8c3366355d4e78b3675.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Godzilla/kick2.png" 14 | dest_files=["res://.godot/imported/kick2.png-2c2563d7aa1fe8c3366355d4e78b3675.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/GameIntro/earthships.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://jye2c33udbgd" 6 | path="res://.godot/imported/earthships.png-cf53685e889111a14ce97e9ed48f0e03.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/GameIntro/earthships.png" 14 | dest_files=["res://.godot/imported/earthships.png-cf53685e889111a14ce97e9ed48f0e03.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/GameIntro/gohtenjets.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bcglofsaynaai" 6 | path="res://.godot/imported/gohtenjets.png-edb3fa15eae08accb7e5c26eee2e1117.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/GameIntro/gohtenjets.png" 14 | dest_files=["res://.godot/imported/gohtenjets.png-edb3fa15eae08accb7e5c26eee2e1117.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Levels/PlanetIcons.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bwwv6hp8lqxa8" 6 | path="res://.godot/imported/PlanetIcons.png-ba0e03b6c4959278f34970f4b8c8cd39.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Levels/PlanetIcons.png" 14 | dest_files=["res://.godot/imported/PlanetIcons.png-ba0e03b6c4959278f34970f4b8c8cd39.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/crouch.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://c8vjp0lgjim3x" 6 | path="res://.godot/imported/crouch.png-8d4fc684931b0a179a38f5576bead0d9.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Godzilla/crouch.png" 14 | dest_files=["res://.godot/imported/crouch.png-8d4fc684931b0a179a38f5576bead0d9.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/punch1.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bhjsxj2v3ms7" 6 | path="res://.godot/imported/punch1.png-95112b2b3a4a5aaf1d4ea97728bca1d8.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Godzilla/punch1.png" 14 | dest_files=["res://.godot/imported/punch1.png-95112b2b3a4a5aaf1d4ea97728bca1d8.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/punch2.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://cp7yo85faut6q" 6 | path="res://.godot/imported/punch2.png-94741e296da6e224501922bf96d88523.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Godzilla/punch2.png" 14 | dest_files=["res://.godot/imported/punch2.png-94741e296da6e224501922bf96d88523.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/heat_beam.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bg00wrudw7pi5" 6 | path="res://.godot/imported/heat_beam.png-18076a605ad9b86195f32ad9d3266ea1.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Godzilla/heat_beam.png" 14 | dest_files=["res://.godot/imported/heat_beam.png-18076a605ad9b86195f32ad9d3266ea1.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/tail_whip.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bsu6rokyd5rmu" 6 | path="res://.godot/imported/tail_whip.png-0a88fa98ed00532b69bfc96ce7be9857.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Godzilla/tail_whip.png" 14 | dest_files=["res://.godot/imported/tail_whip.png-0a88fa98ed00532b69bfc96ce7be9857.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/walk_body.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://c3qwhre32yggp" 6 | path="res://.godot/imported/walk_body.png-3e1305563a6e7c4a097577e50722b24b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Godzilla/walk_body.png" 14 | dest_files=["res://.godot/imported/walk_body.png-3e1305563a6e7c4a097577e50722b24b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/walk_head.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://huytihc5bj4n" 6 | path="res://.godot/imported/walk_head.png-5d55bdd6e9f200e27e06ee291b0c6f02.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Godzilla/walk_head.png" 14 | dest_files=["res://.godot/imported/walk_head.png-5d55bdd6e9f200e27e06ee291b0c6f02.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Characters/Mothra/particles.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://di5yqmheu2g18" 6 | path="res://.godot/imported/particles.png-fa5b6cd1b1424269e52f6f29b58e2752.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Mothra/particles.png" 14 | dest_files=["res://.godot/imported/particles.png-fa5b6cd1b1424269e52f6f29b58e2752.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/YellowShip.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://vwe0hqe8bxv4" 6 | path="res://.godot/imported/YellowShip.png-2cfb91cfbaf3ab18f812385827aa8a2c.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Levels/TestLevel/YellowShip.png" 14 | dest_files=["res://.godot/imported/YellowShip.png-2cfb91cfbaf3ab18f812385827aa8a2c.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Scripts/GameIntro/SolarSystem.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | @onready var solar_system_object: Sprite2D = $Image 4 | @onready var planet_move_timer: Timer = $PlanetMoveTimer 5 | 6 | var solar_system_image: Image = preload("res://Sprites/GameIntro/images.png").get_image() 7 | var planets: Array[Node2D] = [] 8 | 9 | func _ready() -> void: 10 | planets.assign(get_children().filter(func(p: Node) -> bool: 11 | return p.name != "Image" and p is Sprite2D 12 | )) 13 | 14 | func move_planets() -> void: 15 | for planet in planets: 16 | planet.position.x += 1 17 | var image_pos: Vector2 = solar_system_object.to_local(planet.global_position) 18 | var color := solar_system_image.get_pixel(int(image_pos.x), int(image_pos.y)) 19 | if color.g > 0.0: 20 | continue 21 | if solar_system_image.get_pixel(int(image_pos.x), int(image_pos.y)-1).g > 0.0: 22 | planet.position.y -= 1 23 | elif solar_system_image.get_pixel(int(image_pos.x), int(image_pos.y)+1).g > 0.0: 24 | planet.position.y += 1 25 | -------------------------------------------------------------------------------- /Sprites/Characters/Godzilla/heat_beaming.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://drtem8jbie2f0" 6 | path="res://.godot/imported/heat_beaming.png-a2bfd64991f258ec5035c08fc4f0d126.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Characters/Godzilla/heat_beaming.png" 14 | dest_files=["res://.godot/imported/heat_beaming.png-a2bfd64991f258ec5035c08fc4f0d126.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Sprites/Objects/Enemies/RocketLauncher.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bc3bfeis78o8y" 6 | path="res://.godot/imported/RocketLauncher.png-abe1ab8b056c4b42c610e56a62754c4b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Objects/Enemies/RocketLauncher.png" 14 | dest_files=["res://.godot/imported/RocketLauncher.png-abe1ab8b056c4b42c610e56a62754c4b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Scenes/Levels/TransitionLevel.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=3 uid="uid://bdbahbhfgy3yt"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://jnprrhsi16ey" path="res://Scenes/Levels/BaseLevel.tscn" id="1_sxqx2"] 4 | [ext_resource type="AudioStream" uid="uid://bv5227ls5ejej" path="res://Audio/Soundtrack/PassWordGame.ogg" id="2_gkpwp"] 5 | 6 | [sub_resource type="Gradient" id="Gradient_v0rqx"] 7 | offsets = PackedFloat32Array(0.708154, 1) 8 | colors = PackedColorArray(0, 0, 0, 1, 0.344076, 0.344076, 0.344076, 1) 9 | 10 | [sub_resource type="GradientTexture2D" id="GradientTexture2D_kd1v6"] 11 | gradient = SubResource("Gradient_v0rqx") 12 | fill_from = Vector2(0, 1) 13 | fill_to = Vector2(0, 0) 14 | 15 | [node name="Level" instance=ExtResource("1_sxqx2")] 16 | music = ExtResource("2_gkpwp") 17 | right_boundary_behaviour = 2 18 | 19 | [node name="Camera" parent="." index="1"] 20 | limit_right = 260 21 | 22 | [node name="Floor" parent="." index="2"] 23 | texture = SubResource("GradientTexture2D_kd1v6") 24 | -------------------------------------------------------------------------------- /Sprites/Objects/Enemies/RocketLauncherRocket.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dnubo4iltw3px" 6 | path="res://.godot/imported/RocketLauncherRocket.png-b970d0bac6cf8dbe30bb8f58da5e80a3.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Objects/Enemies/RocketLauncherRocket.png" 14 | dest_files=["res://.godot/imported/RocketLauncherRocket.png-b970d0bac6cf8dbe30bb8f58da5e80a3.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /icon.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dkhpam3jsiqy2" 6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.svg" 14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | svg/scale=1.0 36 | editor/scale_with_editor_scale=false 37 | editor/convert_colors_with_editor_theme=false 38 | -------------------------------------------------------------------------------- /Sprites/Levels/TestLevel/GodzillaMoMWilderness.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://c1x100m2wxobm" 6 | path="res://.godot/imported/GodzillaMoMWilderness.png-a3fd224830a82c0bba7e56f959cdb5a8.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://Sprites/Levels/TestLevel/GodzillaMoMWilderness.png" 14 | dest_files=["res://.godot/imported/GodzillaMoMWilderness.png-a3fd224830a82c0bba7e56f959cdb5a8.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /Scripts/GameIntro/EarthInvasion.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | const SMALL_SHIPS_SPEED := 0.0625 * 60 4 | const BIG_SHIPS_SPEED := 0.125 * 60 5 | 6 | @onready var ships: Node2D = $Ships 7 | 8 | var small_ships: Array[Sprite2D] = [] 9 | var big_ships: Array[Sprite2D] = [] 10 | 11 | func _ready() -> void: 12 | small_ships.assign(ships.get_children().filter(func(node: Node) -> bool: 13 | return node is Sprite2D and node.name.begins_with("Small") 14 | )) 15 | big_ships.assign(ships.get_children().filter(func(node: Node) -> bool: 16 | return node is Sprite2D and node.name.begins_with("Big") 17 | )) 18 | 19 | func _process(delta: float) -> void: 20 | for ship in small_ships: 21 | move_ship(ship, SMALL_SHIPS_SPEED, delta) 22 | for ship in big_ships: 23 | move_ship(ship, BIG_SHIPS_SPEED, delta) 24 | 25 | func move_ship(ship: Sprite2D, speed: float, delta: float) -> void: 26 | ship.position.x -= speed * delta 27 | if (ship.position.x + ship.region_rect.size.x / 2) < 0: 28 | ship.position.x += 256 + ship.region_rect.size.x 29 | -------------------------------------------------------------------------------- /Scripts/Objects/Characters/Hurt.gd: -------------------------------------------------------------------------------- 1 | extends State 2 | 3 | @onready var timer := Timer.new() 4 | var hurt_time := 0.0 5 | var move_state: Node 6 | 7 | func state_init() -> void: 8 | move_state = parent.state.states_list[parent.move_state] 9 | timer.timeout.connect(_on_timeout) 10 | timer.one_shot = true 11 | add_child(timer) 12 | 13 | func state_entered() -> void: 14 | if parent.is_flying(): 15 | parent.velocity = Vector2() 16 | 17 | parent.animation_player.play("RESET") 18 | await get_tree().process_frame 19 | if parent.animation_player.has_animation("Hurt"): 20 | parent.animation_player.play("Hurt") 21 | 22 | # -1 if facing right and 1 if facing left 23 | parent.velocity.x = -parent.direction * parent.move_speed 24 | parent.get_sfx("Hurt").play() 25 | timer.start(hurt_time) 26 | 27 | func _on_timeout() -> void: 28 | # Might be called after the character died 29 | if parent.state.current != PlayerCharacter.State.HURT: 30 | return 31 | parent.animation_player.play("RESET") 32 | move_state.reset() 33 | parent.state.current = parent.move_state 34 | -------------------------------------------------------------------------------- /Scenes/Boards/Jupiter.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=3 uid="uid://slv0bn0tcyna"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://d2do8ilhab482" path="res://Scenes/Boards/BaseBoard.tscn" id="1_vt5a8"] 4 | [ext_resource type="AudioStream" uid="uid://dtdevd1wqdmom" path="res://Audio/Soundtrack/Mars.ogg" id="2_qojmy"] 5 | [ext_resource type="PackedScene" uid="uid://dhm8bcemuwqfo" path="res://Scenes/Levels/Wilderness.tscn" id="3_2e2no"] 6 | [ext_resource type="Texture2D" uid="uid://56livh2aqxw0" path="res://Sprites/Levels/Jupiter/board.png" id="4_ylq5q"] 7 | [ext_resource type="PackedScene" uid="uid://cavxehselt3he" path="res://Objects/Boards/Piece.tscn" id="5_kbvgg"] 8 | 9 | [node name="Board" instance=ExtResource("1_vt5a8")] 10 | board_name = "Jupiter" 11 | music = ExtResource("2_qojmy") 12 | tileset = ExtResource("4_ylq5q") 13 | board_id = "jupiter" 14 | levels = Array[PackedScene]([ExtResource("3_2e2no")]) 15 | 16 | [node name="Mothra" parent="Board/Board Icons/Board Pieces" index="1" instance=ExtResource("5_kbvgg")] 17 | position = Vector2(16, 56) 18 | region_rect = Rect2(0, 96, 48, 48) 19 | piece_character = 1 20 | -------------------------------------------------------------------------------- /Scripts/Objects/Enemies/YellowShip.gd: -------------------------------------------------------------------------------- 1 | extends "res://Scripts/Objects/Enemies/BaseEnemy.gd" 2 | 3 | const EXPLOSION := preload("res://Objects/Levels/Explosion.tscn") 4 | 5 | @onready var animation_player: AnimationPlayer = $AnimationPlayer 6 | 7 | var velocity := Vector2() 8 | 9 | func _process(_delta: float) -> void: 10 | var camera := get_viewport().get_camera_2d() 11 | if camera == null: 12 | return 13 | 14 | if velocity.y == 0.0 and global_position.x < \ 15 | camera.get_screen_center_position().x + Global.get_content_size().x / 2 + 20: 16 | velocity = Vector2(-120, -90) 17 | animation_player.play("main") 18 | elif velocity.y == -90.0 and global_position.x < camera.get_screen_center_position().x + 60: 19 | velocity.y = -60.0 20 | 21 | func _physics_process(delta: float) -> void: 22 | position += velocity * delta 23 | 24 | func _on_health_component_dead() -> void: 25 | velocity.x = -velocity.x 26 | 27 | func _on_attack_component_attacked(_body: Node2D, _amount: float) -> void: 28 | var explosion := EXPLOSION.instantiate() 29 | explosion.global_position = global_position 30 | get_parent().add_child(explosion) 31 | queue_free() 32 | -------------------------------------------------------------------------------- /Objects/Levels/Enemies/BaseEnemy.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=3 uid="uid://bvoxqi1x6lk52"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://camascwoory5h" path="res://Objects/HealthComponent.tscn" id="1_cy6fi"] 4 | [ext_resource type="Script" path="res://Scripts/Objects/Enemies/BaseEnemy.gd" id="1_sr5re"] 5 | [ext_resource type="PackedScene" uid="uid://bi7wq6b7la5ki" path="res://Objects/AttackComponent.tscn" id="2_ma02d"] 6 | 7 | [sub_resource type="RectangleShape2D" id="RectangleShape2D_mvstq"] 8 | size = Vector2(20, 10) 9 | 10 | [node name="Enemy" type="StaticBody2D"] 11 | script = ExtResource("1_sr5re") 12 | 13 | [node name="HealthComponent" parent="." instance=ExtResource("1_cy6fi")] 14 | max_value = 6.0 15 | enemy = true 16 | 17 | [node name="AttackComponent" parent="." instance=ExtResource("2_ma02d")] 18 | enemy = true 19 | 20 | [node name="CollisionShape2D" type="CollisionShape2D" parent="."] 21 | shape = SubResource("RectangleShape2D_mvstq") 22 | 23 | [connection signal="damaged" from="HealthComponent" to="." method="_on_health_component_damaged"] 24 | [connection signal="dead" from="HealthComponent" to="." method="_on_health_component_dead"] 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Nintorch 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Objects/Levels/Floor.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://cx8rkmxhgw3oc"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://b2vt2myb2u4qi" path="res://Sprites/Levels/TestLevel/floor.png" id="1_fk1m6"] 4 | 5 | [sub_resource type="GDScript" id="GDScript_jtqjn"] 6 | script/source = "extends TextureRect 7 | 8 | @export var width_before_0 := 50 9 | 10 | func _ready() -> void: 11 | var width: float = get_parent().get_node(\"Camera\").limit_right + width_before_0 12 | size.x = width 13 | $StaticBody2D/CollisionShape2D.shape.size.x = width + width_before_0 * 2 14 | $StaticBody2D/CollisionShape2D.position.x = width / 2 - width_before_0 15 | " 16 | 17 | [sub_resource type="RectangleShape2D" id="RectangleShape2D_ajba1"] 18 | size = Vector2(200, 32) 19 | 20 | [node name="Floor" type="TextureRect"] 21 | offset_right = 100.0 22 | offset_bottom = 32.0 23 | texture = ExtResource("1_fk1m6") 24 | stretch_mode = 1 25 | script = SubResource("GDScript_jtqjn") 26 | 27 | [node name="StaticBody2D" type="StaticBody2D" parent="."] 28 | position = Vector2(0, -200) 29 | collision_layer = 2 30 | 31 | [node name="CollisionShape2D" type="CollisionShape2D" parent="StaticBody2D"] 32 | position = Vector2(0, 216) 33 | shape = SubResource("RectangleShape2D_ajba1") 34 | -------------------------------------------------------------------------------- /Scripts/Objects/Levels/TestLevel/BreakableMountain.gd: -------------------------------------------------------------------------------- 1 | extends StaticBody2D 2 | 3 | @export_enum("Top and bottom", "Top only", "Bottom only") var type := 0 4 | @onready var top_part: StaticBody2D = $TopPart 5 | @onready var bottom_part: StaticBody2D = $BottomPart 6 | 7 | func _ready() -> void: 8 | match type: 9 | 1: bottom_part.queue_free() 10 | 2: top_part.queue_free() 11 | 12 | func _process(_delta: float) -> void: 13 | if not is_instance_valid(top_part) and not is_instance_valid(bottom_part): 14 | queue_free() 15 | 16 | func _on_top_health_damaged(_amount: float, _hurt_time: float) -> void: 17 | var top_sprite := $TopPart/Sprite 18 | top_sprite.region_rect.position.x = 439 19 | top_sprite.region_rect.position.y = 21 20 | play_sfx() 21 | 22 | func _on_bottom_health_damaged(_amount: float, _hurt_time: float) -> void: 23 | $BottomPart/Sprite.region_rect.position.x = 429 24 | play_sfx() 25 | 26 | func _on_top_health_dead() -> void: 27 | top_part.queue_free() 28 | Global.player.add_xp(10) 29 | Global.add_score(100) 30 | 31 | func _on_bottom_health_dead() -> void: 32 | bottom_part.queue_free() 33 | Global.player.add_xp(10) 34 | Global.add_score(100) 35 | 36 | func play_sfx() -> void: 37 | Global.play_global_sfx("BlockDestruct") 38 | -------------------------------------------------------------------------------- /Scenes/MainMenu/VideoSettings.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://bxtvwweer7x10"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/MainMenu/VideoSettings.gd" id="1_kbbau"] 4 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="2_4grkj"] 5 | 6 | [node name="VideoSettings" type="Node2D" groups=["menu"]] 7 | script = ExtResource("1_kbbau") 8 | 9 | [node name="Resolution" type="Label" parent="." groups=["option"]] 10 | offset_left = 72.0 11 | offset_top = 80.0 12 | offset_right = 184.0 13 | offset_bottom = 91.0 14 | theme_override_fonts/font = ExtResource("2_4grkj") 15 | text = "resolution: x1" 16 | uppercase = true 17 | 18 | [node name="Widescreen" type="Label" parent="." groups=["option"]] 19 | offset_left = 72.0 20 | offset_top = 104.0 21 | offset_right = 200.0 22 | offset_bottom = 115.0 23 | theme_override_fonts/font = ExtResource("2_4grkj") 24 | text = "wide screen: off" 25 | uppercase = true 26 | metadata/_edit_use_anchors_ = true 27 | 28 | [node name="Exit" type="Label" parent="." groups=["option"]] 29 | offset_left = 72.0 30 | offset_top = 128.0 31 | offset_right = 184.0 32 | offset_bottom = 139.0 33 | theme_override_fonts/font = ExtResource("2_4grkj") 34 | text = "exit" 35 | uppercase = true 36 | metadata/_edit_use_anchors_ = true 37 | -------------------------------------------------------------------------------- /Scenes/Bosses/BaseBoss.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://cin1i4pomwy3a"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://jnprrhsi16ey" path="res://Scenes/Levels/BaseLevel.tscn" id="1_ohey1"] 4 | [ext_resource type="PackedScene" uid="uid://bdedrxocj46sr" path="res://Objects/Characters/PlayerCharacter.tscn" id="2_atw37"] 5 | [ext_resource type="Script" path="res://Scripts/Levels/Bosses/BaseBoss.gd" id="2_xih6l"] 6 | 7 | [node name="Boss" instance=ExtResource("1_ohey1")] 8 | script = ExtResource("2_xih6l") 9 | xp_amount = 100 10 | score_amount = 110000 11 | right_boundary_behaviour = 0 12 | 13 | [node name="Camera" parent="." index="1"] 14 | limit_right = 256 15 | 16 | [node name="Floor" parent="." index="2"] 17 | offset_top = 216.0 18 | offset_bottom = 249.0 19 | texture = null 20 | 21 | [node name="Boss" parent="." index="3" instance=ExtResource("2_atw37")] 22 | position = Vector2(196, 189) 23 | is_player = false 24 | enable_intro = false 25 | direction = -1 26 | 27 | [node name="Player" parent="." index="4"] 28 | position = Vector2(39, 189) 29 | 30 | [node name="HUD" parent="." index="5" node_paths=PackedStringArray("boss")] 31 | boss = NodePath("../Boss") 32 | boss_bar_color = Color(0, 0.486275, 0.552941, 1) 33 | 34 | [connection signal="boss_timer_timeout" from="HUD" to="." method="_on_hud_boss_timer_timeout"] 35 | -------------------------------------------------------------------------------- /Scripts/Objects/Characters/GodzillaHeatBeam.gd: -------------------------------------------------------------------------------- 1 | extends AnimatedSprite2D 2 | 3 | @onready var flash_timer := $FlashTimer 4 | @onready var destroy_timer := $DestroyTimer 5 | @onready var attack: Node2D = $AttackComponent 6 | 7 | var player: PlayerCharacter 8 | var id := 0 9 | var particle_array: Array[AnimatedSprite2D] 10 | 11 | func setup(init_id: int, init_player: PlayerCharacter) -> void: 12 | frame = init_id 13 | id = init_id 14 | visible = false 15 | player = init_player 16 | 17 | func _ready() -> void: 18 | attack.objects_to_ignore.append(player) 19 | attack.set_collision(Vector2(8, 4 * (id+1)), Vector2(0, 2 * (id+1) - 48/2 + 1)) 20 | attack.enemy = player.attack.enemy 21 | 22 | func start() -> void: 23 | visible = true 24 | destroy_timer.start() 25 | 26 | func _physics_process(_delta: float) -> void: 27 | position.y = player.save_position[id].y - id - player.position.y 28 | 29 | func _on_timer_timeout() -> void: 30 | if animation == "default": 31 | animation = "highlight" 32 | else: 33 | animation = "default" 34 | frame = id 35 | 36 | func _on_destroy_timer_timeout() -> void: 37 | queue_free() 38 | 39 | func _on_attack_component_attacked(body: Node2D, _amount: float) -> void: 40 | for particle in particle_array: 41 | if is_instance_valid(particle): 42 | particle.attack.objects_to_ignore.append(body) 43 | -------------------------------------------------------------------------------- /Scripts/Objects/Capsule.gd: -------------------------------------------------------------------------------- 1 | extends Sprite2D 2 | 3 | @onready var sfx: AudioStreamPlayer = $SFX 4 | @onready var animation_player: AnimationPlayer = $AnimationPlayer 5 | @onready var area_2d: Area2D = $Area2D 6 | @onready var timer: Timer = $Timer 7 | 8 | var velocity: float = 1.3 * 60 9 | var direction := 1 10 | 11 | func initialize(globalPosition: Vector2, type: String) -> Node2D: 12 | self.global_position = globalPosition 13 | animation_player.play(type) 14 | return self 15 | 16 | func _process(delta: float) -> void: 17 | var camera := get_viewport().get_camera_2d() 18 | if camera != null and direction > 0 and (global_position.x + 4) > camera.limit_right: 19 | direction = -1 20 | 21 | position.x += velocity * direction * delta 22 | 23 | func _on_timer_timeout() -> void: 24 | velocity = 0.3 * 60 25 | for body in area_2d.get_overlapping_bodies(): 26 | _on_area_2d_body_entered(body) 27 | 28 | func _on_area_2d_body_entered(body: Node2D) -> void: 29 | if not timer.is_stopped(): 30 | return 31 | 32 | if body is PlayerCharacter: 33 | destroy(body) 34 | 35 | func destroy(character: PlayerCharacter) -> void: 36 | visible = false 37 | area_2d.queue_free() 38 | sfx.play() 39 | sfx.finished.connect(queue_free) 40 | 41 | match animation_player.current_animation: 42 | "health": character.health.heal(2 * 8) 43 | "power": character.power.add(2 * 8) 44 | -------------------------------------------------------------------------------- /Scripts/Levels/Camera.gd: -------------------------------------------------------------------------------- 1 | extends Camera2D 2 | 3 | enum CameraMode { 4 | NORMAL, 5 | TWO_SIDES, 6 | } 7 | 8 | @export var camera_offset_x := 30 9 | @export var target: Node2D 10 | @export var camera_mode := CameraMode.NORMAL 11 | 12 | @onready var window_width_half := Global.get_content_size().x / 2 13 | 14 | var camera_x_old: float 15 | var camera_current_offset := 0 16 | 17 | func _process(_delta: float) -> void: 18 | camera_x_old = get_screen_center_position().x 19 | position.y = target.position.y 20 | match camera_mode: 21 | # The default camera mode, the one from the original game 22 | CameraMode.NORMAL: 23 | if position.x < target.position.x + camera_offset_x \ 24 | and position.x < limit_right - window_width_half: 25 | position.x = clampf(target.position.x + camera_offset_x, 26 | window_width_half, limit_right - window_width_half) 27 | limit_left = max(position.x - window_width_half, 0) 28 | 29 | # The camera can move in both sides 30 | CameraMode.TWO_SIDES: 31 | var direction: int = target.direction if "direction" in target else 1 32 | camera_current_offset = roundi(move_toward( 33 | camera_current_offset, 34 | camera_offset_x * target.direction, 35 | 2 36 | )) 37 | position.x = target.position.x + camera_current_offset 38 | 39 | func is_camera_moving() -> bool: 40 | return camera_x_old != get_screen_center_position().x 41 | -------------------------------------------------------------------------------- /Objects/Levels/Enemies/JetProjectile.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=3 uid="uid://ctvc76vle1gei"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://dh1lle66u4pmf" path="res://Sprites/Objects/Enemies/Jet.png" id="1_654l8"] 4 | [ext_resource type="Script" path="res://Scripts/Objects/Enemies/JetProjectile.gd" id="1_fygt2"] 5 | [ext_resource type="PackedScene" uid="uid://bi7wq6b7la5ki" path="res://Objects/AttackComponent.tscn" id="2_373u2"] 6 | [ext_resource type="AudioStream" uid="uid://dcy2jbwfd2no" path="res://Audio/SFX/CharHurt.wav" id="4_h0tpx"] 7 | 8 | [sub_resource type="RectangleShape2D" id="RectangleShape2D_rgpnx"] 9 | size = Vector2(8, 8) 10 | 11 | [node name="JetProjectile" type="Node2D"] 12 | script = ExtResource("1_fygt2") 13 | 14 | [node name="Jet" type="Sprite2D" parent="."] 15 | texture = ExtResource("1_654l8") 16 | region_enabled = true 17 | region_rect = Rect2(78, 0, 8, 2) 18 | 19 | [node name="AttackComponent" parent="." instance=ExtResource("2_373u2")] 20 | enemy = true 21 | 22 | [node name="CollisionShape2D" parent="AttackComponent/Area2D" index="0"] 23 | shape = SubResource("RectangleShape2D_rgpnx") 24 | 25 | [node name="DestroySFX" type="AudioStreamPlayer" parent="."] 26 | stream = ExtResource("4_h0tpx") 27 | bus = &"SFX" 28 | 29 | [connection signal="attacked" from="AttackComponent" to="." method="_on_attack_component_attacked"] 30 | 31 | [editable path="AttackComponent"] 32 | -------------------------------------------------------------------------------- /Scenes/Levels/BaseLevel.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=3 uid="uid://jnprrhsi16ey"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/Levels/Level.gd" id="1_kceot"] 4 | [ext_resource type="Script" path="res://Scripts/Levels/Camera.gd" id="2_utxvs"] 5 | [ext_resource type="PackedScene" uid="uid://bono4mu6juvo8" path="res://Objects/Levels/HUD.tscn" id="4_cq3ox"] 6 | [ext_resource type="PackedScene" uid="uid://cx8rkmxhgw3oc" path="res://Objects/Levels/Floor.tscn" id="4_tmjpl"] 7 | [ext_resource type="PackedScene" uid="uid://bdedrxocj46sr" path="res://Objects/Characters/PlayerCharacter.tscn" id="5_vpd3j"] 8 | 9 | [node name="Level" type="Node2D"] 10 | script = ExtResource("1_kceot") 11 | 12 | [node name="Background" type="Node2D" parent="."] 13 | 14 | [node name="Camera" type="Camera2D" parent="." node_paths=PackedStringArray("target")] 15 | position = Vector2(56, 120) 16 | limit_left = 0 17 | limit_top = 0 18 | limit_right = 500 19 | limit_bottom = 240 20 | script = ExtResource("2_utxvs") 21 | target = NodePath("../Player") 22 | 23 | [node name="Floor" parent="." instance=ExtResource("4_tmjpl")] 24 | offset_top = 208.0 25 | offset_bottom = 240.0 26 | 27 | [node name="Player" parent="." instance=ExtResource("5_vpd3j")] 28 | position = Vector2(53, 181) 29 | 30 | [node name="HUD" parent="." node_paths=PackedStringArray("player") instance=ExtResource("4_cq3ox")] 31 | player = NodePath("../Player") 32 | -------------------------------------------------------------------------------- /Scenes/MainMenu/SoundSettings.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://dk6nkw1ue84ow"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/MainMenu/SoundSettings.gd" id="1_pspne"] 4 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="2_fls7i"] 5 | [ext_resource type="AudioStream" uid="uid://bq6ov0bep762q" path="res://Audio/SFX/MenuBip.wav" id="3_akdro"] 6 | 7 | [node name="SoundSettings" type="Node2D" groups=["menu"]] 8 | script = ExtResource("1_pspne") 9 | 10 | [node name="SFXVolume" type="Label" parent="." groups=["option"]] 11 | offset_left = 72.0 12 | offset_top = 80.0 13 | offset_right = 184.0 14 | offset_bottom = 91.0 15 | theme_override_fonts/font = ExtResource("2_fls7i") 16 | text = "sfx volume: 100" 17 | uppercase = true 18 | 19 | [node name="MusicVolume" type="Label" parent="." groups=["option"]] 20 | offset_left = 72.0 21 | offset_top = 104.0 22 | offset_right = 208.0 23 | offset_bottom = 115.0 24 | theme_override_fonts/font = ExtResource("2_fls7i") 25 | text = "music volume: 100" 26 | uppercase = true 27 | 28 | [node name="Exit" type="Label" parent="." groups=["option"]] 29 | offset_left = 72.0 30 | offset_top = 128.0 31 | offset_right = 184.0 32 | offset_bottom = 139.0 33 | theme_override_fonts/font = ExtResource("2_fls7i") 34 | text = "exit" 35 | uppercase = true 36 | 37 | [node name="SFXTest" type="AudioStreamPlayer" parent="."] 38 | stream = ExtResource("3_akdro") 39 | -------------------------------------------------------------------------------- /Scripts/TitleScreen.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | func _ready() -> void: 4 | RenderingServer.set_default_clear_color(Color.BLACK) 5 | Global.play_music(preload("res://Audio/Soundtrack/TitleScreen.ogg")) 6 | 7 | $BeforeFlash.visible = true 8 | $AfterFlash.visible = false 9 | 10 | if Global.is_widescreen(): 11 | var color_rects: Array[ColorRect] = \ 12 | [$BeforeFlash/ColorRect, $AfterFlash/ColorRect2] 13 | for cr in color_rects: 14 | cr.size.x = Global.get_content_size().x 15 | cr.position.x = \ 16 | -(Global.get_content_size().x - Global.get_default_resolution().x) / 2 17 | 18 | func _process(_delta: float) -> void: 19 | if Global.any_action_button_pressed(): 20 | if not $AfterFlash.visible: 21 | do_flash() 22 | else: 23 | leave() 24 | 25 | func _on_flash_timer_timeout() -> void: 26 | do_flash() 27 | 28 | func do_flash() -> void: 29 | if not $AfterFlash.visible and not Global.is_fading(): 30 | await Global.fade_out(Global.FadeColor.WHITE) 31 | 32 | $BeforeFlash.visible = false 33 | $AfterFlash.visible = true 34 | Global.fade_in(Global.FadeColor.WHITE) 35 | 36 | func leave() -> void: 37 | if not Global.is_fading(): 38 | get_tree().paused = true 39 | 40 | Global.music_fade_out() 41 | await Global.fade_out(Global.FadeColor.BLACK) 42 | 43 | await get_tree().create_timer(0.5).timeout 44 | 45 | get_tree().paused = false 46 | Global.change_scene(preload("res://Scenes/MainMenu/MainMenu.tscn")) 47 | -------------------------------------------------------------------------------- /Scripts/Objects/Enemies/RocketLauncherRocket.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | const LAUNCH_HEIGHT := 30 4 | const EXPLOSION := preload("res://Objects/Levels/Explosion.tscn") 5 | 6 | @onready var attack_component: Node2D = $AttackComponent 7 | @onready var animation_player: AnimationPlayer = $AnimationPlayer 8 | @onready var destroy_sfx: AudioStreamPlayer = $DestroySFX 9 | 10 | var velocity := Vector2(-0.5 * 60, -4 * 60) 11 | var initial_position := Vector2() 12 | 13 | func _ready() -> void: 14 | initial_position = Vector2(position) 15 | 16 | func _process(delta: float) -> void: 17 | if position.y < initial_position.y - LAUNCH_HEIGHT: 18 | if animation_player.current_animation != "going_down": 19 | animation_player.play("going_down") 20 | velocity.x -= 0.01 * 60 * 60 * delta 21 | velocity.y += 0.1 * 60 * 60 * delta 22 | position += velocity * delta 23 | 24 | var camera := get_viewport().get_camera_2d() 25 | var limit := Global.get_content_size().y + 64.0 26 | if camera != null: 27 | limit += camera.get_screen_center_position().y 28 | if position.y > limit: 29 | queue_free() 30 | 31 | func _on_attack_component_attacked(_body: Node2D, _amount: float) -> void: 32 | var explosion := EXPLOSION.instantiate() 33 | explosion.global_position = global_position 34 | get_parent().add_child(explosion) 35 | destroy_sfx.play() 36 | destroy_sfx.reparent(get_parent()) 37 | destroy_sfx.finished.connect(func() -> void: destroy_sfx.queue_free()) 38 | queue_free() 39 | -------------------------------------------------------------------------------- /Objects/Bar.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://nbd34bkxryjd"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://cdqaohmcc1tj1" path="res://Sprites/hudbar.png" id="1_b8jd6"] 4 | [ext_resource type="Script" path="res://Scripts/Objects/Bar.gd" id="1_f4ary"] 5 | 6 | [node name="Bar" type="Control"] 7 | layout_mode = 3 8 | anchors_preset = 0 9 | offset_right = 80.0 10 | offset_bottom = 8.0 11 | scale = Vector2(0.992631, 1) 12 | script = ExtResource("1_f4ary") 13 | 14 | [node name="Style1" type="Control" parent="." groups=["bar_style"]] 15 | anchors_preset = 0 16 | offset_right = 81.0 17 | offset_bottom = 8.0 18 | 19 | [node name="RedBar" type="ColorRect" parent="Style1"] 20 | layout_mode = 0 21 | offset_top = 2.0 22 | offset_right = 8.0 23 | offset_bottom = 5.0 24 | color = Color(0.71, 0.19, 0.125, 1) 25 | 26 | [node name="BarsOutline" type="TextureRect" parent="Style1"] 27 | layout_mode = 0 28 | offset_right = 9.0 29 | offset_bottom = 8.0 30 | texture = ExtResource("1_b8jd6") 31 | stretch_mode = 1 32 | 33 | [node name="Style2" type="Control" parent="." groups=["bar_style"]] 34 | visible = false 35 | anchors_preset = 0 36 | offset_right = 80.0 37 | offset_bottom = 8.0 38 | 39 | [node name="BarBG" type="ColorRect" parent="Style2"] 40 | layout_mode = 0 41 | offset_top = 1.0 42 | offset_right = 80.0 43 | offset_bottom = 6.0 44 | 45 | [node name="BarColor" type="ColorRect" parent="Style2"] 46 | layout_mode = 0 47 | offset_top = 1.0 48 | offset_right = 80.0 49 | offset_bottom = 6.0 50 | color = Color(0.71, 0.19, 0.125, 1) 51 | -------------------------------------------------------------------------------- /Scenes/Credits.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://cqlhofm4kl4y"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/Credits.gd" id="1_21yi6"] 4 | [ext_resource type="AudioStream" uid="uid://bw2ac1eh6npco" path="res://Audio/Soundtrack/Credits.ogg" id="2_knkbt"] 5 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="2_vqk51"] 6 | 7 | [node name="Credits" type="Node2D"] 8 | script = ExtResource("1_21yi6") 9 | music = ExtResource("2_knkbt") 10 | 11 | [node name="CenterContainer" type="CenterContainer" parent="."] 12 | offset_right = 128.0 13 | offset_bottom = 128.0 14 | 15 | [node name="TextNode" type="RichTextLabel" parent="CenterContainer"] 16 | layout_mode = 2 17 | theme_override_fonts/normal_font = ExtResource("2_vqk51") 18 | bbcode_enabled = true 19 | text = "[color=yellow]HELLO WORLD" 20 | fit_content = true 21 | autowrap_mode = 0 22 | 23 | [node name="Licensing" type="Label" parent="."] 24 | offset_left = 8.0 25 | offset_right = 248.0 26 | offset_bottom = 240.0 27 | theme_override_font_sizes/font_size = 10 28 | text = "Licensing text here" 29 | autowrap_mode = 2 30 | 31 | [node name="ColorRect" type="ColorRect" parent="."] 32 | offset_top = 208.0 33 | offset_right = 256.0 34 | offset_bottom = 240.0 35 | color = Color(0, 0, 0, 1) 36 | 37 | [node name="Continue" type="Label" parent="."] 38 | offset_left = 24.0 39 | offset_top = 216.0 40 | offset_right = 224.0 41 | offset_bottom = 226.0 42 | theme_override_fonts/font = ExtResource("2_vqk51") 43 | text = "PRESS ANY KEY TO CONTINUE" 44 | -------------------------------------------------------------------------------- /Scripts/Objects/Characters/LevelIntro.gd: -------------------------------------------------------------------------------- 1 | extends State 2 | 3 | var move_state: Node 4 | var sfx_step: AudioStreamPlayer 5 | var sfx_roar: AudioStreamPlayer 6 | 7 | const CHARACTER_PARAMS := [ 8 | { 9 | step_sfx_period = 30, 10 | step_sfx_start = 15, 11 | step_sfx_offset = 10, 12 | target_x = 64, 13 | }, 14 | { 15 | step_sfx_period = 15, 16 | step_sfx_start = 20, 17 | step_sfx_offset = 0, 18 | target_x = 80, 19 | }, 20 | ] 21 | 22 | var current_params: Dictionary 23 | 24 | func state_init() -> void: 25 | sfx_step = parent.get_sfx("Step") 26 | sfx_roar = parent.get_sfx("Roar") 27 | move_state = parent.state.states_list[parent.move_state] 28 | current_params = CHARACTER_PARAMS[parent.character] 29 | 30 | func _physics_process(delta: float) -> void: 31 | parent.velocity.x = parent.move_speed 32 | 33 | if not parent.is_flying(): 34 | move_state.walk_frame = wrapf( 35 | move_state.walk_frame + move_state.walk_frame_speed * delta, 36 | 0, move_state.walk_frames) 37 | parent.body.frame = int(move_state.walk_frame) 38 | 39 | if not Global.music.playing: 40 | if Engine.get_physics_frames() >= current_params.step_sfx_start \ 41 | and Engine.get_physics_frames() % current_params.step_sfx_period \ 42 | == current_params.step_sfx_offset: 43 | sfx_step.play() 44 | 45 | if parent.position.x > current_params.target_x: 46 | parent.state.current = parent.move_state 47 | parent.velocity = Vector2(0,0) 48 | move_state.reset() 49 | parent.body.frame = 0 50 | if not Global.music.playing: 51 | sfx_roar.play() 52 | parent.intro_ended.emit() 53 | -------------------------------------------------------------------------------- /Scripts/PauseManager.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | const PAUSE_MENU := preload("res://Scenes/MainMenu/PauseMenu.tscn") 4 | 5 | var previous_scene: Node 6 | 7 | signal pause_finished 8 | 9 | func accept_pause() -> void: 10 | if not Global.is_fading() and Input.is_action_just_pressed("Select"): 11 | start_pause() 12 | 13 | func start_pause() -> void: 14 | previous_scene = Global.get_current_scene() 15 | # Change to pause menu scene but don't free the previous one 16 | Global.change_scene(PAUSE_MENU, false) 17 | # Position the current pause menu on the center of the screen 18 | Global.get_current_scene().position.x = \ 19 | (Global.get_content_size().x - Global.get_default_resolution().x) / 2 20 | get_tree().paused = true 21 | 22 | Global.music.stream_paused = true 23 | Global.play_global_sfx("Pause") 24 | 25 | func finish_pause() -> void: 26 | var current_pause_menu := Global.get_current_scene() 27 | # Don't free the pause menu yet, we will free it later below 28 | Global.change_scene_node(previous_scene, false) 29 | previous_scene = null 30 | get_tree().paused = false 31 | 32 | pause_finished.emit() 33 | 34 | await Global.play_global_sfx("Pause").finished 35 | 36 | # Don't resume the music if the player was fast enough 37 | # to pause again before sfx.finished above fired and 38 | # they're on pause menu again 39 | if previous_scene == null: 40 | Global.music.stream_paused = false 41 | 42 | current_pause_menu.queue_free() 43 | 44 | func prepare_for_exit() -> void: 45 | if is_instance_valid(Global.board): 46 | Global.board.queue_free() 47 | if is_instance_valid(previous_scene): 48 | previous_scene.queue_free() 49 | -------------------------------------------------------------------------------- /Scripts/Objects/Enemies/RocketLauncher.gd: -------------------------------------------------------------------------------- 1 | extends "res://Scripts/Objects/Enemies/BaseEnemy.gd" 2 | 3 | const ROCKET_LAUNCHER_ROCKET = preload("res://Objects/Levels/Enemies/RocketLauncherRocket.tscn") 4 | const CAPSULE := preload("res://Objects/Levels/Capsule.tscn") 5 | const EXPLOSION := preload("res://Objects/Levels/Explosion.tscn") 6 | 7 | @onready var animation_player: AnimationPlayer = $AnimationPlayer 8 | var launched := false 9 | 10 | func _ready() -> void: 11 | animation_player.play("idle") 12 | 13 | func _process(_delta: float) -> void: 14 | if position.x < Global.player.position.x + 100: 15 | launch() 16 | 17 | func launch() -> void: 18 | if not launched: 19 | launched = true 20 | animation_player.play("launching") 21 | await animation_player.animation_finished 22 | # In case if the launcher was destroyed while it was preparing for launch 23 | if animation_player.current_animation == "dead": 24 | return 25 | animation_player.play("launched") 26 | 27 | var rocket := ROCKET_LAUNCHER_ROCKET.instantiate() 28 | rocket.position = position + Vector2(7, -7) 29 | get_parent().add_child(rocket) 30 | rocket.attack_component.objects_to_ignore.append(self) 31 | 32 | func _on_health_component_dead() -> void: 33 | $HealthComponent.queue_free() 34 | launched = true 35 | start_destroy_sfx() 36 | 37 | var explosion := EXPLOSION.instantiate() 38 | explosion.global_position = global_position 39 | get_parent().add_child(explosion) 40 | 41 | var capsule := CAPSULE.instantiate() 42 | Global.get_current_scene().call_deferred("add_child", capsule) 43 | await get_tree().process_frame 44 | capsule.initialize(global_position, "health") 45 | 46 | animation_player.play("dead") 47 | 48 | -------------------------------------------------------------------------------- /Scenes/MainMenu/Settings.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://lxs5br5r3336"] 2 | 3 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="1_bmng2"] 4 | 5 | [sub_resource type="GDScript" id="GDScript_l65hy"] 6 | resource_name = "SettingsMenu" 7 | script/source = "extends \"res://Scripts/MainMenu/Menu.gd\" 8 | 9 | func menu_select(id: int) -> void: 10 | var menus: Array[Node2D] = [ 11 | %VideoSettings, 12 | %SoundSettings, 13 | %Controls, 14 | %MenuMain, 15 | ] 16 | 17 | main_menu.set_menu(menus[id]) 18 | " 19 | 20 | [node name="Settings" type="Node2D" groups=["menu"]] 21 | script = SubResource("GDScript_l65hy") 22 | 23 | [node name="Video" type="Label" parent="." groups=["option"]] 24 | offset_left = 72.0 25 | offset_top = 80.0 26 | offset_right = 136.0 27 | offset_bottom = 91.0 28 | theme_override_fonts/font = ExtResource("1_bmng2") 29 | text = "video options" 30 | uppercase = true 31 | 32 | [node name="Sound" type="Label" parent="." groups=["option"]] 33 | offset_left = 72.0 34 | offset_top = 104.0 35 | offset_right = 176.0 36 | offset_bottom = 115.0 37 | theme_override_fonts/font = ExtResource("1_bmng2") 38 | text = "sound options" 39 | uppercase = true 40 | 41 | [node name="Controls" type="Label" parent="." groups=["option"]] 42 | offset_left = 72.0 43 | offset_top = 128.0 44 | offset_right = 184.0 45 | offset_bottom = 139.0 46 | theme_override_fonts/font = ExtResource("1_bmng2") 47 | text = "controls 48 | " 49 | uppercase = true 50 | 51 | [node name="Exit" type="Label" parent="." groups=["option"]] 52 | offset_left = 72.0 53 | offset_top = 152.0 54 | offset_right = 184.0 55 | offset_bottom = 163.0 56 | theme_override_fonts/font = ExtResource("1_bmng2") 57 | text = "exit" 58 | uppercase = true 59 | -------------------------------------------------------------------------------- /Scripts/Main.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | @export var initial_scene: PackedScene = preload("res://Scenes/TitleScreen.tscn") 4 | @export var wait_before_start := false # Mostly just a debugging feature 5 | @onready var canvas_layer: CanvasLayer = $CanvasLayer 6 | var wait_before_start_flag := false 7 | 8 | func _ready() -> void: 9 | Global.main = self 10 | Global.music = $Music 11 | Global._fade_player = $CanvasLayer/FadePlayer 12 | Global._fader = $CanvasLayer/Fader 13 | 14 | if wait_before_start: 15 | get_tree().paused = true 16 | get_tree().process_frame.connect(func() -> void: 17 | if not wait_before_start_flag and Global.any_action_button_pressed(): 18 | wait_before_start_flag = true 19 | get_tree().paused = false 20 | start() 21 | ) 22 | else: 23 | start() 24 | 25 | func start() -> void: 26 | $CurrentScene.add_child(initial_scene.instantiate()) 27 | Global.widescreen_changed.connect(_on_widescreen_change) 28 | Global.scene_changed.connect(func(_from: Node, _to: Node) -> void: 29 | _on_widescreen_change() 30 | ) 31 | 32 | Global.hide_fade() 33 | _on_widescreen_change() 34 | 35 | func _on_widescreen_change() -> void: 36 | $CanvasLayer/Fader.size = Global.get_content_size() 37 | 38 | if not Global.get_current_scene() is Node2D: 39 | return 40 | 41 | var curscene: Node2D = Global.get_current_scene() as Node2D 42 | if not get_viewport().get_camera_2d(): 43 | curscene.position.x = (Global.get_content_size().x - \ 44 | Global.get_default_resolution().x) / 2 45 | return 46 | 47 | if get_viewport().get_camera_2d().limit_right <= Global.get_content_size().x: 48 | curscene.position.x = (get_viewport().get_camera_2d().limit_right - \ 49 | Global.get_content_size().x) / 2 50 | else: 51 | curscene.position.x = 0 52 | -------------------------------------------------------------------------------- /Scripts/Levels/Bosses/Mothra.gd: -------------------------------------------------------------------------------- 1 | extends "res://Scripts/Levels/Bosses/BaseBoss.gd" 2 | 3 | enum BossState { 4 | NONE, 5 | IDLE, 6 | MOVING, 7 | } 8 | 9 | var state: BossState = BossState.NONE 10 | var time := 40 11 | var attack_time := 0 12 | var simple_attack_time := 0 13 | 14 | func boss_ai_start() -> void: 15 | state = BossState.IDLE 16 | 17 | func boss_ai_stop() -> void: 18 | state = BossState.NONE 19 | 20 | func boss_ai() -> void: 21 | if state == BossState.NONE or boss.state.current == boss.State.DEAD: 22 | return 23 | 24 | time -= 1 25 | 26 | if boss.position.x < 50: 27 | boss.position.x = 50 28 | boss.velocity.x = 0 29 | state = BossState.IDLE 30 | 31 | if (boss.position.x - player.position.x) < 60: 32 | attack_time += 1 33 | elif (boss.position.x - player.position.x) < 100: 34 | simple_attack_time += 1 35 | 36 | if attack_time > 150 and boss.power.value > 3 * 8: 37 | attack_time = 0 38 | boss.simulate_input_press(PlayerCharacter.Inputs.START) 39 | 40 | if simple_attack_time > 100: 41 | simple_attack_time = 0 42 | spam_bullets() 43 | 44 | match state: 45 | BossState.IDLE: 46 | boss.inputs[boss.Inputs.XINPUT] = 0 47 | boss.inputs[boss.Inputs.YINPUT] = 0 48 | if time <= 0: 49 | state = BossState.MOVING 50 | time = 20 51 | 52 | boss.inputs[boss.Inputs.XINPUT] = randi_range(-1, 1) 53 | boss.inputs[boss.Inputs.YINPUT] = randi_range(-1, 1) 54 | BossState.MOVING: 55 | if boss.position.y > 160: 56 | boss.position.y = 160 57 | boss.velocity.y = 0 58 | if time <= 0: 59 | state = BossState.IDLE 60 | time = randi_range(30, 90) 61 | 62 | func spam_bullets() -> void: 63 | boss.inputs_pressed[boss.Inputs.A] = true 64 | await get_tree().create_timer(1, false).timeout 65 | boss.inputs_pressed[boss.Inputs.A] = false 66 | -------------------------------------------------------------------------------- /Scripts/Levels/Bosses/BaseBoss.gd: -------------------------------------------------------------------------------- 1 | extends Level 2 | 3 | ## The amount of XP the player gets when the boss is defeated 4 | @export var xp_amount := 100 5 | ## The amount of score the player gets when the boss is defeated 6 | @export var score_amount := 110000 7 | 8 | @onready var boss: PlayerCharacter = $Boss 9 | 10 | func _ready() -> void: 11 | super._ready() 12 | player.intro_ended.connect(boss_ai_start) 13 | player.health.dead.connect(boss_ai_stop) 14 | 15 | boss.health.damaged.connect(func(amount: float, _hurt_time: float) -> void: 16 | Global.add_score(20 * int(amount)) 17 | ) 18 | boss.health.dead.connect(func() -> void: 19 | $HUD.boss_timer_second.stop() 20 | player.add_xp(xp_amount) 21 | Global.play_music(preload("res://Audio/Soundtrack/Victory.ogg")) 22 | save_player_state() 23 | player_dead(boss, data.boss_piece) 24 | Global.add_score(score_amount, 10000) 25 | ) 26 | 27 | if data.boss_piece: 28 | boss.load_state(data.boss_piece.character_data) 29 | 30 | func _process(delta: float) -> void: 31 | super._process(delta) 32 | 33 | if player.position.x > boss.position.x - 20: 34 | player.position.x = boss.position.x - 20 35 | player.velocity.x = 0 36 | 37 | if boss.position.x > camera.limit_right - 10: 38 | boss.position.x = camera.limit_right - 10 39 | boss.velocity.x = 0.0 40 | 41 | boss_ai() 42 | 43 | func _on_hud_boss_timer_timeout() -> void: 44 | boss.save_state(data.boss_piece.character_data) 45 | 46 | Global.music_fade_out() 47 | await Global.fade_out_paused() 48 | 49 | Global.change_scene_node(Global.board) 50 | # true for ignore_boss_moves 51 | Global.board.returned(true) 52 | 53 | func boss_ai_start() -> void: 54 | pass 55 | 56 | func boss_ai() -> void: 57 | printerr("This boss AI has not been coded in or incorrectly overriden") 58 | 59 | func boss_ai_stop() -> void: 60 | pass 61 | -------------------------------------------------------------------------------- /Scripts/Objects/Characters/MothraParticle.gd: -------------------------------------------------------------------------------- 1 | extends AnimatedSprite2D 2 | 3 | enum Type { 4 | EYE_BEAM, 5 | WING, 6 | } 7 | 8 | @onready var timer := $Timer 9 | @onready var animation_player := $AnimationPlayer 10 | @onready var attack_component: Node2D = $AttackComponent 11 | 12 | var velocity := Vector2() 13 | var type: Type 14 | 15 | func setup(init_type: Type, player: PlayerCharacter) -> void: 16 | type = init_type 17 | attack_component.objects_to_ignore.append(player) 18 | attack_component.enemy = player.attack.enemy 19 | attack_component.attacked.connect(player._on_attack_component_attacked) 20 | 21 | scale.x = player.direction 22 | match type: 23 | Type.EYE_BEAM: 24 | animation = "EyeBeam" 25 | timer.start(0.3) 26 | timer.timeout.connect(func() -> void: queue_free()) 27 | velocity = Vector2(5 * player.direction * 60, 0) 28 | 29 | Type.WING: 30 | animation = "Wing" 31 | animation_player.play("Flash") 32 | timer.start(0.4) 33 | timer.timeout.connect(func() -> void: 34 | animation_player.stop() 35 | visible = true # Just in case 36 | ) 37 | velocity = Vector2(randi_range(2, 10) * 0.1 * 60 * player.direction, 38 | randi_range(6, 9) * 0.1 * 60) 39 | 40 | attack_component.attacked.connect(func(_body: Node2D, _amount: float) -> void: 41 | queue_free() 42 | ) 43 | 44 | attack_component.set_collision( 45 | sprite_frames.get_frame_texture(animation, 0).get_size(), 46 | Vector2.ZERO 47 | ) 48 | 49 | func _physics_process(delta: float) -> void: 50 | if type == Type.WING: 51 | velocity.y += 1 * 60 * delta 52 | position += velocity * delta 53 | var camera := get_viewport().get_camera_2d() 54 | var limit: float = Global.get_content_size().y + 20.0 55 | if camera != null: 56 | limit += camera.get_screen_center_position().y 57 | if position.y > limit: 58 | queue_free() 59 | -------------------------------------------------------------------------------- /Scripts/MainMenu/SaveSlot.gd: -------------------------------------------------------------------------------- 1 | extends Control 2 | 3 | const BOARD_PIECE := preload("res://Objects/Boards/Piece.tscn") 4 | 5 | @onready var save_exists: Node2D = $SaveExists 6 | @onready var doesnt_exist: Node2D = $DoesntExist 7 | @onready var border: NinePatchRect = $Border 8 | 9 | var save_id := 0 10 | var planet: BoardDescription = null 11 | 12 | var pieces: Array[BoardPiece] = [] 13 | 14 | func _ready() -> void: 15 | save_exists.visible = false 16 | doesnt_exist.visible = false 17 | 18 | func set_data(psave_id: int, pplanet: BoardDescription, save_data: Dictionary) -> void: 19 | save_exists.visible = true 20 | doesnt_exist.visible = false 21 | 22 | var group := $SaveExists 23 | 24 | self.save_id = psave_id 25 | $SaveExists/SaveID.text = "save " + str(psave_id + 1) 26 | 27 | self.planet = pplanet 28 | $SaveExists/PlanetName.text = pplanet.name.to_lower() 29 | 30 | if planet.icon != null: 31 | $SaveExists/PlanetIcon.texture = pplanet.icon 32 | 33 | # Load characters from the save 34 | var characters: Array[PlayerCharacter.Type] = save_data["board_data"]["player_characters"] 35 | characters.reverse() 36 | var position_x := 24.0 37 | for character: PlayerCharacter.Type in characters: 38 | var piece := BOARD_PIECE.instantiate() 39 | piece.piece_character = character 40 | group.add_child(piece) 41 | piece.position = Vector2(position_x, 24.0) 42 | pieces.append(piece) 43 | position_x += 8 44 | 45 | func set_data_empty(psave_id: int) -> void: 46 | save_exists.visible = false 47 | doesnt_exist.visible = true 48 | pieces = [] 49 | $DoesntExist/SaveID.text = "save " + str(psave_id + 1) 50 | 51 | func select() -> void: 52 | border.self_modulate = Color("b53120") 53 | for piece in pieces: 54 | piece.select() 55 | 56 | func deselect() -> void: 57 | border.self_modulate = Color.WHITE 58 | for piece in pieces: 59 | piece.deselect() 60 | -------------------------------------------------------------------------------- /Scenes/MainMenu/Controls.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=3 uid="uid://dy3m74iswj1v"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/MainMenu/Controls.gd" id="1_pl7kv"] 4 | [ext_resource type="Texture2D" uid="uid://dewcb08w13bxc" path="res://Sprites/controller.png" id="2_nqnh2"] 5 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="3_alnrf"] 6 | 7 | [sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_pvg2g"] 8 | blend_mode = 1 9 | 10 | [node name="Controls" type="Node2D" groups=["menu"]] 11 | script = ExtResource("1_pl7kv") 12 | 13 | [node name="Controller" type="Sprite2D" parent="."] 14 | position = Vector2(128, 120) 15 | texture = ExtResource("2_nqnh2") 16 | offset = Vector2(0, 3) 17 | region_rect = Rect2(0, 0, 20, 20) 18 | 19 | [node name="ButtonHighlight" type="Sprite2D" parent="."] 20 | material = SubResource("CanvasItemMaterial_pvg2g") 21 | position = Vector2(59, 124) 22 | texture = ExtResource("2_nqnh2") 23 | centered = false 24 | region_enabled = true 25 | region_rect = Rect2(23, 44, 8, 8) 26 | 27 | [node name="CurrentButton" type="Label" parent="."] 28 | offset_top = 64.0 29 | offset_right = 256.0 30 | offset_bottom = 75.0 31 | theme_override_fonts/font = ExtResource("3_alnrf") 32 | text = "press button up" 33 | horizontal_alignment = 1 34 | uppercase = true 35 | 36 | [node name="CancelText" type="Label" parent="."] 37 | offset_top = 176.0 38 | offset_right = 256.0 39 | offset_bottom = 187.0 40 | theme_override_fonts/font = ExtResource("3_alnrf") 41 | text = "press escape to exit this menu" 42 | horizontal_alignment = 1 43 | uppercase = true 44 | 45 | [node name="ResetControls" type="Label" parent="."] 46 | offset_top = 192.0 47 | offset_right = 256.0 48 | offset_bottom = 203.0 49 | theme_override_fonts/font = ExtResource("3_alnrf") 50 | text = "press key to reset controls 51 | later in-game" 52 | horizontal_alignment = 1 53 | uppercase = true 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godotzilla 2 | Godotzilla is a Godzilla: Monster of Monsters-styled framework made for Godot 4.3. 3 | 4 | This framework can be used for anything you want, this includes but not limited to: 5 | - GMoM remakes 6 | - NES Godzilla Creepypasta remakes 7 | - playable NGC fan stories. 8 | 9 | ## Features 10 | - 2 playable characters: Godzilla and Mothra 11 | - Everything essential for a GMoM-styled game is present: 12 | - Levels 13 | - Bosses (includes a Mothra boss template) 14 | - Boards 15 | - Title screen 16 | - Main menu 17 | - "Pass word game" 18 | - Settings 19 | - Credits 20 | - Save system 21 | - With encryption and (hopefully working) protection against using other people's save files 22 | - Wide screen support (togglable) 23 | - Gamepad support 24 | - Tested with cheap controllers as well as Dualshock 4 and Xbox One controllers 25 | - In-game control remapping 26 | - Pause menu with settings 27 | - Reusable components for characters and enemies: 28 | - State machine 29 | - Health component, power component, attack component 30 | - [Tutorials!](Tutorials) (You should at least check out the "Framework overview" one, it also includes 31 | how to properly import the framework into Godot without errors) 32 | - And more! 33 | 34 | ## Credits 35 | - Nintorch - main developer of the framework 36 | - FreKay Planet - sprite rips of Mothra 37 | - Cioss - NES controller sprite for "Controls" menu 38 | - Special thanks to MadzillaKOTH and Dino for following the development 39 | of the framework, giving me motivation to work on it and testing and Z-9 Lurker as well for testing 40 | - "Godzilla: Monster of Monsters" NES game © Toho Co., Ltd. & Compile 41 | - Godzilla and related characters © Toho Co., Ltd. 42 | - Nintendo Entertainment System (NES) © Nintendo 43 | 44 | This project is not affiliated with nor endorsed by Toho, Compile or Nintendo. It's a fan-made non-profit project made for fun. 45 | -------------------------------------------------------------------------------- /Objects/Levels/Explosion.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=3 uid="uid://cpxp6boj611rb"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://dbjki3nsg35x8" path="res://Sprites/Levels/explosion.png" id="1_t4gnj"] 4 | [ext_resource type="Script" path="res://Scripts/Objects/Explosion.gd" id="2_wfcqr"] 5 | 6 | [sub_resource type="Animation" id="Animation_7s04k"] 7 | length = 0.001 8 | tracks/0/type = "value" 9 | tracks/0/imported = false 10 | tracks/0/enabled = true 11 | tracks/0/path = NodePath(".:frame") 12 | tracks/0/interp = 1 13 | tracks/0/loop_wrap = true 14 | tracks/0/keys = { 15 | "times": PackedFloat32Array(0), 16 | "transitions": PackedFloat32Array(1), 17 | "update": 1, 18 | "values": [0] 19 | } 20 | 21 | [sub_resource type="Animation" id="Animation_pjamu"] 22 | resource_name = "animation" 23 | tracks/0/type = "value" 24 | tracks/0/imported = false 25 | tracks/0/enabled = true 26 | tracks/0/path = NodePath(".:frame") 27 | tracks/0/interp = 1 28 | tracks/0/loop_wrap = true 29 | tracks/0/keys = { 30 | "times": PackedFloat32Array(0, 0.1), 31 | "transitions": PackedFloat32Array(1, 1), 32 | "update": 1, 33 | "values": [0, 1] 34 | } 35 | tracks/1/type = "method" 36 | tracks/1/imported = false 37 | tracks/1/enabled = true 38 | tracks/1/path = NodePath(".") 39 | tracks/1/interp = 1 40 | tracks/1/loop_wrap = true 41 | tracks/1/keys = { 42 | "times": PackedFloat32Array(0.2), 43 | "transitions": PackedFloat32Array(1), 44 | "values": [{ 45 | "args": [], 46 | "method": &"queue_free" 47 | }] 48 | } 49 | 50 | [sub_resource type="AnimationLibrary" id="AnimationLibrary_t5kuu"] 51 | _data = { 52 | "RESET": SubResource("Animation_7s04k"), 53 | "animation": SubResource("Animation_pjamu") 54 | } 55 | 56 | [node name="Explosion" type="Sprite2D"] 57 | top_level = true 58 | texture = ExtResource("1_t4gnj") 59 | hframes = 2 60 | script = ExtResource("2_wfcqr") 61 | 62 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."] 63 | libraries = { 64 | "": SubResource("AnimationLibrary_t5kuu") 65 | } 66 | -------------------------------------------------------------------------------- /Scripts/Objects/Characters/Fly.gd: -------------------------------------------------------------------------------- 1 | extends State 2 | 3 | const YLIMIT = 72 4 | var floor_checking: Area2D 5 | var attack_timer := Timer.new() 6 | 7 | func state_init() -> void: 8 | floor_checking = parent.get_node("MothraFloorChecking") 9 | attack_timer.one_shot = true 10 | add_child(attack_timer) 11 | 12 | func _physics_process(delta: float) -> void: 13 | move(delta) 14 | 15 | func _process(_delta: float) -> void: 16 | if parent.character == PlayerCharacter.Type.MOTHRA: 17 | if (parent.inputs_pressed[parent.Inputs.A] 18 | or parent.inputs_pressed[parent.Inputs.B]) \ 19 | and attack_timer.is_stopped(): 20 | parent.use_attack(PlayerCharacter.Attack.EYE_BEAM) 21 | attack_timer.start(0.2) 22 | 23 | if parent.inputs_pressed[parent.Inputs.START]: 24 | parent.use_attack(PlayerCharacter.Attack.WING_ATTACK) 25 | 26 | func move(delta: float) -> void: 27 | var xspeed: float = parent.move_speed 28 | var ylimit := YLIMIT 29 | 30 | var camera := get_viewport().get_camera_2d() 31 | if camera != null: 32 | ylimit += camera.limit_top 33 | if camera.is_camera_moving(): 34 | xspeed = 1 * 60 35 | 36 | parent.velocity.x = signf(parent.inputs[parent.Inputs.XINPUT]) * xspeed 37 | parent.velocity.y = signf(parent.inputs[parent.Inputs.YINPUT]) * parent.move_speed 38 | 39 | if parent.allow_direction_changing and signf(parent.inputs[parent.Inputs.XINPUT]) != 0: 40 | parent.direction = signf(parent.inputs[parent.Inputs.XINPUT]) 41 | 42 | floor_checking.position.y = parent.velocity.y * delta 43 | 44 | if Global.get_current_scene().has_node("HUD"): 45 | ylimit += Global.get_current_scene().get_node("HUD").vertical_size 46 | 47 | if floor_checking.has_overlapping_bodies() and parent.velocity.y > 0: 48 | parent.velocity.y = 0 49 | elif (parent.position.y + parent.velocity.y * delta) < ylimit \ 50 | and parent.velocity.y < 0: 51 | parent.velocity.y = 0 52 | parent.position.y = ylimit 53 | 54 | func reset() -> void: 55 | parent.animation_player.play("Idle") 56 | -------------------------------------------------------------------------------- /Objects/Boards/MessageWindow.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=3 uid="uid://bn3se1dw6cfhu"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/Objects/Boards/MessageWindow.gd" id="1_4muex"] 4 | [ext_resource type="Texture2D" uid="uid://wmgv6kcqcri0" path="res://Sprites/BoardSprites.png" id="1_yr4n5"] 5 | [ext_resource type="FontFile" uid="uid://b4bp7sni8u0il" path="res://Sprites/font2.png" id="3_qerkx"] 6 | [ext_resource type="AudioStream" uid="uid://bq6ov0bep762q" path="res://Audio/SFX/MenuBip.wav" id="4_y31a1"] 7 | 8 | [sub_resource type="LabelSettings" id="LabelSettings_qwev6"] 9 | line_spacing = 0.0 10 | 11 | [node name="MessageWindow" type="NinePatchRect"] 12 | offset_right = 32.0 13 | offset_bottom = 32.0 14 | texture = ExtResource("1_yr4n5") 15 | region_rect = Rect2(48, 0, 24, 24) 16 | patch_margin_left = 8 17 | patch_margin_top = 8 18 | patch_margin_right = 8 19 | patch_margin_bottom = 8 20 | script = ExtResource("1_4muex") 21 | 22 | [node name="Text" type="Label" parent="."] 23 | layout_mode = 0 24 | offset_left = 8.0 25 | offset_top = 8.0 26 | offset_right = 158.0 27 | offset_bottom = 24.0 28 | theme_override_fonts/font = ExtResource("3_qerkx") 29 | text = "text here" 30 | label_settings = SubResource("LabelSettings_qwev6") 31 | autowrap_mode = 2 32 | uppercase = true 33 | 34 | [node name="MenuBip" type="AudioStreamPlayer" parent="."] 35 | process_mode = 3 36 | stream = ExtResource("4_y31a1") 37 | bus = &"SFX" 38 | 39 | [node name="Choice" type="Node2D" parent="."] 40 | position = Vector2(16, 40) 41 | 42 | [node name="YesNo" type="Label" parent="Choice"] 43 | offset_left = 8.0 44 | offset_right = 158.0 45 | offset_bottom = 16.0 46 | theme_override_fonts/font = ExtResource("3_qerkx") 47 | text = "yes no 48 | " 49 | label_settings = SubResource("LabelSettings_qwev6") 50 | autowrap_mode = 2 51 | uppercase = true 52 | 53 | [node name="Selector" type="Sprite2D" parent="Choice"] 54 | texture = ExtResource("1_yr4n5") 55 | centered = false 56 | region_enabled = true 57 | region_rect = Rect2(72, 0, 8, 8) 58 | -------------------------------------------------------------------------------- /Scripts/Objects/HealthComponent.gd: -------------------------------------------------------------------------------- 1 | class_name HealthComponent 2 | extends Node 3 | 4 | ## Health points 5 | @export var max_value := 10.0 6 | @export var enemy := false 7 | @export var invincibility_time_seconds := 0.0 8 | ## How many health points should be taken each frame 9 | @export var health_speed := 1.0 10 | 11 | var value := 0.0: 12 | set(v): 13 | value = v 14 | value_changed.emit(value) 15 | var target_value := 0.0 16 | var died := false 17 | var invincible := false 18 | 19 | signal value_changed(new_value: float) 20 | signal damaged(amount: float, hurt_time: float) 21 | signal dead 22 | signal healed(amount: float) 23 | signal resized(new_amount: float) 24 | 25 | func _ready() -> void: 26 | set_value(max_value) 27 | 28 | func _process(delta: float) -> void: 29 | value = move_toward(value, target_value, health_speed * 60 * delta) 30 | if value <= 0.0 and not died: 31 | died = true 32 | dead.emit() 33 | 34 | func damage(amount: float, hurt_time: float = -1) -> void: 35 | if amount <= 0 or invincible or died \ 36 | or (get_parent().has_method("is_hurtable") and not get_parent().is_hurtable()): 37 | return 38 | 39 | target_value = clampf(target_value - amount, 0.0, max_value) 40 | damaged.emit(amount, hurt_time) 41 | if invincibility_time_seconds > 0.0: 42 | invincible = true 43 | await get_tree().create_timer(invincibility_time_seconds, false).timeout 44 | invincible = false 45 | 46 | func heal(amount: float) -> void: 47 | if amount <= 0 or target_value >= max_value or died: 48 | return 49 | 50 | if target_value + amount <= max_value: 51 | target_value += amount 52 | healed.emit(amount) 53 | else: 54 | var old_value := target_value 55 | target_value = max_value 56 | healed.emit(max_value - old_value) 57 | 58 | func fill() -> void: 59 | set_value(max_value) 60 | 61 | func resize(new_hp_amount: float) -> void: 62 | max_value = new_hp_amount 63 | resized.emit(new_hp_amount) 64 | 65 | func resize_and_fill(new_hp_amount: float) -> void: 66 | resize(new_hp_amount) 67 | fill() 68 | 69 | func set_value(new_value: float) -> void: 70 | target_value = minf(new_value, max_value) 71 | value = target_value 72 | -------------------------------------------------------------------------------- /Scripts/Objects/Enemies/Jet.gd: -------------------------------------------------------------------------------- 1 | extends "res://Scripts/Objects/Enemies/BaseEnemy.gd" 2 | 3 | enum State { 4 | IDLE, 5 | MOVING_LEFT, 6 | MOVING_RIGHT, 7 | } 8 | 9 | const JET_PROJECTILE = preload("res://Objects/Levels/Enemies/JetProjectile.tscn") 10 | const EXPLOSION := preload("res://Objects/Levels/Explosion.tscn") 11 | 12 | @onready var animation_player: AnimationPlayer = $AnimationPlayer 13 | 14 | var state := State.IDLE 15 | var velocity := Vector2() 16 | var launched_projectile := false 17 | 18 | func _ready() -> void: 19 | attack_component.set_collision(Vector2(20, 10), Vector2.ZERO) 20 | 21 | func _process(delta: float) -> void: 22 | match state: 23 | State.IDLE: 24 | var camera := get_viewport().get_camera_2d() 25 | if camera != null \ 26 | and position.x < camera.position.x + Global.get_content_size().x / 2 + 30: 27 | state = State.MOVING_LEFT 28 | velocity = Vector2(-0.8 * 60, -0.2 * 60) 29 | animation_player.play("flying_left") 30 | 31 | State.MOVING_LEFT: 32 | velocity.x -= 0.1 * 60 * 60 * delta 33 | 34 | if Global.player != null and Global.player.character == PlayerCharacter.Type.MOTHRA \ 35 | and position.x < Global.player.position.x + 150: 36 | state = State.MOVING_RIGHT 37 | animation_player.play("flying_right") 38 | 39 | State.MOVING_RIGHT: 40 | velocity.x += 0.05 * 60 * 60 * delta 41 | if not launched_projectile and absf(velocity.x) < 0.04 * 60: 42 | var projectile := JET_PROJECTILE.instantiate() 43 | projectile.position = position 44 | get_parent().add_child(projectile) 45 | projectile.attack_component.objects_to_ignore.append(self) 46 | launched_projectile = true 47 | 48 | position += velocity * delta 49 | 50 | func _on_attack_component_attacked(_body: Node2D, _amount: float) -> void: 51 | _on_health_component_dead() 52 | 53 | func _on_health_component_damaged(_amount: float, _hurt_time: float) -> void: 54 | pass 55 | 56 | func _on_health_component_dead() -> void: 57 | var explosion := EXPLOSION.instantiate() 58 | explosion.global_position = global_position 59 | 60 | start_destroy_sfx() 61 | get_parent().add_child(explosion) 62 | queue_free() 63 | -------------------------------------------------------------------------------- /Scenes/TitleScreen.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://bcqw43w8eilwf"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://b0k23sbm3154y" path="res://Sprites/TitleScreen.png" id="1_nksky"] 4 | [ext_resource type="Script" path="res://Scripts/TitleScreen.gd" id="1_pfn82"] 5 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="2_0bcny"] 6 | 7 | [node name="TitleScreen" type="Node2D"] 8 | script = ExtResource("1_pfn82") 9 | 10 | [node name="FlashTimer" type="Timer" parent="."] 11 | wait_time = 4.0 12 | one_shot = true 13 | autostart = true 14 | 15 | [node name="BeforeFlash" type="Node2D" parent="."] 16 | visible = false 17 | 18 | [node name="ColorRect" type="ColorRect" parent="BeforeFlash"] 19 | offset_top = 48.0 20 | offset_right = 256.0 21 | offset_bottom = 184.0 22 | color = Color(0.423529, 0.027451, 0, 1) 23 | 24 | [node name="GodzillaSilhouette" type="Sprite2D" parent="BeforeFlash"] 25 | position = Vector2(0, 48) 26 | texture = ExtResource("1_nksky") 27 | centered = false 28 | region_enabled = true 29 | region_rect = Rect2(0, 0, 256, 136) 30 | 31 | [node name="AfterFlash" type="Node2D" parent="."] 32 | 33 | [node name="ColorRect2" type="ColorRect" parent="AfterFlash"] 34 | offset_top = 48.0 35 | offset_right = 256.0 36 | offset_bottom = 184.0 37 | color = Color(0.678431, 0.678431, 0.678431, 1) 38 | 39 | [node name="Godzilla" type="Sprite2D" parent="AfterFlash"] 40 | position = Vector2(0, 48) 41 | texture = ExtResource("1_nksky") 42 | centered = false 43 | region_enabled = true 44 | region_rect = Rect2(0, 136, 256, 136) 45 | 46 | [node name="OriginalCopyrights" type="Sprite2D" parent="AfterFlash"] 47 | position = Vector2(16, 192) 48 | texture = ExtResource("1_nksky") 49 | centered = false 50 | region_enabled = true 51 | region_rect = Rect2(0, 272, 256, 24) 52 | 53 | [node name="Godotzilla" type="Label" parent="AfterFlash"] 54 | offset_left = 40.0 55 | offset_top = 24.0 56 | offset_right = 216.0 57 | offset_bottom = 35.0 58 | theme_override_fonts/font = ExtResource("2_0bcny") 59 | text = "powered by godotzilla" 60 | horizontal_alignment = 1 61 | uppercase = true 62 | 63 | [connection signal="timeout" from="FlashTimer" to="." method="_on_flash_timer_timeout"] 64 | -------------------------------------------------------------------------------- /Scripts/MainMenu/BaseMenu.gd: -------------------------------------------------------------------------------- 1 | class_name BaseMenu 2 | extends Node2D 3 | 4 | @export var music: AudioStream = null 5 | @onready var selector: ColorRect = $Selector 6 | var selector_option := 0 7 | var current_menu: Node2D 8 | 9 | func _ready() -> void: 10 | RenderingServer.set_default_clear_color(Color.BLACK) 11 | 12 | # Disable every menu when starting up 13 | for menu: Node in get_children().filter(func(x: Node) -> bool: return x.is_in_group("menu")): 14 | enable_menu(menu, false) 15 | 16 | set_menu(%MenuMain) 17 | 18 | Global.hide_fade() 19 | if music: 20 | Global.play_music(music) 21 | 22 | func _process(_delta: float) -> void: 23 | if selector.is_processing(): 24 | if Input.is_action_just_pressed("Down"): 25 | selector_option = mini(selector_option + 1, \ 26 | current_menu.options.size() - 1) 27 | move_selector(selector_option) 28 | 29 | if Input.is_action_just_pressed("Up"): 30 | selector_option = maxi(selector_option - 1, 0) 31 | move_selector(selector_option) 32 | 33 | if Global.any_action_button_pressed(): 34 | current_menu.menu_select(selector_option) 35 | 36 | func enable_menu(menu: Node2D, flag: bool) -> void: 37 | menu.visible = flag 38 | menu.set_process(flag) 39 | menu.set_physics_process(flag) 40 | menu.set_process_input(flag) 41 | 42 | func set_menu(menu: Node2D) -> void: 43 | var prev_menu := current_menu 44 | selector.visible = false 45 | 46 | current_menu = menu 47 | if prev_menu: prev_menu.menu_exit() 48 | current_menu.menu_enter() 49 | 50 | await get_tree().process_frame 51 | 52 | if prev_menu: enable_menu(prev_menu, false) 53 | enable_menu(current_menu, true) 54 | 55 | if current_menu.options.size() > 0: 56 | selector.visible = true 57 | selector.set_process(true) 58 | selector_option = 0 59 | move_selector(0) 60 | else: 61 | # Hide the selector in case if the menu doesn't have options 62 | selector.set_process(false) 63 | 64 | func move_selector(option: int) -> void: 65 | var control_option: Node = current_menu.options[option] 66 | selector.global_position = control_option.global_position + Vector2(-16, 0) 67 | 68 | func change_scene(scene: PackedScene) -> void: 69 | get_tree().paused = true 70 | 71 | Global.music_fade_out() 72 | await Global.fade_out() 73 | await get_tree().create_timer(0.5).timeout 74 | 75 | get_tree().paused = false 76 | Global.change_scene(scene) 77 | -------------------------------------------------------------------------------- /Scripts/Objects/Bar.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends Control 3 | 4 | enum Style { 5 | STYLE1, 6 | STYLE2, 7 | } 8 | 9 | const SPEED := 1 * 60 10 | 11 | ## Style 1 is the style for player's power and life bars. 12 | @export var style := Style.STYLE1: 13 | set(value): style = value; update_style() 14 | 15 | ## Bar count for style 1, maximum value for style 2 16 | @export var width := 1: 17 | set(value): width = value; update_style() 18 | 19 | ## -1 for full 20 | @export var initial_value := -1: 21 | set(value): initial_value = value; update_style() 22 | 23 | @export var color1 := Color(1, 1, 1): 24 | set(value): color1 = value; update_style() 25 | 26 | @export var color2 := Color(0.71, 0.19, 0.125): 27 | set(value): color2 = value; update_style() 28 | 29 | var value: float = 0 30 | var target_value: float = 0 31 | var max_value: float = 0 32 | 33 | func _ready() -> void: 34 | update_style() 35 | 36 | func _process(delta: float) -> void: 37 | if target_value > max_value or value > max_value: 38 | target_value = max_value 39 | value = max_value 40 | 41 | if value != target_value: 42 | value = move_toward(value, target_value, SPEED * delta) 43 | match style: 44 | Style.STYLE1: 45 | $Style1/RedBar.size.x = int(value) 46 | Style.STYLE2: 47 | $Style2/BarColor.size.x = (value / max_value) * $Style2/BarBG.size.x 48 | 49 | func update_style() -> void: 50 | for s: Control in get_children().filter(func(x: Control) -> bool: 51 | return x.is_in_group("bar_style")): 52 | s.visible = false 53 | 54 | match style: 55 | Style.STYLE1: 56 | $Style1.visible = true 57 | 58 | $Style1/BarsOutline.size.x = width * 8 + 1 59 | $Style1/BarsOutline.self_modulate = color1 60 | $Style1/RedBar.color = color2 61 | max_value = width * 8 62 | 63 | if initial_value < 0: 64 | value = max_value 65 | else: 66 | value = initial_value 67 | 68 | $Style1/RedBar.size.x = value 69 | 70 | Style.STYLE2: 71 | $Style2.visible = true 72 | 73 | $Style2/BarBG.color = color1 74 | $Style2/BarBG.size.x = size.x 75 | $Style2/BarColor.color = color2 76 | max_value = width 77 | 78 | if initial_value < 0: 79 | value = max_value 80 | else: 81 | value = initial_value 82 | 83 | $Style2/BarColor.size.x = (value / max_value) * $Style2/BarBG.size.x 84 | 85 | target_value = value 86 | 87 | if Engine.is_editor_hint(): 88 | queue_redraw() 89 | -------------------------------------------------------------------------------- /Objects/Levels/Enemies/YellowShip.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=3 uid="uid://dkwaunrisvrj0"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://vwe0hqe8bxv4" path="res://Sprites/Levels/TestLevel/YellowShip.png" id="1_jpes6"] 4 | [ext_resource type="PackedScene" uid="uid://bvoxqi1x6lk52" path="res://Objects/Levels/Enemies/BaseEnemy.tscn" id="1_sghao"] 5 | [ext_resource type="Script" path="res://Scripts/Objects/Enemies/YellowShip.gd" id="2_164y3"] 6 | 7 | [sub_resource type="Animation" id="Animation_m62yt"] 8 | length = 0.001 9 | tracks/0/type = "value" 10 | tracks/0/imported = false 11 | tracks/0/enabled = true 12 | tracks/0/path = NodePath(".:region_rect") 13 | tracks/0/interp = 1 14 | tracks/0/loop_wrap = true 15 | tracks/0/keys = { 16 | "times": PackedFloat32Array(0), 17 | "transitions": PackedFloat32Array(1), 18 | "update": 0, 19 | "values": [Rect2(7, 11, 20, 12)] 20 | } 21 | 22 | [sub_resource type="Animation" id="Animation_xt50m"] 23 | resource_name = "main" 24 | length = 1.6 25 | loop_mode = 1 26 | step = 0.1 27 | tracks/0/type = "value" 28 | tracks/0/imported = false 29 | tracks/0/enabled = true 30 | tracks/0/path = NodePath(".:region_rect") 31 | tracks/0/interp = 0 32 | tracks/0/loop_wrap = true 33 | tracks/0/keys = { 34 | "times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4), 35 | "transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1), 36 | "update": 0, 37 | "values": [Rect2(7, 12, 20, 12), Rect2(32, 8, 20, 12), Rect2(54, 6, 20, 16), Rect2(75, 7, 20, 16), Rect2(97, 8, 20, 16), Rect2(117, 8, 20, 16), Rect2(7, 26, 18, 16), Rect2(26, 28, 18, 16)] 38 | } 39 | 40 | [sub_resource type="AnimationLibrary" id="AnimationLibrary_lcmgl"] 41 | _data = { 42 | "RESET": SubResource("Animation_m62yt"), 43 | "main": SubResource("Animation_xt50m") 44 | } 45 | 46 | [node name="YellowShip" instance=ExtResource("1_sghao")] 47 | script = ExtResource("2_164y3") 48 | 49 | [node name="HealthComponent" parent="." index="0"] 50 | max_value = 2.0 51 | 52 | [node name="Sprite" type="Sprite2D" parent="." index="3"] 53 | texture = ExtResource("1_jpes6") 54 | region_enabled = true 55 | region_rect = Rect2(7, 11, 20, 12) 56 | 57 | [node name="AnimationPlayer" type="AnimationPlayer" parent="." index="4"] 58 | root_node = NodePath("../Sprite") 59 | libraries = { 60 | "": SubResource("AnimationLibrary_lcmgl") 61 | } 62 | 63 | [connection signal="attacked" from="AttackComponent" to="." method="_on_attack_component_attacked"] 64 | -------------------------------------------------------------------------------- /Scripts/SaveManager.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | const SETTINGS_PATH = "user://settings.cfg" 4 | const SAVE_FILE_PATH = "user://save.cfg" 5 | const SAVE_FILE_PASS = "Godotzilla" # Change this in your game!!! 6 | 7 | var save_slot_id := -1 # -1 means no save 8 | var save_data := { 9 | "board_id": "", 10 | "board_data": {}, 11 | "score": 0, 12 | } 13 | 14 | #region Settings 15 | 16 | func _ready() -> void: 17 | var file := load_settings_file() 18 | 19 | VideoSettings.load_video_settings(file) 20 | SoundSettings.load_sound_settings(file) 21 | ControlsSettings.init_controls() 22 | ControlsSettings.load_mapping(file) 23 | 24 | func _process(_delta: float) -> void: 25 | if Input.is_action_just_pressed("ResetControls"): 26 | InputMap.load_from_project_settings() 27 | var file := load_settings_file() 28 | file.erase_section("Input") 29 | save_settings_file(file) 30 | 31 | func load_settings_file() -> ConfigFile: 32 | var file := ConfigFile.new() 33 | if file.load(SETTINGS_PATH) != OK: 34 | save_settings_file(file) 35 | return file 36 | 37 | func save_settings_file(file: ConfigFile) -> void: 38 | file.save(SETTINGS_PATH) 39 | 40 | #endregion 41 | 42 | #region Save files 43 | 44 | func load_save_data() -> Dictionary: 45 | var config_file := load_save_file() 46 | save_data = config_file.get_value(get_save_slot_section(), "data", {}) 47 | return save_data 48 | 49 | func store_save_data() -> void: 50 | var config_file := load_save_file() 51 | config_file.set_value(get_save_slot_section(), "data", save_data) 52 | store_save_file(config_file) 53 | 54 | func load_save_file() -> ConfigFile: 55 | var file := ConfigFile.new() 56 | if file.load_encrypted_pass(SAVE_FILE_PATH, get_save_password()) != OK: 57 | store_save_file(file) 58 | return file 59 | 60 | func store_save_file(file: ConfigFile) -> void: 61 | if save_slot_id >= 0: 62 | file.save_encrypted_pass(SAVE_FILE_PATH, get_save_password()) 63 | 64 | func set_save_slot(id: int) -> void: 65 | save_slot_id = id 66 | 67 | func get_save_slot_section() -> String: 68 | return "save" + str(save_slot_id+1) 69 | 70 | func get_save_password() -> String: 71 | # We tried to prevent other people from sending their 72 | # save files to other people 73 | # Like imagine if someone completed the game and sent other 74 | # people their save file 75 | # So we also use (hopefully) user-unique home directory 76 | return SAVE_FILE_PASS + OS.get_user_data_dir() 77 | 78 | #endregion 79 | -------------------------------------------------------------------------------- /Scenes/Boards/TheEarth.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=8 format=4 uid="uid://blo8x6bqjbe1w"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://d2do8ilhab482" path="res://Scenes/Boards/BaseBoard.tscn" id="1_swyd4"] 4 | [ext_resource type="AudioStream" uid="uid://ij42lx3rq1l1" path="res://Audio/Soundtrack/Earth.ogg" id="2_qcs5w"] 5 | [ext_resource type="PackedScene" uid="uid://dhm8bcemuwqfo" path="res://Scenes/Levels/Wilderness.tscn" id="2_sgm5j"] 6 | [ext_resource type="PackedScene" uid="uid://slv0bn0tcyna" path="res://Scenes/Boards/Jupiter.tscn" id="3_npn5c"] 7 | [ext_resource type="PackedScene" uid="uid://bdbahbhfgy3yt" path="res://Scenes/Levels/TransitionLevel.tscn" id="5_vaw1m"] 8 | [ext_resource type="PackedScene" uid="uid://cavxehselt3he" path="res://Objects/Boards/Piece.tscn" id="6_vncvx"] 9 | [ext_resource type="PackedScene" uid="uid://df3jptqtpl75u" path="res://Scenes/Bosses/Mothra.tscn" id="7_ng0gx"] 10 | 11 | [node name="Board" instance=ExtResource("1_swyd4")] 12 | board_name = "The Earth" 13 | music = ExtResource("2_qcs5w") 14 | next_scene = ExtResource("3_npn5c") 15 | board_id = "earth" 16 | levels = Array[PackedScene]([ExtResource("2_sgm5j"), ExtResource("2_sgm5j"), ExtResource("5_vaw1m")]) 17 | 18 | [node name="Board Icons" parent="Board" index="1"] 19 | tile_map_data = PackedByteArray("AAAAAAAAAQAAAAAAAAABAAEAAQAAAAAAAAABAAIAAQAAAAAAAAAAAAEAAQAAAAAAAAACAAEAAQAAAAAAAAACAAIAAQAAAAAAAAACAAMAAQABAAAAAAABAAMAAQAAAAAAAAAAAAIAAQAAAAAAAAACAAQAAQABAAAAAAABAAQAAQAAAAAAAAAFAAEAAQAAAAAAAAAEAAEAAQAAAAAAAAAEAAIAAQAAAAAAAAADAAIAAQAAAAAAAAADAAMAAQAAAAAAAAADAAUAAQABAAAAAAADAAQAAQABAAAAAAAEAAMAAQAAAAAAAAAEAAQAAQAAAAAAAAAFAAQAAQACAAAAAAAGAAMAAQACAAAAAAAGAAIAAQAAAAAAAAAFAAIAAQAAAAAAAAAFAAMAAQAAAAAAAAAGAAQAAQACAAAAAAAFAAUAAQACAAAAAAA=") 20 | 21 | [node name="Godzilla2" parent="Board/Board Icons/Board Pieces" index="1" instance=ExtResource("6_vncvx")] 22 | position = Vector2(208, 152) 23 | scale = Vector2(-1, 1) 24 | region_rect = Rect2(0, 96, 48, 48) 25 | piece_character = 1 26 | piece_type = 1 27 | boss_scene = ExtResource("7_ng0gx") 28 | 29 | [node name="Mothra" parent="Board/Board Icons/Board Pieces" index="2" instance=ExtResource("6_vncvx")] 30 | position = Vector2(16, 56) 31 | region_rect = Rect2(0, 96, 48, 48) 32 | piece_character = 1 33 | 34 | [node name="Mothra2" parent="Board/Board Icons/Board Pieces" index="3" instance=ExtResource("6_vncvx")] 35 | position = Vector2(112, 104) 36 | scale = Vector2(-1, 1) 37 | region_rect = Rect2(0, 96, 48, 48) 38 | piece_character = 1 39 | piece_type = 1 40 | boss_scene = ExtResource("7_ng0gx") 41 | -------------------------------------------------------------------------------- /Scenes/MainMenu/SaveSlot.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=3 uid="uid://bishkusg7nuhs"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://c5trtmb05sfr4" path="res://Sprites/PassWordGame.png" id="1_lyp2j"] 4 | [ext_resource type="Script" path="res://Scripts/MainMenu/SaveSlot.gd" id="2_han8w"] 5 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="3_6dxk1"] 6 | 7 | [sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_cnspg"] 8 | size = Vector2(32, 32) 9 | 10 | [node name="SaveSlot" type="Control"] 11 | layout_mode = 3 12 | anchors_preset = 0 13 | offset_right = 40.0 14 | offset_bottom = 40.0 15 | script = ExtResource("2_han8w") 16 | 17 | [node name="Border" type="NinePatchRect" parent="."] 18 | layout_mode = 0 19 | offset_right = 192.0 20 | offset_bottom = 48.0 21 | texture = ExtResource("1_lyp2j") 22 | draw_center = false 23 | patch_margin_left = 8 24 | patch_margin_top = 8 25 | patch_margin_right = 8 26 | patch_margin_bottom = 8 27 | 28 | [node name="SaveExists" type="Node2D" parent="."] 29 | 30 | [node name="PlanetIcon" type="TextureRect" parent="SaveExists"] 31 | offset_left = 152.0 32 | offset_top = 8.0 33 | offset_right = 184.0 34 | offset_bottom = 40.0 35 | texture = SubResource("PlaceholderTexture2D_cnspg") 36 | 37 | [node name="SaveID" type="Label" parent="SaveExists" groups=["option"]] 38 | offset_left = 72.0 39 | offset_top = 16.0 40 | offset_right = 120.0 41 | offset_bottom = 32.0 42 | theme_override_fonts/font = ExtResource("3_6dxk1") 43 | text = "save 1" 44 | uppercase = true 45 | metadata/_edit_use_anchors_ = true 46 | 47 | [node name="PlanetName" type="Label" parent="SaveExists" groups=["option"]] 48 | offset_left = 48.0 49 | offset_top = 24.0 50 | offset_right = 144.0 51 | offset_bottom = 40.0 52 | theme_override_fonts/font = ExtResource("3_6dxk1") 53 | text = "the earth" 54 | horizontal_alignment = 1 55 | uppercase = true 56 | metadata/_edit_use_anchors_ = true 57 | 58 | [node name="DoesntExist" type="Node2D" parent="."] 59 | position = Vector2(0, 24) 60 | 61 | [node name="SaveID" type="Label" parent="DoesntExist" groups=["option"]] 62 | offset_left = 72.0 63 | offset_top = -8.0 64 | offset_right = 120.0 65 | offset_bottom = 8.0 66 | theme_override_fonts/font = ExtResource("3_6dxk1") 67 | text = "save 1" 68 | uppercase = true 69 | 70 | [node name="Empty" type="Label" parent="DoesntExist" groups=["option"]] 71 | offset_left = 72.0 72 | offset_right = 120.0 73 | offset_bottom = 16.0 74 | theme_override_fonts/font = ExtResource("3_6dxk1") 75 | text = "empty" 76 | uppercase = true 77 | -------------------------------------------------------------------------------- /Scripts/MainMenu/SoundSettings.gd: -------------------------------------------------------------------------------- 1 | class_name SoundSettings 2 | extends "res://Scripts/MainMenu/Menu.gd" 3 | 4 | # Section in the save file 5 | const SECTION = "Sound" 6 | 7 | const SFX_BUS = 1 8 | const MUSIC_BUS = 2 9 | 10 | @onready var sfx_test: AudioStreamPlayer = $SFXTest 11 | var sfx_volume := 100 12 | var music_volume := 100 13 | 14 | func _ready() -> void: 15 | super._ready() 16 | var file := SaveManager.load_settings_file() 17 | sfx_volume = file.get_value(SECTION, "sfx", 100) 18 | $SFXVolume.text = "sfx volume: " + str(sfx_volume) 19 | music_volume = file.get_value(SECTION, "music", 100) 20 | $MusicVolume.text = "music volume: " + str(music_volume) 21 | 22 | func menu_select(id: int) -> void: 23 | if id == 2: 24 | main_menu.set_menu(%Settings) 25 | 26 | func menu_exit() -> void: 27 | save_sound_settings() 28 | 29 | func _process(_delta: float) -> void: 30 | match main_menu.selector_option: 31 | 0: # SFX volume 32 | if Input.is_action_just_pressed("Left"): 33 | sfx_volume = max(sfx_volume - 10, 0) 34 | update_sfx_volume() 35 | 36 | if Input.is_action_just_pressed("Right"): 37 | sfx_volume = min(sfx_volume + 10, 100) 38 | update_sfx_volume() 39 | 1: # Music volume 40 | if Input.is_action_just_pressed("Left"): 41 | music_volume = max(music_volume - 10, 0) 42 | update_music_volume() 43 | 44 | if Input.is_action_just_pressed("Right"): 45 | music_volume = min(music_volume + 10, 100) 46 | update_music_volume() 47 | 48 | func update_sfx_volume() -> void: 49 | $SFXVolume.text = "sfx volume: " + str(sfx_volume) 50 | AudioServer.set_bus_volume_db(SFX_BUS, 51 | SoundSettings.volume_db_from_save(sfx_volume)) 52 | sfx_test.bus = "SFX" 53 | sfx_test.play() 54 | 55 | func update_music_volume() -> void: 56 | $MusicVolume.text = "music volume: " + str(music_volume) 57 | AudioServer.set_bus_volume_db(MUSIC_BUS, 58 | SoundSettings.volume_db_from_save(music_volume)) 59 | sfx_test.bus = "Music" 60 | sfx_test.play() 61 | 62 | func save_sound_settings() -> void: 63 | var file := SaveManager.load_settings_file() 64 | file.set_value(SECTION, "sfx", sfx_volume) 65 | file.set_value(SECTION, "music", music_volume) 66 | SaveManager.save_settings_file(file) 67 | 68 | static func load_sound_settings(file: ConfigFile) -> void: 69 | AudioServer.set_bus_volume_db(SFX_BUS, 70 | volume_db_from_save(file.get_value(SECTION, "sfx", 100))) 71 | AudioServer.set_bus_volume_db(MUSIC_BUS, 72 | volume_db_from_save(file.get_value(SECTION, "music", 100))) 73 | 74 | static func volume_db_from_save(value: int) -> int: 75 | return roundi((value - 100) * 0.8) 76 | -------------------------------------------------------------------------------- /Scripts/GameIntro/GameIntro.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | const TEXT_SPEED := 1 * 60 4 | 5 | @export var next_scene: PackedScene 6 | 7 | @onready var story_text := $Bars/StoryText 8 | @onready var images: Node2D = $Images 9 | @onready var bars: Node2D = $Bars 10 | @onready var image_change_timer: Timer = $ImageChangeTimer 11 | 12 | var started := false 13 | var finished := false 14 | var image_count := 0 15 | var current_image := 0 16 | 17 | func _ready() -> void: 18 | RenderingServer.set_default_clear_color(Color.BLACK) 19 | for bar: Node in [$Bars/Bar1, $Bars/Bar2]: 20 | bar.size.x = Global.get_default_resolution().x 21 | setup_widescreen_bars() 22 | 23 | story_text.text = FileAccess.open("res://Other/GameIntroText.txt", FileAccess.READ) \ 24 | .get_as_text().replace('\n', '').replace('\r', '') 25 | images.visible = false 26 | image_count = images.get_child_count() 27 | 28 | Global.play_music(preload("res://Audio/Soundtrack/Mars.ogg")) 29 | Global.fade_in() 30 | await get_tree().create_timer(1, false).timeout 31 | started = true 32 | 33 | bars.reparent(Global.main.canvas_layer) 34 | Global.fade_in() 35 | Global.show_fade() 36 | show_current_image() 37 | images.visible = true 38 | 39 | func _process(delta: float) -> void: 40 | if not started: 41 | return 42 | 43 | story_text.position.x -= TEXT_SPEED * delta 44 | if Global.any_action_button_pressed(): 45 | finish() 46 | 47 | func setup_widescreen_bars() -> void: 48 | var bar1: Control = $Bars/WidescreenBar1 49 | var bar2: Control = $Bars/WidescreenBar2 50 | bar1.position.x = -(Global.get_content_size().x - Global.get_default_resolution().x) / 2 - 1 51 | bar1.size.x = -bar1.position.x 52 | bar1.size.y = Global.get_content_size().y 53 | bar2.position.x = Global.get_default_resolution().x 54 | bar2.size = bar1.size 55 | 56 | func show_current_image() -> void: 57 | images.get_children().map(func(img: Node2D) -> void: 58 | img.visible = false 59 | img.set_process(false) 60 | ) 61 | var current_sequence := images.get_child(current_image) 62 | current_sequence.visible = true 63 | current_sequence.set_process(true) 64 | 65 | func next_image() -> void: 66 | if current_image < (image_count-1): 67 | await Global.fade_out() 68 | current_image += 1 69 | await get_tree().create_timer(0.5, false).timeout 70 | show_current_image() 71 | Global.fade_in() 72 | else: 73 | finish() 74 | 75 | func finish() -> void: 76 | if finished: return 77 | finished = true 78 | 79 | bars.reparent(self) 80 | Global.music_fade_out() 81 | await Global.fade_out() 82 | await get_tree().create_timer(0.5, false).timeout 83 | Global.change_scene(next_scene) 84 | -------------------------------------------------------------------------------- /Scripts/Objects/AttackComponent.gd: -------------------------------------------------------------------------------- 1 | class_name AttackComponent 2 | extends Node2D 3 | 4 | ## Always keep checking for other bodies in the attack component and attack them 5 | @export var attack_always := false 6 | @export var default_attack_amount := 4.0 7 | @export var default_hurt_time := -1.0 8 | @export var objects_to_ignore: Array[Node2D] 9 | ## Allow the attack component to attack at all 10 | @export var should_attack := true 11 | ## Set to true if this attack component belongs to an enemy, 12 | ## otherwise false if it belongs to a player/not enemy 13 | @export var enemy := false 14 | 15 | @onready var area_2d: Area2D = $Area2D 16 | @onready var collision: CollisionShape2D = $Area2D/CollisionShape2D 17 | 18 | # We don't want to attack a body multiple times in the same attack 19 | var attacked_bodies: Array[Node2D] = [] 20 | 21 | signal attacked(body: Node2D, amount: float) 22 | 23 | func _ready() -> void: 24 | collision.shape = collision.shape.duplicate() 25 | collision.shape.size = Vector2.ZERO 26 | if not attack_always: 27 | attack_bodies() 28 | area_2d.body_entered.connect(_on_area_2d_body_entered) 29 | 30 | func _process(_delta: float) -> void: 31 | if attack_always: 32 | attack_bodies() 33 | 34 | func attack_bodies(amount := default_attack_amount, hurt_time := default_hurt_time) -> void: 35 | var bodies := area_2d.get_overlapping_bodies() 36 | for body in bodies: 37 | attack_body(body, amount, hurt_time) 38 | 39 | func attack_body(body: Node2D, 40 | amount := default_attack_amount, 41 | hurt_time := default_hurt_time) -> void: 42 | if body == get_parent() or body in objects_to_ignore or not should_attack: 43 | return 44 | if body.has_node("HealthComponent") and (enemy != body.get_node("HealthComponent").enemy) \ 45 | and body not in attacked_bodies: 46 | body.get_node("HealthComponent").damage(amount, hurt_time) 47 | attacked.emit(body, amount) 48 | attacked_bodies.append(body) 49 | 50 | func set_collision(size: Vector2, offset: Vector2) -> void: 51 | collision.shape.size = size 52 | collision.position = offset 53 | 54 | # The next 2 functions are useful for attack moves of a player or a boss 55 | 56 | func start_attack(amount: float, hurt_time := -1.0) -> void: 57 | attack_always = true 58 | should_attack = true 59 | default_attack_amount = amount 60 | default_hurt_time = hurt_time 61 | attacked_bodies.clear() 62 | 63 | func stop_attack() -> void: 64 | attack_always = false 65 | should_attack = false 66 | attacked_bodies.clear() 67 | collision.shape.size = Vector2.ZERO 68 | collision.position = Vector2.ZERO 69 | 70 | func _on_area_2d_body_entered(body: Node2D) -> void: 71 | attack_body(body) 72 | -------------------------------------------------------------------------------- /Objects/Levels/TestLevel/BreakableMountain.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=3 uid="uid://1q6rp0t4rh72"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/Objects/Levels/TestLevel/BreakableMountain.gd" id="1_oxw1c"] 4 | [ext_resource type="Texture2D" uid="uid://c1x100m2wxobm" path="res://Sprites/Levels/TestLevel/GodzillaMoMWilderness.png" id="1_ppbww"] 5 | [ext_resource type="PackedScene" uid="uid://camascwoory5h" path="res://Objects/HealthComponent.tscn" id="2_k6k24"] 6 | 7 | [sub_resource type="RectangleShape2D" id="RectangleShape2D_gssje"] 8 | size = Vector2(32, 48) 9 | 10 | [sub_resource type="RectangleShape2D" id="RectangleShape2D_mnffa"] 11 | size = Vector2(16, 16) 12 | 13 | [sub_resource type="RectangleShape2D" id="RectangleShape2D_1lues"] 14 | size = Vector2(16, 24) 15 | 16 | [node name="BreakableMountain" type="StaticBody2D"] 17 | collision_layer = 2 18 | script = ExtResource("1_oxw1c") 19 | 20 | [node name="CollisionShape2D" type="CollisionShape2D" parent="."] 21 | position = Vector2(0, -24) 22 | shape = SubResource("RectangleShape2D_gssje") 23 | debug_color = Color(0.587198, 0.518021, 0.504798, 0.42) 24 | 25 | [node name="TopPart" type="StaticBody2D" parent="."] 26 | position = Vector2(1, -36) 27 | 28 | [node name="Sprite" type="Sprite2D" parent="TopPart"] 29 | texture = ExtResource("1_ppbww") 30 | region_enabled = true 31 | region_rect = Rect2(403, 22, 18, 30) 32 | 33 | [node name="HealthComponent" parent="TopPart" instance=ExtResource("2_k6k24")] 34 | max_value = 4.0 35 | enemy = true 36 | health_speed = 0.2 37 | 38 | [node name="CollisionShape2D" type="CollisionShape2D" parent="TopPart"] 39 | position = Vector2(-1, -4) 40 | shape = SubResource("RectangleShape2D_mnffa") 41 | 42 | [node name="BottomPart" type="StaticBody2D" parent="."] 43 | position = Vector2(1, -14) 44 | 45 | [node name="Sprite" type="Sprite2D" parent="BottomPart"] 46 | texture = ExtResource("1_ppbww") 47 | region_enabled = true 48 | region_rect = Rect2(394, 60, 34, 30) 49 | 50 | [node name="HealthComponent" parent="BottomPart" instance=ExtResource("2_k6k24")] 51 | max_value = 4.0 52 | enemy = true 53 | health_speed = 0.2 54 | 55 | [node name="CollisionShape2D" type="CollisionShape2D" parent="BottomPart"] 56 | position = Vector2(-1, 2) 57 | shape = SubResource("RectangleShape2D_1lues") 58 | 59 | [connection signal="damaged" from="TopPart/HealthComponent" to="." method="_on_top_health_damaged"] 60 | [connection signal="dead" from="TopPart/HealthComponent" to="." method="_on_top_health_dead"] 61 | [connection signal="damaged" from="BottomPart/HealthComponent" to="." method="_on_bottom_health_damaged"] 62 | [connection signal="dead" from="BottomPart/HealthComponent" to="." method="_on_bottom_health_dead"] 63 | -------------------------------------------------------------------------------- /Objects/Characters/MothraParticle.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=10 format=3 uid="uid://wk0ngrdkwnbv"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://di5yqmheu2g18" path="res://Sprites/Characters/Mothra/particles.png" id="1_ok31u"] 4 | [ext_resource type="Script" path="res://Scripts/Objects/Characters/MothraParticle.gd" id="2_v1kq8"] 5 | [ext_resource type="PackedScene" uid="uid://bi7wq6b7la5ki" path="res://Objects/AttackComponent.tscn" id="3_f4212"] 6 | 7 | [sub_resource type="AtlasTexture" id="AtlasTexture_5tse6"] 8 | atlas = ExtResource("1_ok31u") 9 | region = Rect2(0, 12, 9, 8) 10 | 11 | [sub_resource type="AtlasTexture" id="AtlasTexture_akx7u"] 12 | atlas = ExtResource("1_ok31u") 13 | region = Rect2(0, 24, 48, 13) 14 | 15 | [sub_resource type="SpriteFrames" id="SpriteFrames_8dfex"] 16 | animations = [{ 17 | "frames": [{ 18 | "duration": 1.0, 19 | "texture": SubResource("AtlasTexture_5tse6") 20 | }], 21 | "loop": true, 22 | "name": &"EyeBeam", 23 | "speed": 5.0 24 | }, { 25 | "frames": [{ 26 | "duration": 1.0, 27 | "texture": SubResource("AtlasTexture_akx7u") 28 | }], 29 | "loop": true, 30 | "name": &"Wing", 31 | "speed": 5.0 32 | }] 33 | 34 | [sub_resource type="Animation" id="Animation_yy0va"] 35 | resource_name = "Flash" 36 | length = 0.04 37 | loop_mode = 1 38 | step = 0.02 39 | tracks/0/type = "value" 40 | tracks/0/imported = false 41 | tracks/0/enabled = true 42 | tracks/0/path = NodePath(".:visible") 43 | tracks/0/interp = 1 44 | tracks/0/loop_wrap = true 45 | tracks/0/keys = { 46 | "times": PackedFloat32Array(0, 0.02), 47 | "transitions": PackedFloat32Array(1, 1), 48 | "update": 1, 49 | "values": [true, false] 50 | } 51 | 52 | [sub_resource type="Animation" id="Animation_o8vym"] 53 | length = 0.001 54 | tracks/0/type = "value" 55 | tracks/0/imported = false 56 | tracks/0/enabled = true 57 | tracks/0/path = NodePath(".:visible") 58 | tracks/0/interp = 1 59 | tracks/0/loop_wrap = true 60 | tracks/0/keys = { 61 | "times": PackedFloat32Array(0), 62 | "transitions": PackedFloat32Array(1), 63 | "update": 1, 64 | "values": [true] 65 | } 66 | 67 | [sub_resource type="AnimationLibrary" id="AnimationLibrary_4aq1u"] 68 | _data = { 69 | "Flash": SubResource("Animation_yy0va"), 70 | "RESET": SubResource("Animation_o8vym") 71 | } 72 | 73 | [node name="MothraParticle" type="AnimatedSprite2D"] 74 | sprite_frames = SubResource("SpriteFrames_8dfex") 75 | animation = &"Wing" 76 | script = ExtResource("2_v1kq8") 77 | 78 | [node name="Timer" type="Timer" parent="."] 79 | 80 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."] 81 | libraries = { 82 | "": SubResource("AnimationLibrary_4aq1u") 83 | } 84 | 85 | [node name="AttackComponent" parent="." instance=ExtResource("3_f4212")] 86 | default_attack_amount = 2.0 87 | -------------------------------------------------------------------------------- /Scripts/Credits.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | @export var music: AudioStream 4 | @onready var text_node: RichTextLabel = $CenterContainer/TextNode 5 | @onready var licensing: Label = $Licensing 6 | var current_text := 0 7 | var texts: Array[String] 8 | 9 | func _ready() -> void: 10 | RenderingServer.set_default_clear_color(Color.BLACK) 11 | $CenterContainer.size = Vector2(Global.get_default_resolution()) 12 | 13 | texts.assign(Array(FileAccess.open("res://Other/Credits.txt", FileAccess.READ) \ 14 | .get_as_text().split("==")).map(func(i: String) -> String: return i.strip_edges())) 15 | 16 | licensing.hide() 17 | licensing.position.y = Global.get_content_size().y 18 | 19 | Global.play_music(music) 20 | display_text() 21 | Global.fade_in() 22 | 23 | func _process(delta: float) -> void: 24 | if not Global.is_fading(): 25 | if Global.any_action_button_pressed(): 26 | next_text() 27 | elif Input.is_action_just_pressed("Exit"): 28 | exit() 29 | 30 | if licensing.visible: 31 | var diry := signf(Input.get_axis("Up", "Down")) 32 | var speed := 1 if is_zero_approx(diry) else 6 if diry > 0.4 else 0 33 | licensing.position.y -= speed * 60 * delta 34 | 35 | func display_text() -> void: 36 | if current_text == texts.size(): 37 | text_node.text = "" 38 | await get_tree().create_timer(0.1).timeout 39 | prepare_licensing_text() 40 | return 41 | var text := "[center]%s[/center]" % texts[current_text] 42 | text_node.text = text 43 | 44 | func prepare_licensing_text() -> void: 45 | var result := FileAccess.open("res://LICENSE", FileAccess.READ).get_as_text() 46 | 47 | result += "\n" + Engine.get_license_text() 48 | result += "\nGodot Engine also uses third-party libraries, 49 | the next list includes the licensed files and their respective licenses:\n" 50 | 51 | for copyright in Engine.get_copyright_info(): 52 | result += "Name: %s, parts:\n" % copyright["name"] 53 | for part in copyright["parts"]: 54 | result += "- files: %s 55 | - copyright: %s 56 | - license: %s 57 | 58 | " % [", ".join(part["files"]), ", ".join(part["copyright"]), part["license"]] 59 | 60 | result += "Now the actual licenses texts:\n" 61 | 62 | var license_dict := Engine.get_license_info() 63 | for license_name in license_dict: 64 | result += "Name: %s, contents:\n%s\n" % [license_name, license_dict[license_name]] 65 | 66 | licensing.show() 67 | licensing.text = result 68 | 69 | 70 | func next_text() -> void: 71 | current_text += 1 72 | if current_text >= texts.size() + 1: 73 | exit() 74 | return 75 | else: 76 | await Global.fade_out() 77 | display_text() 78 | await Global.fade_in() 79 | 80 | func exit() -> void: 81 | get_tree().paused = true 82 | Global.music_fade_out() 83 | await Global.fade_out() 84 | 85 | await get_tree().create_timer(0.5).timeout 86 | 87 | get_tree().paused = false 88 | Global.hide_fade() 89 | Global.change_scene(Global.get_initial_scene()) 90 | -------------------------------------------------------------------------------- /Objects/Levels/Capsule.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=9 format=3 uid="uid://hos7shkktc1k"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://c1n8vhgw5br0w" path="res://Sprites/Objects/capsules.png" id="1_0f167"] 4 | [ext_resource type="Script" path="res://Scripts/Objects/Capsule.gd" id="2_74wkk"] 5 | [ext_resource type="AudioStream" uid="uid://btqycedtut0o6" path="res://Audio/SFX/Capsule.wav" id="3_eegh8"] 6 | 7 | [sub_resource type="Animation" id="Animation_5m62m"] 8 | length = 0.001 9 | tracks/0/type = "value" 10 | tracks/0/imported = false 11 | tracks/0/enabled = true 12 | tracks/0/path = NodePath(".:frame") 13 | tracks/0/interp = 1 14 | tracks/0/loop_wrap = true 15 | tracks/0/keys = { 16 | "times": PackedFloat32Array(0), 17 | "transitions": PackedFloat32Array(1), 18 | "update": 1, 19 | "values": [0] 20 | } 21 | 22 | [sub_resource type="Animation" id="Animation_c4ftu"] 23 | resource_name = "health" 24 | length = 0.24 25 | loop_mode = 1 26 | step = 0.01 27 | tracks/0/type = "value" 28 | tracks/0/imported = false 29 | tracks/0/enabled = true 30 | tracks/0/path = NodePath(".:frame") 31 | tracks/0/interp = 1 32 | tracks/0/loop_wrap = true 33 | tracks/0/keys = { 34 | "times": PackedFloat32Array(0, 0.12), 35 | "transitions": PackedFloat32Array(1, 1), 36 | "update": 1, 37 | "values": [0, 1] 38 | } 39 | 40 | [sub_resource type="Animation" id="Animation_um106"] 41 | resource_name = "power" 42 | length = 0.24 43 | loop_mode = 1 44 | step = 0.01 45 | tracks/0/type = "value" 46 | tracks/0/imported = false 47 | tracks/0/enabled = true 48 | tracks/0/path = NodePath(".:frame") 49 | tracks/0/interp = 1 50 | tracks/0/loop_wrap = true 51 | tracks/0/keys = { 52 | "times": PackedFloat32Array(0, 0.12), 53 | "transitions": PackedFloat32Array(1, 1), 54 | "update": 1, 55 | "values": [2, 3] 56 | } 57 | 58 | [sub_resource type="AnimationLibrary" id="AnimationLibrary_cxuko"] 59 | _data = { 60 | "RESET": SubResource("Animation_5m62m"), 61 | "health": SubResource("Animation_c4ftu"), 62 | "power": SubResource("Animation_um106") 63 | } 64 | 65 | [sub_resource type="RectangleShape2D" id="RectangleShape2D_4xqf8"] 66 | size = Vector2(8, 16) 67 | 68 | [node name="Capsule" type="Sprite2D"] 69 | texture = ExtResource("1_0f167") 70 | hframes = 4 71 | script = ExtResource("2_74wkk") 72 | 73 | [node name="SFX" type="AudioStreamPlayer" parent="."] 74 | stream = ExtResource("3_eegh8") 75 | bus = &"SFX" 76 | 77 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."] 78 | libraries = { 79 | "": SubResource("AnimationLibrary_cxuko") 80 | } 81 | 82 | [node name="Timer" type="Timer" parent="."] 83 | one_shot = true 84 | autostart = true 85 | 86 | [node name="Area2D" type="Area2D" parent="."] 87 | collision_layer = 2 88 | 89 | [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] 90 | shape = SubResource("RectangleShape2D_4xqf8") 91 | 92 | [connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"] 93 | [connection signal="body_entered" from="Area2D" to="." method="_on_area_2d_body_entered"] 94 | -------------------------------------------------------------------------------- /Scripts/Objects/Characters/Walk.gd: -------------------------------------------------------------------------------- 1 | extends State 2 | 3 | # Move state is used for characters that walk on the ground. 4 | # This state consists of not only walking but also crouching and jumping. 5 | # This state also includes the movement for flying characters. 6 | 7 | var walk_frame := 0.0 8 | var walk_frames := 0 9 | var walk_frame_speed := 0 10 | 11 | var jumping := false 12 | var jump_speed := -2 * 60 13 | 14 | func state_init() -> void: 15 | if not parent.is_flying(): 16 | walk_frames = parent.body.sprite_frames.get_frame_count("Walk") 17 | 18 | match parent.character: 19 | PlayerCharacter.Type.GODZILLA: 20 | walk_frame_speed = 9 21 | # # You can change the jumping speed for your character like this 22 | # jump_speed = -1 * 60 23 | 24 | func _process(delta: float) -> void: 25 | move(delta) 26 | 27 | # Attacks 28 | match parent.character: 29 | PlayerCharacter.Type.GODZILLA: 30 | common_ground_attacks() 31 | if parent.animation_player.current_animation == "Crouch" \ 32 | and parent.inputs_pressed[PlayerCharacter.Inputs.B]: 33 | parent.use_attack(PlayerCharacter.Attack.TAIL_WHIP) 34 | if parent.inputs_pressed[PlayerCharacter.Inputs.START] \ 35 | and parent.power.value >= 6 * 8: 36 | parent.use_attack(PlayerCharacter.Attack.HEAT_BEAM) 37 | 38 | func common_ground_attacks() -> void: 39 | if parent.inputs_pressed[PlayerCharacter.Inputs.A]: 40 | parent.use_attack(PlayerCharacter.Attack.PUNCH) 41 | if parent.animation_player.current_animation != "Crouch" \ 42 | and parent.inputs_pressed[PlayerCharacter.Inputs.B]: 43 | parent.use_attack(PlayerCharacter.Attack.KICK) 44 | 45 | func move(delta: float) -> void: 46 | var dirx: float = signf(parent.inputs[PlayerCharacter.Inputs.XINPUT]) 47 | if dirx: 48 | parent.velocity.x = parent.move_speed * dirx 49 | 50 | if parent.allow_direction_changing: 51 | parent.direction = int(signf(dirx)) 52 | 53 | walk_frame = wrapf( 54 | walk_frame + walk_frame_speed * delta * dirx * parent.direction, 55 | 0, walk_frames) 56 | 57 | if parent.body.animation == "Walk": 58 | parent.body.frame = int(walk_frame) 59 | else: 60 | parent.velocity.x = 0 61 | 62 | var diry: float = parent.inputs[PlayerCharacter.Inputs.YINPUT] 63 | 64 | # Jump! 65 | if parent.is_on_floor() and diry < -0.4: 66 | parent.velocity.y = jump_speed 67 | jumping = true 68 | 69 | # Variable jump height 70 | if not parent.is_on_floor() and jumping: 71 | if diry < -0.4 and parent.velocity.y < -1.95 * 60: 72 | parent.velocity.y -= 216 * delta 73 | if parent.velocity.y < 0 and diry >= -0.4: 74 | jumping = false 75 | parent.velocity.y = 0 76 | 77 | # Crouch 78 | if diry > 0.4 and parent.body.sprite_frames.has_animation("Crouch"): 79 | if parent.animation_player.current_animation == "Walk"\ 80 | or parent.animation_player.current_animation == "": 81 | parent.animation_player.play("Crouch") 82 | 83 | if diry <= 0.4 and parent.animation_player.current_animation == "Crouch": 84 | parent.animation_player.play("RESET") 85 | 86 | func reset() -> void: 87 | walk_frame = 0 88 | -------------------------------------------------------------------------------- /Scenes/Main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=8 format=3 uid="uid://du38sf8ro3elu"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/Main.gd" id="1_csd2w"] 4 | [ext_resource type="AudioStream" uid="uid://bgfupmtntcg8x" path="res://Audio/SFX/Pause.wav" id="3_iol3x"] 5 | [ext_resource type="AudioStream" uid="uid://dcy2jbwfd2no" path="res://Audio/SFX/CharHurt.wav" id="3_jlebr"] 6 | [ext_resource type="AudioStream" uid="uid://byy8g0bpfb65s" path="res://Audio/SFX/BlockDestruct.wav" id="4_oop6x"] 7 | 8 | [sub_resource type="Animation" id="Animation_xmtka"] 9 | resource_name = "FadeIn" 10 | length = 0.3 11 | tracks/0/type = "value" 12 | tracks/0/imported = false 13 | tracks/0/enabled = true 14 | tracks/0/path = NodePath("Fader:modulate") 15 | tracks/0/interp = 1 16 | tracks/0/loop_wrap = true 17 | tracks/0/keys = { 18 | "times": PackedFloat32Array(0, 0.1, 0.2, 0.3), 19 | "transitions": PackedFloat32Array(4.43828, 1, 1, 1.2394e-05), 20 | "update": 1, 21 | "values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0.666667), Color(1, 1, 1, 0.333333), Color(1, 1, 1, 0)] 22 | } 23 | 24 | [sub_resource type="Animation" id="Animation_mfy1u"] 25 | length = 0.001 26 | tracks/0/type = "value" 27 | tracks/0/imported = false 28 | tracks/0/enabled = true 29 | tracks/0/path = NodePath("Fader:color") 30 | tracks/0/interp = 1 31 | tracks/0/loop_wrap = true 32 | tracks/0/keys = { 33 | "times": PackedFloat32Array(0), 34 | "transitions": PackedFloat32Array(1), 35 | "update": 0, 36 | "values": [Color(0, 0, 0, 1)] 37 | } 38 | tracks/1/type = "value" 39 | tracks/1/imported = false 40 | tracks/1/enabled = true 41 | tracks/1/path = NodePath("Fader:modulate") 42 | tracks/1/interp = 1 43 | tracks/1/loop_wrap = true 44 | tracks/1/keys = { 45 | "times": PackedFloat32Array(0), 46 | "transitions": PackedFloat32Array(1), 47 | "update": 1, 48 | "values": [Color(1, 1, 1, 1)] 49 | } 50 | 51 | [sub_resource type="AnimationLibrary" id="AnimationLibrary_lb25u"] 52 | _data = { 53 | "FadeIn": SubResource("Animation_xmtka"), 54 | "RESET": SubResource("Animation_mfy1u") 55 | } 56 | 57 | [node name="Main" type="Node2D"] 58 | process_mode = 3 59 | script = ExtResource("1_csd2w") 60 | 61 | [node name="CurrentScene" type="Node2D" parent="."] 62 | process_mode = 1 63 | 64 | [node name="Music" type="AudioStreamPlayer" parent="."] 65 | process_mode = 3 66 | bus = &"Music" 67 | 68 | [node name="CanvasLayer" type="CanvasLayer" parent="."] 69 | process_mode = 3 70 | layer = 10 71 | 72 | [node name="Fader" type="ColorRect" parent="CanvasLayer"] 73 | offset_right = 40.0 74 | offset_bottom = 40.0 75 | color = Color(0, 0, 0, 1) 76 | 77 | [node name="FadePlayer" type="AnimationPlayer" parent="CanvasLayer"] 78 | libraries = { 79 | "": SubResource("AnimationLibrary_lb25u") 80 | } 81 | 82 | [node name="GlobalSFX" type="Node" parent="."] 83 | process_mode = 1 84 | 85 | [node name="Pause" type="AudioStreamPlayer" parent="GlobalSFX"] 86 | process_mode = 3 87 | stream = ExtResource("3_iol3x") 88 | bus = &"SFX" 89 | 90 | [node name="Explosion" type="AudioStreamPlayer" parent="GlobalSFX"] 91 | stream = ExtResource("3_jlebr") 92 | bus = &"SFX" 93 | 94 | [node name="BlockDestruct" type="AudioStreamPlayer" parent="GlobalSFX"] 95 | stream = ExtResource("4_oop6x") 96 | volume_db = 5.0 97 | bus = &"SFX" 98 | -------------------------------------------------------------------------------- /Scenes/MainMenu/PauseMenu.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=8 format=3 uid="uid://cmoopalhh65x1"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://bjcf4tfdeo6ta" path="res://Scenes/MainMenu/BaseMenu.tscn" id="1_3ivqh"] 4 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="4_vods2"] 5 | [ext_resource type="PackedScene" uid="uid://lxs5br5r3336" path="res://Scenes/MainMenu/Settings.tscn" id="5_frcs8"] 6 | [ext_resource type="PackedScene" uid="uid://dy3m74iswj1v" path="res://Scenes/MainMenu/Controls.tscn" id="6_kgulq"] 7 | [ext_resource type="PackedScene" uid="uid://dk6nkw1ue84ow" path="res://Scenes/MainMenu/SoundSettings.tscn" id="7_w1mw8"] 8 | [ext_resource type="PackedScene" uid="uid://bxtvwweer7x10" path="res://Scenes/MainMenu/VideoSettings.tscn" id="8_f0twr"] 9 | 10 | [sub_resource type="GDScript" id="GDScript_mmqcn"] 11 | script/source = "extends \"res://Scripts/MainMenu/Menu.gd\" 12 | 13 | func menu_select(id: int) -> void: 14 | match id: 15 | 0: # Continue 16 | PauseManager.finish_pause() 17 | 1: # Settings 18 | main_menu.set_menu(%Settings) 19 | 2: # Exit 20 | PauseManager.prepare_for_exit() 21 | get_tree().paused = true 22 | 23 | Global.music_fade_out() 24 | Global.fade_out() 25 | await Global.fade_end 26 | main_menu.hide() 27 | 28 | await get_tree().create_timer(0.25).timeout 29 | 30 | get_tree().paused = false 31 | Global.change_scene(preload(\"res://Scenes/MainMenu/MainMenu.tscn\")) 32 | main_menu.queue_free() 33 | " 34 | 35 | [node name="PauseMenu" instance=ExtResource("1_3ivqh")] 36 | process_mode = 2 37 | 38 | [node name="MenuMain" parent="." index="1"] 39 | script = SubResource("GDScript_mmqcn") 40 | 41 | [node name="Pause" type="Label" parent="MenuMain" index="0"] 42 | offset_left = 64.0 43 | offset_top = 80.0 44 | offset_right = 184.0 45 | offset_bottom = 91.0 46 | theme_override_fonts/font = ExtResource("4_vods2") 47 | text = "pause" 48 | horizontal_alignment = 1 49 | uppercase = true 50 | 51 | [node name="Continue" type="Label" parent="MenuMain" index="1" groups=["option"]] 52 | offset_left = 72.0 53 | offset_top = 104.0 54 | offset_right = 184.0 55 | offset_bottom = 115.0 56 | theme_override_fonts/font = ExtResource("4_vods2") 57 | text = "continue" 58 | uppercase = true 59 | 60 | [node name="Settings" type="Label" parent="MenuMain" index="2" groups=["option"]] 61 | offset_left = 72.0 62 | offset_top = 128.0 63 | offset_right = 184.0 64 | offset_bottom = 139.0 65 | theme_override_fonts/font = ExtResource("4_vods2") 66 | text = "settings" 67 | uppercase = true 68 | 69 | [node name="Exit" parent="MenuMain" index="3"] 70 | offset_top = 152.0 71 | offset_bottom = 163.0 72 | 73 | [node name="Settings" parent="." index="2" instance=ExtResource("5_frcs8")] 74 | unique_name_in_owner = true 75 | visible = false 76 | 77 | [node name="Controls" parent="." index="3" instance=ExtResource("6_kgulq")] 78 | unique_name_in_owner = true 79 | visible = false 80 | 81 | [node name="SoundSettings" parent="." index="4" instance=ExtResource("7_w1mw8")] 82 | unique_name_in_owner = true 83 | visible = false 84 | 85 | [node name="VideoSettings" parent="." index="5" instance=ExtResource("8_f0twr")] 86 | unique_name_in_owner = true 87 | visible = false 88 | include_widescreen = false 89 | -------------------------------------------------------------------------------- /Objects/Levels/Enemies/RocketLauncherRocket.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=9 format=3 uid="uid://kd587533e5l4"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://dnubo4iltw3px" path="res://Sprites/Objects/Enemies/RocketLauncherRocket.png" id="1_0euw7"] 4 | [ext_resource type="Script" path="res://Scripts/Objects/Enemies/RocketLauncherRocket.gd" id="1_1tm2y"] 5 | [ext_resource type="PackedScene" uid="uid://bi7wq6b7la5ki" path="res://Objects/AttackComponent.tscn" id="3_y14pf"] 6 | [ext_resource type="AudioStream" uid="uid://dcy2jbwfd2no" path="res://Audio/SFX/CharHurt.wav" id="4_7tx0r"] 7 | 8 | [sub_resource type="Animation" id="Animation_s4816"] 9 | length = 0.001 10 | tracks/0/type = "value" 11 | tracks/0/imported = false 12 | tracks/0/enabled = true 13 | tracks/0/path = NodePath("Sprite:frame") 14 | tracks/0/interp = 1 15 | tracks/0/loop_wrap = true 16 | tracks/0/keys = { 17 | "times": PackedFloat32Array(0), 18 | "transitions": PackedFloat32Array(1), 19 | "update": 1, 20 | "values": [0] 21 | } 22 | tracks/1/type = "value" 23 | tracks/1/imported = false 24 | tracks/1/enabled = true 25 | tracks/1/path = NodePath("Sprite:flip_v") 26 | tracks/1/interp = 1 27 | tracks/1/loop_wrap = true 28 | tracks/1/keys = { 29 | "times": PackedFloat32Array(0), 30 | "transitions": PackedFloat32Array(1), 31 | "update": 1, 32 | "values": [false] 33 | } 34 | 35 | [sub_resource type="Animation" id="Animation_jrg5h"] 36 | resource_name = "going_down" 37 | length = 2.0 38 | tracks/0/type = "value" 39 | tracks/0/imported = false 40 | tracks/0/enabled = true 41 | tracks/0/path = NodePath("Sprite:frame") 42 | tracks/0/interp = 1 43 | tracks/0/loop_wrap = true 44 | tracks/0/keys = { 45 | "times": PackedFloat32Array(0, 0.2, 0.4, 0.8, 1), 46 | "transitions": PackedFloat32Array(1, 1, 1, 1, 1), 47 | "update": 1, 48 | "values": [0, 1, 2, 1, 0] 49 | } 50 | tracks/1/type = "value" 51 | tracks/1/imported = false 52 | tracks/1/enabled = true 53 | tracks/1/path = NodePath("Sprite:flip_v") 54 | tracks/1/interp = 1 55 | tracks/1/loop_wrap = true 56 | tracks/1/keys = { 57 | "times": PackedFloat32Array(0, 0.6), 58 | "transitions": PackedFloat32Array(1, 1), 59 | "update": 1, 60 | "values": [false, true] 61 | } 62 | 63 | [sub_resource type="AnimationLibrary" id="AnimationLibrary_vwlvx"] 64 | _data = { 65 | "RESET": SubResource("Animation_s4816"), 66 | "going_down": SubResource("Animation_jrg5h") 67 | } 68 | 69 | [sub_resource type="RectangleShape2D" id="RectangleShape2D_px6nh"] 70 | size = Vector2(16, 16) 71 | 72 | [node name="RocketLauncherRocket" type="Node2D"] 73 | script = ExtResource("1_1tm2y") 74 | 75 | [node name="Sprite" type="Sprite2D" parent="."] 76 | texture = ExtResource("1_0euw7") 77 | hframes = 3 78 | 79 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."] 80 | libraries = { 81 | "": SubResource("AnimationLibrary_vwlvx") 82 | } 83 | 84 | [node name="AttackComponent" parent="." instance=ExtResource("3_y14pf")] 85 | enemy = true 86 | 87 | [node name="CollisionShape2D" parent="AttackComponent/Area2D" index="0"] 88 | shape = SubResource("RectangleShape2D_px6nh") 89 | 90 | [node name="DestroySFX" type="AudioStreamPlayer" parent="."] 91 | stream = ExtResource("4_7tx0r") 92 | bus = &"SFX" 93 | 94 | [connection signal="attacked" from="AttackComponent" to="." method="_on_attack_component_attacked"] 95 | 96 | [editable path="AttackComponent"] 97 | -------------------------------------------------------------------------------- /Scripts/MainMenu/VideoSettings.gd: -------------------------------------------------------------------------------- 1 | class_name VideoSettings 2 | extends "res://Scripts/MainMenu/Menu.gd" 3 | 4 | # Section in the save file 5 | const SECTION := "Video" 6 | const RESOLUTIONS := [1, 2, 3, 4, -1] 7 | 8 | @export var include_widescreen := true 9 | var current_resolution := 2 10 | 11 | func _ready() -> void: 12 | super._ready() 13 | var widescreen_node := $Widescreen 14 | 15 | if not include_widescreen: 16 | options.erase(widescreen_node) 17 | widescreen_node.queue_free() 18 | $Exit.position.y -= 24 19 | 20 | Global.fullscreen_changed.connect(func(flag: bool) -> void: 21 | if flag: 22 | $Resolution.text = "resolution: full screen" 23 | else: 24 | current_resolution = min(3, current_resolution) 25 | update_resolution() 26 | ) 27 | 28 | var file := SaveManager.load_settings_file() 29 | widescreen_node.text = "wide screen: " + \ 30 | ("on" if file.get_value(SECTION, "widescreen", false) else "off") 31 | current_resolution = file.get_value(SECTION, "resolution", 2) 32 | update_resolution_text() 33 | 34 | func menu_exit() -> void: 35 | save_video_settings() 36 | 37 | func menu_select(id: int) -> void: 38 | if id == options.size() - 1: 39 | main_menu.set_menu($"../Settings") 40 | 41 | func _process(_delta: float) -> void: 42 | match main_menu.selector_option: 43 | 0: # Resolution 44 | if Input.is_action_just_pressed("Left"): 45 | current_resolution = max(current_resolution - 1, 0) 46 | update_resolution() 47 | 48 | if Input.is_action_just_pressed("Right"): 49 | current_resolution = min(current_resolution + 1, \ 50 | RESOLUTIONS.size() - 1) 51 | update_resolution() 52 | 1: # Wide screen 53 | if not include_widescreen: 54 | return 55 | 56 | if Input.is_action_just_pressed("Left"): 57 | $Widescreen.text = "wide screen: off" 58 | Global.use_widescreen(false) 59 | update_resolution() 60 | 61 | if Input.is_action_just_pressed("Right"): 62 | $Widescreen.text = "wide screen: on" 63 | Global.use_widescreen(true) 64 | update_resolution() 65 | 66 | func update_resolution_text() -> void: 67 | if RESOLUTIONS[current_resolution] == -1: 68 | $Resolution.text = "resolution: full screen" 69 | else: 70 | $Resolution.text = "resolution: x" + str(RESOLUTIONS[current_resolution]) 71 | 72 | func update_resolution() -> void: 73 | update_resolution_text() 74 | 75 | Global.use_fullscreen(RESOLUTIONS[current_resolution] == -1) 76 | if Global.is_fullscreen(): 77 | return 78 | 79 | get_window().set_size(Global.get_content_size() * RESOLUTIONS[current_resolution]) 80 | 81 | func save_video_settings() -> void: 82 | var file := SaveManager.load_settings_file() 83 | file.set_value(SECTION, "widescreen", Global.is_widescreen()) 84 | file.set_value(SECTION, "fullscreen", Global.is_fullscreen()) 85 | file.set_value(SECTION, "resolution", current_resolution) 86 | SaveManager.save_settings_file(file) 87 | 88 | static func load_video_settings(file: ConfigFile) -> void: 89 | var resolution: int = file.get_value("Video", "resolution", 2) 90 | var window := Global.get_window() 91 | 92 | Global.use_widescreen(file.get_value("Video", "widescreen", false)) 93 | Global.use_fullscreen(file.get_value("Video", "fullscreen", false)) 94 | window.size = Global.get_content_size() * RESOLUTIONS[resolution] 95 | 96 | await Global.get_tree().process_frame 97 | window.move_to_center() 98 | -------------------------------------------------------------------------------- /Scenes/MainMenu/Saves.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=14 format=3 uid="uid://bdey4yd06l4t3"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/MainMenu/Saves.gd" id="1_k6r7c"] 4 | [ext_resource type="Script" path="res://Scripts/Boards/BoardDescription.gd" id="2_j2snq"] 5 | [ext_resource type="Texture2D" uid="uid://bwwv6hp8lqxa8" path="res://Sprites/Levels/PlanetIcons.png" id="3_30or2"] 6 | [ext_resource type="PackedScene" uid="uid://blo8x6bqjbe1w" path="res://Scenes/Boards/TheEarth.tscn" id="3_fesxg"] 7 | [ext_resource type="PackedScene" uid="uid://slv0bn0tcyna" path="res://Scenes/Boards/Jupiter.tscn" id="4_nkx8y"] 8 | [ext_resource type="PackedScene" uid="uid://dockgi1sveicy" path="res://Scenes/GameIntro.tscn" id="5_8br8r"] 9 | [ext_resource type="PackedScene" uid="uid://bishkusg7nuhs" path="res://Scenes/MainMenu/SaveSlot.tscn" id="6_3xjm8"] 10 | [ext_resource type="PackedScene" uid="uid://bn3se1dw6cfhu" path="res://Objects/Boards/MessageWindow.tscn" id="7_csx5w"] 11 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="7_sjpp6"] 12 | 13 | [sub_resource type="AtlasTexture" id="AtlasTexture_heghi"] 14 | atlas = ExtResource("3_30or2") 15 | region = Rect2(0, 0, 32, 32) 16 | 17 | [sub_resource type="Resource" id="Resource_tt3oh"] 18 | script = ExtResource("2_j2snq") 19 | name = "The Earth" 20 | board_id = "earth" 21 | icon = SubResource("AtlasTexture_heghi") 22 | scene = ExtResource("3_fesxg") 23 | 24 | [sub_resource type="AtlasTexture" id="AtlasTexture_6cjqn"] 25 | atlas = ExtResource("3_30or2") 26 | region = Rect2(32, 0, 32, 32) 27 | 28 | [sub_resource type="Resource" id="Resource_425mq"] 29 | script = ExtResource("2_j2snq") 30 | name = "Jupiter" 31 | board_id = "jupiter" 32 | icon = SubResource("AtlasTexture_6cjqn") 33 | scene = ExtResource("4_nkx8y") 34 | 35 | [node name="Saves" type="Node2D" groups=["menu"]] 36 | script = ExtResource("1_k6r7c") 37 | boards = Array[ExtResource("2_j2snq")]([SubResource("Resource_tt3oh"), SubResource("Resource_425mq")]) 38 | starting_scene = ExtResource("5_8br8r") 39 | 40 | [node name="DeleteText" type="Label" parent="."] 41 | offset_left = 16.0 42 | offset_top = 16.0 43 | offset_right = 248.0 44 | offset_bottom = 27.0 45 | theme_override_fonts/font = ExtResource("7_sjpp6") 46 | text = "press action to delete a slot" 47 | uppercase = true 48 | 49 | [node name="SaveSlot1" parent="." groups=["option", "saveslot"] instance=ExtResource("6_3xjm8")] 50 | offset_left = 32.0 51 | offset_top = 32.0 52 | offset_right = 48.0 53 | offset_bottom = 48.0 54 | 55 | [node name="SaveSlot2" parent="." groups=["option", "saveslot"] instance=ExtResource("6_3xjm8")] 56 | offset_left = 32.0 57 | offset_top = 80.0 58 | offset_right = 48.0 59 | offset_bottom = 96.0 60 | 61 | [node name="SaveSlot3" parent="." groups=["option", "saveslot"] instance=ExtResource("6_3xjm8")] 62 | offset_left = 32.0 63 | offset_top = 128.0 64 | offset_right = 48.0 65 | offset_bottom = 144.0 66 | 67 | [node name="Delete" type="Label" parent="." groups=["option"]] 68 | offset_left = 104.0 69 | offset_top = 184.0 70 | offset_right = 216.0 71 | offset_bottom = 195.0 72 | theme_override_fonts/font = ExtResource("7_sjpp6") 73 | text = "delete" 74 | uppercase = true 75 | 76 | [node name="Exit" type="Label" parent="." groups=["option"]] 77 | offset_left = 104.0 78 | offset_top = 200.0 79 | offset_right = 216.0 80 | offset_bottom = 211.0 81 | theme_override_fonts/font = ExtResource("7_sjpp6") 82 | text = "exit" 83 | uppercase = true 84 | 85 | [node name="MessageWindow" parent="." instance=ExtResource("7_csx5w")] 86 | offset_left = 16.0 87 | offset_top = 160.0 88 | offset_right = 48.0 89 | offset_bottom = 192.0 90 | -------------------------------------------------------------------------------- /Objects/Levels/Enemies/RocketLauncher.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=10 format=3 uid="uid://c1nseuiv0k6ax"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://bvoxqi1x6lk52" path="res://Objects/Levels/Enemies/BaseEnemy.tscn" id="1_rx4fb"] 4 | [ext_resource type="Script" path="res://Scripts/Objects/Enemies/RocketLauncher.gd" id="2_5wmul"] 5 | [ext_resource type="Texture2D" uid="uid://bc3bfeis78o8y" path="res://Sprites/Objects/Enemies/RocketLauncher.png" id="2_p5nvc"] 6 | 7 | [sub_resource type="Animation" id="Animation_1n8n6"] 8 | length = 0.001 9 | tracks/0/type = "value" 10 | tracks/0/imported = false 11 | tracks/0/enabled = true 12 | tracks/0/path = NodePath("Sprite2D:frame") 13 | tracks/0/interp = 1 14 | tracks/0/loop_wrap = true 15 | tracks/0/keys = { 16 | "times": PackedFloat32Array(0), 17 | "transitions": PackedFloat32Array(1), 18 | "update": 1, 19 | "values": [0] 20 | } 21 | 22 | [sub_resource type="Animation" id="Animation_yyk1h"] 23 | resource_name = "dead" 24 | loop_mode = 1 25 | tracks/0/type = "value" 26 | tracks/0/imported = false 27 | tracks/0/enabled = true 28 | tracks/0/path = NodePath("Sprite2D:frame") 29 | tracks/0/interp = 1 30 | tracks/0/loop_wrap = true 31 | tracks/0/keys = { 32 | "times": PackedFloat32Array(0), 33 | "transitions": PackedFloat32Array(1), 34 | "update": 1, 35 | "values": [4] 36 | } 37 | 38 | [sub_resource type="Animation" id="Animation_6jfoh"] 39 | resource_name = "idle" 40 | tracks/0/type = "value" 41 | tracks/0/imported = false 42 | tracks/0/enabled = true 43 | tracks/0/path = NodePath("Sprite2D:frame") 44 | tracks/0/interp = 1 45 | tracks/0/loop_wrap = true 46 | tracks/0/keys = { 47 | "times": PackedFloat32Array(0), 48 | "transitions": PackedFloat32Array(1), 49 | "update": 1, 50 | "values": [0] 51 | } 52 | 53 | [sub_resource type="Animation" id="Animation_glueo"] 54 | resource_name = "launched" 55 | tracks/0/type = "value" 56 | tracks/0/imported = false 57 | tracks/0/enabled = true 58 | tracks/0/path = NodePath("Sprite2D:frame") 59 | tracks/0/interp = 1 60 | tracks/0/loop_wrap = true 61 | tracks/0/keys = { 62 | "times": PackedFloat32Array(0), 63 | "transitions": PackedFloat32Array(1), 64 | "update": 1, 65 | "values": [3] 66 | } 67 | 68 | [sub_resource type="Animation" id="Animation_vr21e"] 69 | resource_name = "launching" 70 | length = 0.9 71 | tracks/0/type = "value" 72 | tracks/0/imported = false 73 | tracks/0/enabled = true 74 | tracks/0/path = NodePath("Sprite2D:frame") 75 | tracks/0/interp = 1 76 | tracks/0/loop_wrap = true 77 | tracks/0/keys = { 78 | "times": PackedFloat32Array(0, 0.3, 0.6), 79 | "transitions": PackedFloat32Array(1, 1, 1), 80 | "update": 1, 81 | "values": [0, 1, 2] 82 | } 83 | 84 | [sub_resource type="AnimationLibrary" id="AnimationLibrary_edroy"] 85 | _data = { 86 | "RESET": SubResource("Animation_1n8n6"), 87 | "dead": SubResource("Animation_yyk1h"), 88 | "idle": SubResource("Animation_6jfoh"), 89 | "launched": SubResource("Animation_glueo"), 90 | "launching": SubResource("Animation_vr21e") 91 | } 92 | 93 | [node name="RocketLauncher" instance=ExtResource("1_rx4fb")] 94 | script = ExtResource("2_5wmul") 95 | 96 | [node name="HealthComponent" parent="." index="0"] 97 | max_value = 1.0 98 | 99 | [node name="AttackComponent" parent="." index="1"] 100 | should_attack = false 101 | 102 | [node name="Sprite2D" type="Sprite2D" parent="." index="3"] 103 | position = Vector2(0, -8) 104 | texture = ExtResource("2_p5nvc") 105 | hframes = 5 106 | 107 | [node name="AnimationPlayer" type="AnimationPlayer" parent="." index="4"] 108 | libraries = { 109 | "": SubResource("AnimationLibrary_edroy") 110 | } 111 | -------------------------------------------------------------------------------- /Scenes/PassWordGame.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=3 uid="uid://cppc4qs4rb3b6"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/PassWordGame.gd" id="1_ge7e5"] 4 | [ext_resource type="Texture2D" uid="uid://c5trtmb05sfr4" path="res://Sprites/PassWordGame.png" id="2_7ptjk"] 5 | [ext_resource type="FontFile" uid="uid://b4bp7sni8u0il" path="res://Sprites/font2.png" id="3_fdywt"] 6 | 7 | [sub_resource type="LabelSettings" id="LabelSettings_vafdc"] 8 | line_spacing = 16.0 9 | font = ExtResource("3_fdywt") 10 | 11 | [node name="PassWordGame" type="Node2D"] 12 | script = ExtResource("1_ge7e5") 13 | 14 | [node name="PasswordInput" type="Node2D" parent="."] 15 | position = Vector2(48, 48) 16 | 17 | [node name="Box" type="NinePatchRect" parent="PasswordInput"] 18 | offset_left = -16.0 19 | offset_top = -16.0 20 | offset_right = 176.0 21 | offset_bottom = 96.0 22 | texture = ExtResource("2_7ptjk") 23 | draw_center = false 24 | patch_margin_left = 8 25 | patch_margin_top = 8 26 | patch_margin_right = 8 27 | patch_margin_bottom = 8 28 | 29 | [node name="InputLetters" type="Label" parent="PasswordInput"] 30 | offset_right = 40.0 31 | offset_bottom = 23.0 32 | text = "0123456789 33 | abcdefghjk 34 | lmnpqrstuw 35 | xy " 36 | label_settings = SubResource("LabelSettings_vafdc") 37 | uppercase = true 38 | 39 | [node name="InputLeft" type="Label" parent="PasswordInput"] 40 | offset_left = 48.0 41 | offset_top = 72.0 42 | offset_right = 80.0 43 | offset_bottom = 83.0 44 | theme_override_fonts/font = ExtResource("3_fdywt") 45 | text = "left" 46 | uppercase = true 47 | 48 | [node name="InputRight" type="Label" parent="PasswordInput"] 49 | offset_left = 88.0 50 | offset_top = 72.0 51 | offset_right = 120.0 52 | offset_bottom = 83.0 53 | theme_override_fonts/font = ExtResource("3_fdywt") 54 | text = "right" 55 | uppercase = true 56 | 57 | [node name="InputEnd" type="Label" parent="PasswordInput"] 58 | offset_left = 136.0 59 | offset_top = 72.0 60 | offset_right = 160.0 61 | offset_bottom = 83.0 62 | theme_override_fonts/font = ExtResource("3_fdywt") 63 | text = "end" 64 | uppercase = true 65 | 66 | [node name="Selector" type="Sprite2D" parent="PasswordInput"] 67 | texture = ExtResource("2_7ptjk") 68 | centered = false 69 | offset = Vector2(0, 8) 70 | region_enabled = true 71 | region_rect = Rect2(8, 8, 8, 8) 72 | 73 | [node name="PasswordBox" type="Node2D" parent="."] 74 | position = Vector2(40, 168) 75 | 76 | [node name="Box" type="NinePatchRect" parent="PasswordBox"] 77 | offset_left = -16.0 78 | offset_top = -16.0 79 | offset_right = 192.0 80 | offset_bottom = 48.0 81 | texture = ExtResource("2_7ptjk") 82 | draw_center = false 83 | patch_margin_left = 8 84 | patch_margin_top = 8 85 | patch_margin_right = 8 86 | patch_margin_bottom = 8 87 | 88 | [node name="Password" type="Label" parent="PasswordBox"] 89 | offset_right = 176.0 90 | offset_bottom = 48.0 91 | text = "0123456789abcdefghjklm 92 | sd" 93 | label_settings = SubResource("LabelSettings_vafdc") 94 | uppercase = true 95 | 96 | [node name="Selector" type="Sprite2D" parent="PasswordBox"] 97 | texture = ExtResource("2_7ptjk") 98 | centered = false 99 | offset = Vector2(0, 8) 100 | region_enabled = true 101 | region_rect = Rect2(8, 8, 8, 8) 102 | 103 | [node name="PassWordError" type="Label" parent="."] 104 | visible = false 105 | offset_left = 72.0 106 | offset_top = 144.0 107 | offset_right = 192.0 108 | offset_bottom = 155.0 109 | theme_override_fonts/font = ExtResource("3_fdywt") 110 | text = "pass word error" 111 | uppercase = true 112 | 113 | [node name="PWETimer" type="Timer" parent="."] 114 | process_mode = 3 115 | wait_time = 0.2 116 | -------------------------------------------------------------------------------- /Scripts/MainMenu/Saves.gd: -------------------------------------------------------------------------------- 1 | extends "res://Scripts/MainMenu/Menu.gd" 2 | 3 | # Explanation of the save system: 4 | # When the player gets on a board (using a save ofc) 5 | # the board's id is saved in the save file. 6 | # In this menu the needed BoardDescription is found by 7 | # comparing the board ids 8 | # 9 | # After the player completes the board, the next board 10 | # the player is sent to is determined by "next_board" 11 | # exported variable. 12 | 13 | @export var boards: Array[BoardDescription] 14 | @export var starting_scene: PackedScene 15 | 16 | @onready var delete_text: Label = $DeleteText 17 | @onready var message_window: MessageWindow = $MessageWindow 18 | 19 | var save_slots: Array[Control] = [] 20 | 21 | func _ready() -> void: 22 | super._ready() 23 | delete_text.hide() 24 | save_slots.assign(get_children().filter( 25 | func(c: Control) -> bool: return c.is_in_group("saveslot") 26 | )) 27 | 28 | var save_id := 0 29 | for save_slot in save_slots: 30 | SaveManager.set_save_slot(save_id) 31 | var save_data := SaveManager.load_save_data() 32 | var board_description := get_board_description(save_data) 33 | if board_description == null: 34 | save_slot.set_data_empty(save_id) 35 | else: 36 | save_slot.set_data(save_id, board_description, save_data) 37 | save_id += 1 38 | 39 | save_slots[0].select() 40 | 41 | func menu_enter() -> void: 42 | main_menu.selector.hide() 43 | 44 | func _process(_delta: float) -> void: 45 | save_slots.map(func(s: Control) -> void: s.deselect()) 46 | if main_menu.selector_option < save_slots.size(): 47 | main_menu.selector.hide() 48 | save_slots[main_menu.selector_option].select() 49 | else: 50 | main_menu.selector.show() 51 | 52 | func menu_select(id: int) -> void: 53 | match id: 54 | 3: 55 | delete_text.visible = not delete_text.visible 56 | 4: 57 | main_menu.set_menu(%MenuMain) 58 | delete_text.hide() 59 | _: 60 | SaveManager.set_save_slot(id) 61 | var save_data := SaveManager.load_save_data() 62 | var board_description := get_board_description(save_data) 63 | 64 | if delete_text.visible: 65 | if board_description == null: 66 | return 67 | main_menu.selector.set_process(false) 68 | 69 | reposition_message_window() 70 | var result := await message_window.appear( 71 | "Do you want to delete this slot?", true, true) 72 | if result == MessageWindow.Response.YES: 73 | var save_file := SaveManager.load_save_file() 74 | save_file.erase_section(SaveManager.get_save_slot_section()) 75 | SaveManager.store_save_file(save_file) 76 | save_slots[id].set_data_empty(id) 77 | delete_text.hide() 78 | 79 | main_menu.selector.set_process(true) 80 | else: 81 | if board_description == null: 82 | main_menu.change_scene(starting_scene) 83 | return 84 | 85 | get_tree().paused = true 86 | 87 | Global.music_fade_out() 88 | await Global.fade_out() 89 | await get_tree().create_timer(0.5).timeout 90 | 91 | get_tree().paused = false 92 | Global.score = save_data.get("score", 0) 93 | Global.change_scene(board_description.scene) 94 | 95 | func get_board_description(save_data: Dictionary) -> BoardDescription: 96 | var board_id: String = save_data.get("board_id", "") 97 | if board_id.is_empty(): 98 | return null 99 | return boards.filter( 100 | func(b: BoardDescription) -> bool: return b.board_id == board_id 101 | )[0] 102 | 103 | func reposition_message_window() -> void: 104 | if Global.is_widescreen(): 105 | message_window.global_position.x = 16 106 | else: 107 | message_window.position.x = 16 108 | -------------------------------------------------------------------------------- /Scenes/MainMenu/MainMenu.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=10 format=3 uid="uid://b8f5oi120p3iu"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://bjcf4tfdeo6ta" path="res://Scenes/MainMenu/BaseMenu.tscn" id="1_0ctmj"] 4 | [ext_resource type="AudioStream" uid="uid://nl06a7xp7bq7" path="res://Audio/Soundtrack/MainMenu.ogg" id="2_tex8m"] 5 | [ext_resource type="FontFile" uid="uid://dycfyvuoxfwc0" path="res://Sprites/font1.png" id="2_xjjqh"] 6 | [ext_resource type="PackedScene" uid="uid://bdey4yd06l4t3" path="res://Scenes/MainMenu/Saves.tscn" id="4_bf7ph"] 7 | [ext_resource type="PackedScene" uid="uid://lxs5br5r3336" path="res://Scenes/MainMenu/Settings.tscn" id="5_jak1r"] 8 | [ext_resource type="PackedScene" uid="uid://bxtvwweer7x10" path="res://Scenes/MainMenu/VideoSettings.tscn" id="5_w2jg4"] 9 | [ext_resource type="PackedScene" uid="uid://dk6nkw1ue84ow" path="res://Scenes/MainMenu/SoundSettings.tscn" id="6_2krn8"] 10 | [ext_resource type="PackedScene" uid="uid://dy3m74iswj1v" path="res://Scenes/MainMenu/Controls.tscn" id="6_u2h2c"] 11 | 12 | [sub_resource type="GDScript" id="GDScript_46jxm"] 13 | script/source = "extends \"res://Scripts/MainMenu/Menu.gd\" 14 | 15 | func menu_select(id: int) -> void: 16 | match id: 17 | 0: # New Game 18 | main_menu.set_menu(%Saves) 19 | 1: # Pass word game 20 | main_menu.change_scene(preload(\"res://Scenes/PassWordGame.tscn\")) 21 | 2: # Settings 22 | main_menu.set_menu(%Settings) 23 | 3: # Credits 24 | main_menu.change_scene(preload(\"res://Scenes/Credits.tscn\")) 25 | 4: # Exit 26 | get_tree().paused = true 27 | 28 | Global.music_fade_out() 29 | Global.fade_out() 30 | await Global.fade_end 31 | 32 | await get_tree().create_timer(0.25).timeout 33 | 34 | get_tree().quit() 35 | " 36 | 37 | [node name="MainMenu" instance=ExtResource("1_0ctmj")] 38 | music = ExtResource("2_tex8m") 39 | 40 | [node name="MenuMain" parent="." index="1"] 41 | script = SubResource("GDScript_46jxm") 42 | 43 | [node name="NewGame" type="Label" parent="MenuMain" index="0" groups=["option"]] 44 | offset_left = 72.0 45 | offset_top = 80.0 46 | offset_right = 200.0 47 | offset_bottom = 96.0 48 | theme_override_fonts/font = ExtResource("2_xjjqh") 49 | text = "new game" 50 | uppercase = true 51 | 52 | [node name="Password" type="Label" parent="MenuMain" index="1" groups=["option"]] 53 | offset_left = 72.0 54 | offset_top = 104.0 55 | offset_right = 184.0 56 | offset_bottom = 115.0 57 | theme_override_fonts/font = ExtResource("2_xjjqh") 58 | text = "pass word game" 59 | uppercase = true 60 | 61 | [node name="Settings" type="Label" parent="MenuMain" index="2" groups=["option"]] 62 | offset_left = 72.0 63 | offset_top = 128.0 64 | offset_right = 184.0 65 | offset_bottom = 139.0 66 | theme_override_fonts/font = ExtResource("2_xjjqh") 67 | text = "settings" 68 | uppercase = true 69 | 70 | [node name="Credits" type="Label" parent="MenuMain" index="3" groups=["option"]] 71 | offset_left = 72.0 72 | offset_top = 152.0 73 | offset_right = 184.0 74 | offset_bottom = 163.0 75 | theme_override_fonts/font = ExtResource("2_xjjqh") 76 | text = "credits" 77 | uppercase = true 78 | 79 | [node name="Saves" parent="." index="2" instance=ExtResource("4_bf7ph")] 80 | unique_name_in_owner = true 81 | visible = false 82 | 83 | [node name="Settings" parent="." index="3" instance=ExtResource("5_jak1r")] 84 | unique_name_in_owner = true 85 | visible = false 86 | 87 | [node name="Controls" parent="." index="4" instance=ExtResource("6_u2h2c")] 88 | unique_name_in_owner = true 89 | visible = false 90 | 91 | [node name="SoundSettings" parent="." index="5" instance=ExtResource("6_2krn8")] 92 | unique_name_in_owner = true 93 | visible = false 94 | 95 | [node name="VideoSettings" parent="." index="6" instance=ExtResource("5_w2jg4")] 96 | unique_name_in_owner = true 97 | visible = false 98 | --------------------------------------------------------------------------------