commit 1497a225cc56b22bd99a2ae5e83cbf52332ffdb1 Author: wanp Date: Sun Feb 8 12:20:45 2026 -0300 Initial commit (release) diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7758b98 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# Godot 4+ specific ignores +.godot/ +.nomedia + +# Godot-specific ignores +.import/ +export.cfg +export_credentials.cfg +*.tmp + +# Imported translations (automatically generated from CSV files) +*.translation + +# Mono-specific ignores +.mono/ +data_*/ +mono_crash.*.json + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ca22410 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2026 wanp + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/assets/arrow.glb b/assets/arrow.glb new file mode 100644 index 0000000..525b527 Binary files /dev/null and b/assets/arrow.glb differ diff --git a/assets/arrow.glb.import b/assets/arrow.glb.import new file mode 100644 index 0000000..d6a8594 --- /dev/null +++ b/assets/arrow.glb.import @@ -0,0 +1,42 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://cwtmdaxfjpek5" +path="res://.godot/imported/arrow.glb-fbbbd1f233a05b386bf12d76bd49138b.scn" + +[deps] + +source_file="res://assets/arrow.glb" +dest_files=["res://.godot/imported/arrow.glb-fbbbd1f233a05b386bf12d76bd49138b.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="Arrow" +nodes/root_script=null +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={} +gltf/naming_version=2 +gltf/embedded_image_handling=1 diff --git a/assets/button.glb b/assets/button.glb new file mode 100644 index 0000000..d381d96 Binary files /dev/null and b/assets/button.glb differ diff --git a/assets/button.glb.import b/assets/button.glb.import new file mode 100644 index 0000000..0cd3e52 --- /dev/null +++ b/assets/button.glb.import @@ -0,0 +1,42 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://fbqbcvko5rla" +path="res://.godot/imported/button.glb-c091fb4dc2edb443cfd7c3e13491944b.scn" + +[deps] + +source_file="res://assets/button.glb" +dest_files=["res://.godot/imported/button.glb-c091fb4dc2edb443cfd7c3e13491944b.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="Button" +nodes/root_script=null +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={} +gltf/naming_version=2 +gltf/embedded_image_handling=1 diff --git a/assets/button.wav b/assets/button.wav new file mode 100644 index 0000000..42cb6bb Binary files /dev/null and b/assets/button.wav differ diff --git a/assets/button.wav.import b/assets/button.wav.import new file mode 100644 index 0000000..21624d8 --- /dev/null +++ b/assets/button.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://l3eewf8v21rl" +path="res://.godot/imported/button.wav-8583ca65880448b76a9f4a2aef4af9c3.sample" + +[deps] + +source_file="res://assets/button.wav" +dest_files=["res://.godot/imported/button.wav-8583ca65880448b76a9f4a2aef4af9c3.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/assets/button_button-colors.png b/assets/button_button-colors.png new file mode 100644 index 0000000..55e28ad Binary files /dev/null and b/assets/button_button-colors.png differ diff --git a/assets/button_button-colors.png.import b/assets/button_button-colors.png.import new file mode 100644 index 0000000..0560c4b --- /dev/null +++ b/assets/button_button-colors.png.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://btiwfrsqwqpb0" +path="res://.godot/imported/button_button-colors.png-b3e694bdad4006b8b5e9e9231b641088.ctex" +metadata={ +"vram_texture": false +} +generator_parameters={ +"md5": "6ca987e3bee41277db70025faf205a39" +} + +[deps] + +source_file="res://assets/button_button-colors.png" +dest_files=["res://.godot/imported/button_button-colors.png-b3e694bdad4006b8b5e9e9231b641088.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/assets/fandanguillo-de-almeria-la-argentinita.ogg b/assets/fandanguillo-de-almeria-la-argentinita.ogg new file mode 100644 index 0000000..a15b456 Binary files /dev/null and b/assets/fandanguillo-de-almeria-la-argentinita.ogg differ diff --git a/assets/fandanguillo-de-almeria-la-argentinita.ogg.import b/assets/fandanguillo-de-almeria-la-argentinita.ogg.import new file mode 100644 index 0000000..6c5fdda --- /dev/null +++ b/assets/fandanguillo-de-almeria-la-argentinita.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://bj2ksich3ki3b" +path="res://.godot/imported/fandanguillo-de-almeria-la-argentinita.ogg-3985f6350437735c282d8ee732a6fb86.oggvorbisstr" + +[deps] + +source_file="res://assets/fandanguillo-de-almeria-la-argentinita.ogg" +dest_files=["res://.godot/imported/fandanguillo-de-almeria-la-argentinita.ogg-3985f6350437735c282d8ee732a6fb86.oggvorbisstr"] + +[params] + +loop=true +loop_offset=0.0 +bpm=0.0 +beat_count=0 +bar_beats=4 diff --git a/assets/ghost1.glb b/assets/ghost1.glb new file mode 100644 index 0000000..8f0c207 Binary files /dev/null and b/assets/ghost1.glb differ diff --git a/assets/ghost1.glb.import b/assets/ghost1.glb.import new file mode 100644 index 0000000..83c74eb --- /dev/null +++ b/assets/ghost1.glb.import @@ -0,0 +1,50 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bjwne0uhljtcp" +path="res://.godot/imported/ghost1.glb-8fe4d028afe8ef41f60711efaaf7caf8.scn" + +[deps] + +source_file="res://assets/ghost1.glb" +dest_files=["res://.godot/imported/ghost1.glb-8fe4d028afe8ef41f60711efaaf7caf8.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={ +"materials": { +"Material.001": { +"use_external/enabled": true, +"use_external/fallback_path": "res://src/game/ghost_material.tres", +"use_external/path": "uid://b2fsxx7piy766" +} +} +} +gltf/naming_version=2 +gltf/embedded_image_handling=1 diff --git a/assets/ghost2.glb b/assets/ghost2.glb new file mode 100644 index 0000000..0ed7fa0 Binary files /dev/null and b/assets/ghost2.glb differ diff --git a/assets/ghost2.glb.import b/assets/ghost2.glb.import new file mode 100644 index 0000000..d373e38 --- /dev/null +++ b/assets/ghost2.glb.import @@ -0,0 +1,50 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://nvmmfbhcsklr" +path="res://.godot/imported/ghost2.glb-51f8285307a2f55adc2c16c906db0392.scn" + +[deps] + +source_file="res://assets/ghost2.glb" +dest_files=["res://.godot/imported/ghost2.glb-51f8285307a2f55adc2c16c906db0392.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={ +"materials": { +"Material.001": { +"use_external/enabled": true, +"use_external/fallback_path": "res://src/game/ghost_material.tres", +"use_external/path": "uid://b2fsxx7piy766" +} +} +} +gltf/naming_version=2 +gltf/embedded_image_handling=1 diff --git a/assets/ghost3.glb b/assets/ghost3.glb new file mode 100644 index 0000000..3126e6d Binary files /dev/null and b/assets/ghost3.glb differ diff --git a/assets/ghost3.glb.import b/assets/ghost3.glb.import new file mode 100644 index 0000000..c78118b --- /dev/null +++ b/assets/ghost3.glb.import @@ -0,0 +1,50 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://vwimm7jky61f" +path="res://.godot/imported/ghost3.glb-a8268a4246a419d28e073c28b06c2a75.scn" + +[deps] + +source_file="res://assets/ghost3.glb" +dest_files=["res://.godot/imported/ghost3.glb-a8268a4246a419d28e073c28b06c2a75.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={ +"materials": { +"Material.001": { +"use_external/enabled": true, +"use_external/fallback_path": "res://src/game/ghost_material.tres", +"use_external/path": "uid://b2fsxx7piy766" +} +} +} +gltf/naming_version=2 +gltf/embedded_image_handling=1 diff --git a/assets/in.wav b/assets/in.wav new file mode 100644 index 0000000..c1828aa Binary files /dev/null and b/assets/in.wav differ diff --git a/assets/in.wav.import b/assets/in.wav.import new file mode 100644 index 0000000..750a662 --- /dev/null +++ b/assets/in.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://g5227ljhgxba" +path="res://.godot/imported/in.wav-93008283f2cdf3bf14c9d1270f0829b3.sample" + +[deps] + +source_file="res://assets/in.wav" +dest_files=["res://.godot/imported/in.wav-93008283f2cdf3bf14c9d1270f0829b3.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/assets/out.wav b/assets/out.wav new file mode 100644 index 0000000..33c0b10 Binary files /dev/null and b/assets/out.wav differ diff --git a/assets/out.wav.import b/assets/out.wav.import new file mode 100644 index 0000000..97d8fad --- /dev/null +++ b/assets/out.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://cb2cly1p33pue" +path="res://.godot/imported/out.wav-f7d74ab5eb384260957d2d1fa6b3aa06.sample" + +[deps] + +source_file="res://assets/out.wav" +dest_files=["res://.godot/imported/out.wav-f7d74ab5eb384260957d2d1fa6b3aa06.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/assets/rhodium-libre.ttf b/assets/rhodium-libre.ttf new file mode 100644 index 0000000..03f9331 Binary files /dev/null and b/assets/rhodium-libre.ttf differ diff --git a/assets/rhodium-libre.ttf.import b/assets/rhodium-libre.ttf.import new file mode 100644 index 0000000..da2be4a --- /dev/null +++ b/assets/rhodium-libre.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://c4p2j3cqdcx8x" +path="res://.godot/imported/rhodium-libre.ttf-3f99e6a93d6b7f0d5d26ada6d8f419af.fontdata" + +[deps] + +source_file="res://assets/rhodium-libre.ttf" +dest_files=["res://.godot/imported/rhodium-libre.ttf-3f99e6a93d6b7f0d5d26ada6d8f419af.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/slam.wav b/assets/slam.wav new file mode 100644 index 0000000..56f48d4 Binary files /dev/null and b/assets/slam.wav differ diff --git a/assets/slam.wav.import b/assets/slam.wav.import new file mode 100644 index 0000000..9752c92 --- /dev/null +++ b/assets/slam.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://c1stp6572r2qg" +path="res://.godot/imported/slam.wav-07138e7f1e045a7cc6aaf4d7bfd42d12.sample" + +[deps] + +source_file="res://assets/slam.wav" +dest_files=["res://.godot/imported/slam.wav-07138e7f1e045a7cc6aaf4d7bfd42d12.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/assets/splat.wav b/assets/splat.wav new file mode 100644 index 0000000..62181d6 Binary files /dev/null and b/assets/splat.wav differ diff --git a/assets/splat.wav.import b/assets/splat.wav.import new file mode 100644 index 0000000..34048eb --- /dev/null +++ b/assets/splat.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://d2fttu4hq27nb" +path="res://.godot/imported/splat.wav-be60c91081f5190f812703dd3fac1124.sample" + +[deps] + +source_file="res://assets/splat.wav" +dest_files=["res://.godot/imported/splat.wav-be60c91081f5190f812703dd3fac1124.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/assets/the-nautigal.ttf b/assets/the-nautigal.ttf new file mode 100644 index 0000000..856ce8d Binary files /dev/null and b/assets/the-nautigal.ttf differ diff --git a/assets/the-nautigal.ttf.import b/assets/the-nautigal.ttf.import new file mode 100644 index 0000000..50405f3 --- /dev/null +++ b/assets/the-nautigal.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://dsnbywa4hscr0" +path="res://.godot/imported/the-nautigal.ttf-b9354cb802dd9bb9fa65eac1a923ace4.fontdata" + +[deps] + +source_file="res://assets/the-nautigal.ttf" +dest_files=["res://.godot/imported/the-nautigal.ttf-b9354cb802dd9bb9fa65eac1a923ace4.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/default_bus_layout.tres b/default_bus_layout.tres new file mode 100644 index 0000000..55d8e50 --- /dev/null +++ b/default_bus_layout.tres @@ -0,0 +1,27 @@ +[gd_resource type="AudioBusLayout" format=3 uid="uid://cg8ko5gj8ec6t"] + +[sub_resource type="AudioEffectLimiter" id="AudioEffectLimiter_j3pel"] +resource_name = "Limiter" + +[sub_resource type="AudioEffectReverb" id="AudioEffectReverb_j3pel"] +resource_name = "Reverb" +room_size = 0.01 +damping = 0.8 + +[resource] +bus/1/name = &"music" +bus/1/solo = false +bus/1/mute = false +bus/1/bypass_fx = false +bus/1/volume_db = 0.0 +bus/1/send = &"Master" +bus/2/name = &"sfx" +bus/2/solo = false +bus/2/mute = false +bus/2/bypass_fx = false +bus/2/volume_db = -6.0044775 +bus/2/send = &"Master" +bus/2/effect/0/effect = SubResource("AudioEffectLimiter_j3pel") +bus/2/effect/0/enabled = true +bus/2/effect/1/effect = SubResource("AudioEffectReverb_j3pel") +bus/2/effect/1/enabled = true diff --git a/export_presets.cfg b/export_presets.cfg new file mode 100644 index 0000000..877ef0d --- /dev/null +++ b/export_presets.cfg @@ -0,0 +1,49 @@ +[preset.0] + +name="Web" +platform="Web" +runnable=true +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="dist/index.html" +patches=PackedStringArray() +patch_delta_encoding=false +patch_delta_compression_level_zstd=19 +patch_delta_min_reduction=0.1 +patch_delta_include_filters="*" +patch_delta_exclude_filters="" +encryption_include_filters="" +encryption_exclude_filters="" +seed=0 +encrypt_pck=false +encrypt_directory=false +script_export_mode=2 + +[preset.0.options] + +custom_template/debug="" +custom_template/release="" +variant/extensions_support=false +variant/thread_support=false +vram_texture_compression/for_desktop=true +vram_texture_compression/for_mobile=false +html/export_icon=false +html/custom_html_shell="" +html/head_include="" +html/canvas_resize_policy=2 +html/focus_canvas_on_start=true +html/experimental_virtual_keyboard=false +progressive_web_app/enabled=false +progressive_web_app/ensure_cross_origin_isolation_headers=true +progressive_web_app/offline_page="" +progressive_web_app/display=1 +progressive_web_app/orientation=0 +progressive_web_app/icon_144x144="" +progressive_web_app/icon_180x180="" +progressive_web_app/icon_512x512="" +progressive_web_app/background_color=Color(0, 0, 0, 1) +threads/emscripten_pool_size=8 +threads/godot_pool_size=4 diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..c6bbb7d --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..ac7187d --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://wf6nm2xuxq6r" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..5f324ca --- /dev/null +++ b/project.godot @@ -0,0 +1,73 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[animation] + +compatibility/default_parent_skeleton_in_mesh_instance_3d=true + +[application] + +config/name="D'n'J Crusher" +run/main_scene="uid://0t1khpumpjk6" +config/features=PackedStringArray("4.6", "GL Compatibility") +boot_splash/bg_color=Color(0, 0, 0, 1) +boot_splash/show_image=false +config/icon="res://icon.svg" + +[audio] + +buses/default_bus_layout="uid://cg8ko5gj8ec6t" +general/default_playback_type.web=0 + +[display] + +window/size/viewport_width=800 +window/size/viewport_height=600 +window/stretch/mode="canvas_items" + +[global_group] + +ghosts="" + +[input] + +d_act={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} +j_act={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":74,"physical_keycode":0,"key_label":0,"unicode":106,"location":0,"echo":false,"script":null) +] +} +pause={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194309,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} + +[physics] + +3d/run_on_separate_thread=true +2d/physics_engine="Dummy" +3d/physics_engine="Dummy" +common/physics_interpolation=true + +[rendering] + +rendering_device/driver.windows="d3d12" +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility" +lights_and_shadows/positional_shadow/soft_shadow_filter_quality=0 +shading/overrides/force_vertex_shading=true +limits/opengl/max_renderable_elements=4096 +limits/opengl/max_renderable_lights=8 diff --git a/src/game/basic.gdshader b/src/game/basic.gdshader new file mode 100644 index 0000000..43d033b --- /dev/null +++ b/src/game/basic.gdshader @@ -0,0 +1,8 @@ +shader_type spatial; + +uniform sampler2D texture_image : source_color; +uniform vec3 tint : source_color = vec3(1, 1, 1); + +void fragment() { + ALBEDO = texture(texture_image, UV).rgb * tint.rgb; +} diff --git a/src/game/basic.gdshader.uid b/src/game/basic.gdshader.uid new file mode 100644 index 0000000..c3e4e7e --- /dev/null +++ b/src/game/basic.gdshader.uid @@ -0,0 +1 @@ +uid://bvemv1371ggkd diff --git a/src/game/basic_untinted_material.tres b/src/game/basic_untinted_material.tres new file mode 100644 index 0000000..c822c1a --- /dev/null +++ b/src/game/basic_untinted_material.tres @@ -0,0 +1,8 @@ +[gd_resource type="ShaderMaterial" format=3 uid="uid://b6qswdhurj1l6"] + +[ext_resource type="Shader" uid="uid://bvemv1371ggkd" path="res://src/game/basic.gdshader" id="1_mml0d"] + +[resource] +render_priority = 0 +shader = ExtResource("1_mml0d") +shader_parameter/tint = Color(1, 0.81666666, 0, 1) diff --git a/src/game/game.gd b/src/game/game.gd new file mode 100644 index 0000000..708b0c6 --- /dev/null +++ b/src/game/game.gd @@ -0,0 +1,120 @@ +extends Node3D + +enum TutorialStep { + PRESS_J, + PRESS_D, + DONE, +} + +@export var _ui_layer: CanvasLayer +@export var _press_d_prompt: Node3D +@export var _press_j_prompt: Node3D + +@export var _d_anim: AnimationPlayer +@export var _d_button: Node3D +@export var _j_anim: AnimationPlayer +@export var _j_button: Node3D + +@onready var _d_button_anim: AnimationPlayer = _d_button.get_node("AnimationPlayer") +@onready var _j_button_anim: AnimationPlayer = _j_button.get_node("AnimationPlayer") + +var _tutorial_step := TutorialStep.PRESS_J + + +func _ready() -> void: + _press_d_prompt.hide() + _press_j_prompt.hide() + +func _unhandled_input(event: InputEvent) -> void: + if event.is_action_pressed("d_act"): + _d_anim.play("press") + _d_button_anim.play("press") + _crusher_deactivate() + return + + if event.is_action_pressed("j_act"): + _j_anim.play("press") + _j_button_anim.play("press") + _crusher_activate() + return + +func _physics_process(_delta: float) -> void: + if _tutorial_step != TutorialStep.DONE: + match _tutorial_step: + TutorialStep.PRESS_J: + if _crusher_is_active: + _tutorial_step = (_tutorial_step + 1) as TutorialStep + else: + _press_d_prompt.hide() + _press_j_prompt.show() + TutorialStep.PRESS_D: + if not _crusher_is_active: + _tutorial_step = (_tutorial_step + 1) as TutorialStep + else: + _press_d_prompt.show() + _press_j_prompt.hide() + + # was set in one of the match cases + if _tutorial_step == TutorialStep.DONE: + _ui_layer.hide() + _press_d_prompt.hide() + _press_j_prompt.hide() + _ghost_spawn_timer.start() + +#region Ghosts +@export var _ghost_spawn_timer: Timer +@export var _ghost_scene: PackedScene + + +func _on_ghost_spawn_timer_timeout() -> void: + var ghost: Node3D = _ghost_scene.instantiate() + add_child(ghost) + ghost.position = Vector3(randf_range(-1, 1), -4, 0) + + _ghost_spawn_timer.wait_time = randf_range(0.3, 1.3) +#endregion + + +#region Crusher +@export var _crusher: Node3D +@export var _slam_sfx: AudioStreamPlayer3D +@export var _splat_sfx: AudioStreamPlayer3D +@export var _crusher_anim: AnimationPlayer + +@onready var _crush_range_start = _crusher.position.y + 1.8 +@onready var _crush_range_end = _crusher.position.y + -1.4 + +# can't reactivate until deactivated, and vice versa +var _crusher_is_active := false + + +func _crusher_activate() -> void: + if _crusher_anim.is_playing() or _crusher_is_active: + return + + _crusher_is_active = true + _crusher_anim.play("crush") + +func _crusher_deactivate() -> void: + if _crusher_anim.is_playing() or not _crusher_is_active: + return + + _crusher_is_active = false + _crusher_anim.play("uncrush") + +func crusher_crush() -> void: + var ghosts := get_tree().get_nodes_in_group("ghosts") + var crushed_any := false + for ghost: Ghost in ghosts: + if ghost.is_crushed: + continue + if ghost.position.y > _crush_range_start or ghost.position.y < _crush_range_end: + continue + + ghost.crush(0) + crushed_any = true + + _slam_sfx.play() + if crushed_any: + _splat_sfx.play() +#endregion diff --git a/src/game/game.gd.uid b/src/game/game.gd.uid new file mode 100644 index 0000000..4607b9b --- /dev/null +++ b/src/game/game.gd.uid @@ -0,0 +1 @@ +uid://cagqlqi6ahncv diff --git a/src/game/game.tscn b/src/game/game.tscn new file mode 100644 index 0000000..8bbf7a2 --- /dev/null +++ b/src/game/game.tscn @@ -0,0 +1,646 @@ +[gd_scene format=3 uid="uid://0t1khpumpjk6"] + +[ext_resource type="Script" uid="uid://cagqlqi6ahncv" path="res://src/game/game.gd" id="1_s6lek"] +[ext_resource type="Material" uid="uid://b6qswdhurj1l6" path="res://src/game/basic_untinted_material.tres" id="2_kgj8g"] +[ext_resource type="PackedScene" uid="uid://sdd62ogittlq" path="res://src/game/ghost.tscn" id="2_l80un"] +[ext_resource type="Material" uid="uid://di0etogxlb5dq" path="res://src/game/wall_material.tres" id="2_s6lek"] +[ext_resource type="AudioStream" uid="uid://bj2ksich3ki3b" path="res://assets/fandanguillo-de-almeria-la-argentinita.ogg" id="3_htx8b"] +[ext_resource type="FontFile" uid="uid://dsnbywa4hscr0" path="res://assets/the-nautigal.ttf" id="4_etvrb"] +[ext_resource type="PackedScene" uid="uid://fbqbcvko5rla" path="res://assets/button.glb" id="4_xptat"] +[ext_resource type="AudioStream" uid="uid://l3eewf8v21rl" path="res://assets/button.wav" id="5_6kr85"] +[ext_resource type="AudioStream" uid="uid://c1stp6572r2qg" path="res://assets/slam.wav" id="6_jhw8o"] +[ext_resource type="PackedScene" uid="uid://cwtmdaxfjpek5" path="res://assets/arrow.glb" id="6_yarin"] +[ext_resource type="AudioStream" uid="uid://g5227ljhgxba" path="res://assets/in.wav" id="7_7r0dx"] +[ext_resource type="AudioStream" uid="uid://d2fttu4hq27nb" path="res://assets/splat.wav" id="7_n7s5x"] +[ext_resource type="AudioStream" uid="uid://cb2cly1p33pue" path="res://assets/out.wav" id="8_htx8b"] +[ext_resource type="FontFile" uid="uid://c4p2j3cqdcx8x" path="res://assets/rhodium-libre.ttf" id="12_ueio8"] + +[sub_resource type="Environment" id="Environment_jn5yv"] +background_mode = 1 +ambient_light_source = 1 +reflected_light_source = 1 + +[sub_resource type="Animation" id="Animation_clwl7"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:light_energy") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [3.0] +} + +[sub_resource type="Animation" id="Animation_7r0dx"] +resource_name = "flicker" +length = 0.8 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:light_energy") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.4), +"transitions": PackedFloat32Array(0.5, 1), +"update": 0, +"values": [3.0, 5.0] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_htx8b"] +_data = { +&"RESET": SubResource("Animation_clwl7"), +&"flicker": SubResource("Animation_7r0dx") +} + +[sub_resource type="CylinderMesh" id="CylinderMesh_s6lek"] +top_radius = 1.0 +radial_segments = 6 +rings = 0 + +[sub_resource type="PlaneMesh" id="PlaneMesh_qnjlk"] +material = ExtResource("2_s6lek") +size = Vector2(15, 15) + +[sub_resource type="Animation" id="Animation_jhw8o"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Hand:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(-0.4000001, -0.100000024, 0.30000004)] +} + +[sub_resource type="Animation" id="Animation_yarin"] +resource_name = "press" +length = 0.1667 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Hand:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.033333335, 0.16666667), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(-0.4000001, -0.100000024, 0.30000004), Vector3(-0.4000001, -0.30000007, 0.30000004), Vector3(-0.4000001, -0.100000024, 0.30000004)] +} +tracks/1/type = "audio" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Button/ButtonSfx") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"clips": [{ +"end_offset": 0.0, +"start_offset": 0.0, +"stream": ExtResource("5_6kr85") +}], +"times": PackedFloat32Array(0.033333335) +} +tracks/1/use_blend = true + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_jhw8o"] +_data = { +&"RESET": SubResource("Animation_jhw8o"), +&"press": SubResource("Animation_yarin") +} + +[sub_resource type="SphereMesh" id="SphereMesh_kgj8g"] +lightmap_size_hint = Vector2i(14, 8) +material = ExtResource("2_kgj8g") +radius = 0.4 +height = 0.8 +radial_segments = 8 +rings = 6 + +[sub_resource type="Gradient" id="Gradient_s6lek"] +interpolation_mode = 1 +offsets = PackedFloat32Array(0, 0.6) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_kgj8g"] +gradient = SubResource("Gradient_s6lek") +width = 8 +height = 16 +fill = 1 +fill_from = Vector2(0.5, 0.5) + +[sub_resource type="SphereMesh" id="SphereMesh_l80un"] +material = ExtResource("2_kgj8g") +radius = 0.1 +height = 0.2 +radial_segments = 8 +rings = 6 + +[sub_resource type="Animation" id="Animation_6kr85"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Hand:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0.4, -0.1, 0.3)] +} + +[sub_resource type="Animation" id="Animation_n7s5x"] +resource_name = "press" +length = 0.1667 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Hand:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.033333335, 0.16666667), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0.4, -0.1, 0.3), Vector3(0.4000001, -0.30000007, 0.3), Vector3(0.4, -0.1, 0.3)] +} +tracks/1/type = "audio" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Button/ButtonSfx") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"clips": [{ +"end_offset": 0.0, +"start_offset": 0.0, +"stream": ExtResource("5_6kr85") +}], +"times": PackedFloat32Array(0.033333335) +} +tracks/1/use_blend = true + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_6kr85"] +_data = { +&"RESET": SubResource("Animation_6kr85"), +&"press": SubResource("Animation_n7s5x") +} + +[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_jhw8o"] +random_pitch = 1.122462 +streams_count = 1 +stream_0/stream = ExtResource("7_n7s5x") + +[sub_resource type="Animation" id="Animation_l80un"] +length = 0.001 +tracks/0/type = "position_3d" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("TubeLeft") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = PackedFloat32Array(0, 1, -10, 0, 0) +tracks/1/type = "position_3d" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("TubeRight") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = PackedFloat32Array(0, 1, 10, 0, 0) +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("TubeLeft:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(-10, 0, 0)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("TubeRight:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(10, 0, 0)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("TubeLeft/MashyPlate:scale") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(1, 1, 1)] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("TubeRight/MashyPlate:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(1, 1, 1)] +} + +[sub_resource type="Animation" id="Animation_s6lek"] +resource_name = "crush" +length = 0.13333334 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("TubeLeft:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.0666, 0.13333334), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(-10, 0, 0), Vector3(-4.157, 0, 0), Vector3(-4.19, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("TubeRight:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.0666, 0.13333334), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(10, 0, 0), Vector3(4.15, 0, 0), Vector3(4.2, 0, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("TubeLeft/MashyPlate:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.06666667, 0.13333334), +"transitions": PackedFloat32Array(0, 1, 1), +"update": 0, +"values": [Vector3(1, 1, 1), Vector3(0.6, 1.4, 1), Vector3(1, 1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("TubeRight/MashyPlate:scale") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.06666667, 0.13333334), +"transitions": PackedFloat32Array(0, 1, 1), +"update": 0, +"values": [Vector3(1, 1, 1), Vector3(0.6, 1.4, 1), Vector3(1, 1, 1)] +} +tracks/4/type = "method" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("..") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0.06666667), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"crusher_crush" +}] +} +tracks/5/type = "audio" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("MoveSfx") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"clips": [{ +"end_offset": 0.0, +"start_offset": 0.0, +"stream": ExtResource("7_7r0dx") +}], +"times": PackedFloat32Array(0) +} +tracks/5/use_blend = true + +[sub_resource type="Animation" id="Animation_kgj8g"] +resource_name = "idle" +length = 0.001 +tracks/0/type = "position_3d" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("TubeLeft") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = PackedFloat32Array(0, 1, -10, 0, 0) +tracks/1/type = "position_3d" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("TubeRight") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = PackedFloat32Array(0, 1, 10, 0, 0) + +[sub_resource type="Animation" id="Animation_xptat"] +resource_name = "uncrush" +length = 0.1998 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("TubeLeft:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1998), +"transitions": PackedFloat32Array(3.5, 1), +"update": 0, +"values": [Vector3(-4.209, 0, 0), Vector3(-10, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("TubeRight:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.1998), +"transitions": PackedFloat32Array(3.5, 1), +"update": 0, +"values": [Vector3(4.2, 0, 0), Vector3(10, 0, 0)] +} +tracks/2/type = "audio" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("MoveSfx") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"clips": [{ +"end_offset": 0.0, +"start_offset": 0.0, +"stream": ExtResource("8_htx8b") +}], +"times": PackedFloat32Array(0) +} +tracks/2/use_blend = true + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_kgj8g"] +_data = { +&"RESET": SubResource("Animation_l80un"), +&"crush": SubResource("Animation_s6lek"), +&"idle": SubResource("Animation_kgj8g"), +&"uncrush": SubResource("Animation_xptat") +} + +[sub_resource type="BoxMesh" id="BoxMesh_qnjlk"] +size = Vector3(8, 0.2, 0.2) + +[sub_resource type="BoxMesh" id="BoxMesh_s6lek"] +size = Vector3(0.205, 2.5, 1.5) + +[sub_resource type="TextMesh" id="TextMesh_xptat"] +material = ExtResource("2_kgj8g") +text = "Press J" +font = ExtResource("12_ueio8") +font_size = 64 + +[sub_resource type="TextMesh" id="TextMesh_yarin"] +material = ExtResource("2_kgj8g") +text = "Press D" +font = ExtResource("12_ueio8") +font_size = 64 + +[node name="Game" type="Node3D" unique_id=133158643 node_paths=PackedStringArray("_ui_layer", "_press_d_prompt", "_press_j_prompt", "_d_anim", "_d_button", "_j_anim", "_j_button", "_ghost_spawn_timer", "_crusher", "_slam_sfx", "_splat_sfx", "_crusher_anim")] +script = ExtResource("1_s6lek") +_ui_layer = NodePath("UI") +_press_d_prompt = NodePath("PressDPrompt") +_press_j_prompt = NodePath("PressJPrompt") +_d_anim = NodePath("D/AnimationPlayer") +_d_button = NodePath("D/Button") +_j_anim = NodePath("J/AnimationPlayer") +_j_button = NodePath("J/Button") +_ghost_spawn_timer = NodePath("GhostSpawnTimer") +_ghost_scene = ExtResource("2_l80un") +_crusher = NodePath("Crusher") +_slam_sfx = NodePath("Crusher/SlamSfx") +_splat_sfx = NodePath("Crusher/SplatSfx") +_crusher_anim = NodePath("Crusher/AnimationPlayer") + +[node name="MusicPlayer" type="AudioStreamPlayer" parent="." unique_id=220746864] +stream = ExtResource("3_htx8b") +autoplay = true +bus = &"music" + +[node name="UI" type="CanvasLayer" parent="." unique_id=697702645] + +[node name="TitleLabel" type="Label" parent="UI" unique_id=1741345152] +offset_left = 8.0 +offset_top = 12.0 +offset_right = 170.0 +offset_bottom = 40.0 +theme_override_fonts/font = ExtResource("4_etvrb") +theme_override_font_sizes/font_size = 72 +text = "“D 'n' J Crusher”" + +[node name="WanpLabel" type="Label" parent="UI" unique_id=531736359] +offset_left = 17.0 +offset_top = 100.0 +offset_right = 179.0 +offset_bottom = 128.0 +theme_override_fonts/font = ExtResource("12_ueio8") +text = "manifested by wanp" + +[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1729807054] +environment = SubResource("Environment_jn5yv") + +[node name="Camera3D" type="Camera3D" parent="." unique_id=1917918356] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 4) + +[node name="OmniLight3D" type="OmniLight3D" parent="." unique_id=1281532038] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1.6) +light_color = Color(1, 0.75, 0, 1) +light_energy = 2.0 +omni_shadow_mode = 0 + +[node name="OmniLight3D2" type="OmniLight3D" parent="." unique_id=387250400] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3000001, 1.6) +light_color = Color(1, 0.75, 0, 1) +light_energy = 2.0 +omni_shadow_mode = 0 + +[node name="OmniLight3D3" type="OmniLight3D" parent="." unique_id=1580815460] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2.6999998, 0.100000024) +light_color = Color(1, 0.18333334, 0, 1) +light_energy = 3.0 +omni_shadow_mode = 0 + +[node name="AnimationPlayer" type="AnimationPlayer" parent="OmniLight3D3" unique_id=1586322282] +libraries/ = SubResource("AnimationLibrary_htx8b") +autoplay = &"flicker" + +[node name="PlatformLeft" type="MeshInstance3D" parent="." unique_id=1783405889] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -2.7, 0) +mesh = SubResource("CylinderMesh_s6lek") + +[node name="PlatformRight" type="MeshInstance3D" parent="." unique_id=1346653145] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, -2.7, 0) +mesh = SubResource("CylinderMesh_s6lek") + +[node name="Wall" type="MeshInstance3D" parent="." unique_id=1308282145] +transform = Transform3D(1, 0, 0, 0, -4.371139e-08, -1, 0, 1, -4.371139e-08, 0, -1, -2) +mesh = SubResource("PlaneMesh_qnjlk") + +[node name="D" type="Node3D" parent="." unique_id=928869159] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -1.3000001, 0.20000002) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="D" unique_id=7005501] +libraries/ = SubResource("AnimationLibrary_jhw8o") + +[node name="Orb" type="MeshInstance3D" parent="D" unique_id=762810288] +mesh = SubResource("SphereMesh_kgj8g") +skeleton = NodePath("../..") + +[node name="Eye" type="Sprite3D" parent="D" unique_id=1973646501] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.100000024, 0.100000024, 0.29999998) +pixel_size = 0.02 +billboard = 1 +no_depth_test = true +texture_filter = 0 +texture = SubResource("GradientTexture2D_kgj8g") + +[node name="Eye2" type="Sprite3D" parent="D" unique_id=1067064441] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.20000005, 0.4) +pixel_size = 0.02 +billboard = 1 +no_depth_test = true +texture_filter = 0 +texture = SubResource("GradientTexture2D_kgj8g") + +[node name="Hand" type="MeshInstance3D" parent="D" unique_id=179301020] +transform = Transform3D(1, 0, 0, 0, 1.0000001, 0, 0, 0, 1, -0.4000001, -0.100000024, 0.30000004) +mesh = SubResource("SphereMesh_l80un") + +[node name="Button" parent="D" unique_id=1703705526 instance=ExtResource("4_xptat")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.3849659, -0.39247894, 0.30321684) + +[node name="ButtonSfx" type="AudioStreamPlayer3D" parent="D/Button" unique_id=1459135632] +panning_strength = 2.0 +bus = &"sfx" + +[node name="J" type="Node3D" parent="." unique_id=794820390] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, -1.3, 0.2) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="J" unique_id=1956217934] +libraries/ = SubResource("AnimationLibrary_6kr85") + +[node name="Orb" type="MeshInstance3D" parent="J" unique_id=1264857338] +mesh = SubResource("SphereMesh_kgj8g") +skeleton = NodePath("../..") + +[node name="Eye" type="Sprite3D" parent="J" unique_id=1330761631] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.1, 0.1, 0.3) +pixel_size = 0.02 +billboard = 1 +no_depth_test = true +texture_filter = 0 +texture = SubResource("GradientTexture2D_kgj8g") + +[node name="Eye2" type="Sprite3D" parent="J" unique_id=1441343203] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 0.2, 0.4) +pixel_size = 0.02 +billboard = 1 +no_depth_test = true +texture_filter = 0 +texture = SubResource("GradientTexture2D_kgj8g") + +[node name="Hand" type="MeshInstance3D" parent="J" unique_id=2003843339] +transform = Transform3D(1, 0, 0, 0, 1.0000001, 0, 0, 0, 1, 0.4, -0.1, 0.3) +mesh = SubResource("SphereMesh_l80un") +skeleton = NodePath("../../D") + +[node name="Button" parent="J" unique_id=1343560287 instance=ExtResource("4_xptat")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.385, -0.392, 0.303) + +[node name="ButtonSfx" type="AudioStreamPlayer3D" parent="J/Button" unique_id=2054923244] +panning_strength = 2.0 +bus = &"sfx" + +[node name="Crusher" type="Node3D" parent="." unique_id=135343329] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.7, 0) + +[node name="MoveSfx" type="AudioStreamPlayer3D" parent="Crusher" unique_id=154564713] +bus = &"sfx" + +[node name="SlamSfx" type="AudioStreamPlayer3D" parent="Crusher" unique_id=1867676118] +stream = ExtResource("6_jhw8o") +volume_db = -9.0 +bus = &"sfx" + +[node name="SplatSfx" type="AudioStreamPlayer3D" parent="Crusher" unique_id=995157383] +stream = SubResource("AudioStreamRandomizer_jhw8o") +volume_db = -8.0 +bus = &"sfx" + +[node name="AnimationPlayer" type="AnimationPlayer" parent="Crusher" unique_id=1632097092] +libraries/ = SubResource("AnimationLibrary_kgj8g") + +[node name="TubeLeft" type="MeshInstance3D" parent="Crusher" unique_id=5559250] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10, 0, 0) +mesh = SubResource("BoxMesh_qnjlk") + +[node name="MashyPlate" type="MeshInstance3D" parent="Crusher/TubeLeft" unique_id=1333803171] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.1, 0, 0) +mesh = SubResource("BoxMesh_s6lek") + +[node name="TubeRight" type="MeshInstance3D" parent="Crusher" unique_id=1854970319] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10, 0, 0) +mesh = SubResource("BoxMesh_qnjlk") + +[node name="MashyPlate" type="MeshInstance3D" parent="Crusher/TubeRight" unique_id=773801297] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.1, 0, 0) +mesh = SubResource("BoxMesh_s6lek") +skeleton = NodePath("../../TubeLeft") + +[node name="GhostSpawnTimer" type="Timer" parent="." unique_id=1851782317] + +[node name="PressJPrompt" type="MeshInstance3D" parent="." unique_id=1875037720] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.6, 0.2, 0) +mesh = SubResource("TextMesh_xptat") + +[node name="Arrow" parent="PressJPrompt" unique_id=1726557209 instance=ExtResource("6_yarin")] +transform = Transform3D(0.93969274, 0.34202018, 0, -0.34202018, 0.93969274, 0, 0, 0, 1, 0.8000001, -0.6000001, 0) + +[node name="PressDPrompt" type="MeshInstance3D" parent="." unique_id=1772110792] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.6, 0.2, 0) +mesh = SubResource("TextMesh_yarin") + +[node name="Arrow" parent="PressDPrompt" unique_id=596720032 instance=ExtResource("6_yarin")] +transform = Transform3D(0.76604456, 0.64278764, 0, -0.64278764, 0.76604456, 0, 0, 0, 1, 0.6000002, -0.6000001, 0) + +[connection signal="timeout" from="GhostSpawnTimer" to="." method="_on_ghost_spawn_timer_timeout"] diff --git a/src/game/ghost.gd b/src/game/ghost.gd new file mode 100644 index 0000000..4aae83c --- /dev/null +++ b/src/game/ghost.gd @@ -0,0 +1,43 @@ +class_name Ghost +extends Node3D + +static var _models: Array[PackedScene] = [ + load("res://assets/ghost1.glb"), + load("res://assets/ghost2.glb"), + load("res://assets/ghost3.glb"), +] + +var _rise_speed := 0.0 +var _turn_speed := 0.0 +var _fall_velocity := 0.0 + +var is_crushed := false + + +func _ready() -> void: + add_child(_models.pick_random().instantiate()) + _rise_speed = randf_range(0.06, 0.1) + _turn_speed = randf_range(0.06, 0.2) * [1, -1].pick_random() + + +func _physics_process(_delta: float) -> void: + if not is_crushed: + position.y += _rise_speed + rotate_y(_turn_speed) + else: + _fall_velocity += -0.002 + position.y += _fall_velocity + + +func crush(final_position_x: float) -> void: + is_crushed = true + + position.x = final_position_x + rotation.y = 0 + scale.x = 0.2 + scale.y = 1.4 + reset_physics_interpolation() + + +func _on_screen_exited() -> void: + queue_free() diff --git a/src/game/ghost.gd.uid b/src/game/ghost.gd.uid new file mode 100644 index 0000000..dac8f84 --- /dev/null +++ b/src/game/ghost.gd.uid @@ -0,0 +1 @@ +uid://duakb2887lc64 diff --git a/src/game/ghost.gdshader b/src/game/ghost.gdshader new file mode 100644 index 0000000..a01de72 --- /dev/null +++ b/src/game/ghost.gdshader @@ -0,0 +1,7 @@ +shader_type spatial; +render_mode unshaded; + +void fragment() { + ALBEDO = vec3(1); + ALPHA = 0.5; +} diff --git a/src/game/ghost.gdshader.uid b/src/game/ghost.gdshader.uid new file mode 100644 index 0000000..aabf064 --- /dev/null +++ b/src/game/ghost.gdshader.uid @@ -0,0 +1 @@ +uid://dwh2j57d7dtt7 diff --git a/src/game/ghost.tscn b/src/game/ghost.tscn new file mode 100644 index 0000000..a90246d --- /dev/null +++ b/src/game/ghost.tscn @@ -0,0 +1,11 @@ +[gd_scene format=3 uid="uid://sdd62ogittlq"] + +[ext_resource type="Script" uid="uid://duakb2887lc64" path="res://src/game/ghost.gd" id="1_jtw1h"] + +[node name="Ghost" type="Node3D" unique_id=80173777 groups=["ghosts"]] +script = ExtResource("1_jtw1h") + +[node name="VisibleOnScreenNotifier3D" type="VisibleOnScreenNotifier3D" parent="." unique_id=1773071315] +aabb = AABB(-0.4, -0.4, -0.4, 0.8, 0.8, 0.8) + +[connection signal="screen_exited" from="VisibleOnScreenNotifier3D" to="." method="_on_screen_exited"] diff --git a/src/game/ghost_material.tres b/src/game/ghost_material.tres new file mode 100644 index 0000000..6af2dd4 --- /dev/null +++ b/src/game/ghost_material.tres @@ -0,0 +1,7 @@ +[gd_resource type="ShaderMaterial" format=3 uid="uid://b2fsxx7piy766"] + +[ext_resource type="Shader" uid="uid://dwh2j57d7dtt7" path="res://src/game/ghost.gdshader" id="1_n2xwl"] + +[resource] +render_priority = 0 +shader = ExtResource("1_n2xwl") diff --git a/src/game/wall.gdshader b/src/game/wall.gdshader new file mode 100644 index 0000000..f02aab6 --- /dev/null +++ b/src/game/wall.gdshader @@ -0,0 +1,8 @@ +shader_type spatial; +render_mode unshaded; + +uniform sampler2D texture_image : source_color; + +void fragment() { + ALBEDO = texture(texture_image, UV).rgb; +} diff --git a/src/game/wall.gdshader.uid b/src/game/wall.gdshader.uid new file mode 100644 index 0000000..7b83aa0 --- /dev/null +++ b/src/game/wall.gdshader.uid @@ -0,0 +1 @@ +uid://dyjjgyovssd7s diff --git a/src/game/wall_material.tres b/src/game/wall_material.tres new file mode 100644 index 0000000..ad34f31 --- /dev/null +++ b/src/game/wall_material.tres @@ -0,0 +1,30 @@ +[gd_resource type="ShaderMaterial" format=3 uid="uid://di0etogxlb5dq"] + +[ext_resource type="Shader" uid="uid://dyjjgyovssd7s" path="res://src/game/wall.gdshader" id="1_q0bvm"] + +[sub_resource type="Gradient" id="Gradient_igrk8"] +interpolation_mode = 2 +offsets = PackedFloat32Array(0.23913044, 1) +colors = PackedColorArray(0, 0, 0, 1, 0.26, 0, 0.004333267, 1) + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_5bnbn"] +noise_type = 2 +seed = 255 +frequency = 0.0879 +fractal_type = 0 +domain_warp_enabled = true +domain_warp_type = 2 +domain_warp_fractal_gain = 0.0 + +[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_igrk8"] +width = 64 +height = 64 +generate_mipmaps = false +noise = SubResource("FastNoiseLite_5bnbn") +color_ramp = SubResource("Gradient_igrk8") +seamless = true + +[resource] +render_priority = 0 +shader = ExtResource("1_q0bvm") +shader_parameter/texture_image = SubResource("NoiseTexture2D_igrk8")