diff --git a/assets/alien ship/Mega_boss.png b/assets/alien ship/Mega_boss.png new file mode 100644 index 0000000..c87aa22 Binary files /dev/null and b/assets/alien ship/Mega_boss.png differ diff --git a/assets/alien ship/Mega_boss.png.import b/assets/alien ship/Mega_boss.png.import new file mode 100644 index 0000000..530ef35 --- /dev/null +++ b/assets/alien ship/Mega_boss.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c3x33x6ebn57b" +path="res://.godot/imported/Mega_boss.png-bf85d47b027baa1e1dda02ec00aaf874.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Mega_boss.png" +dest_files=["res://.godot/imported/Mega_boss.png-bf85d47b027baa1e1dda02ec00aaf874.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 diff --git a/assets/alien ship/Ship_1.png b/assets/alien ship/Ship_1.png new file mode 100644 index 0000000..443005b Binary files /dev/null and b/assets/alien ship/Ship_1.png differ diff --git a/assets/alien ship/Ship_1.png.import b/assets/alien ship/Ship_1.png.import new file mode 100644 index 0000000..f07e6d7 --- /dev/null +++ b/assets/alien ship/Ship_1.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c7h3eu21r0pdl" +path="res://.godot/imported/Ship_1.png-1b656f872aea9da20f7c1a3da5574354.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Ship_1.png" +dest_files=["res://.godot/imported/Ship_1.png-1b656f872aea9da20f7c1a3da5574354.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 diff --git a/assets/alien ship/Ship_10.png b/assets/alien ship/Ship_10.png new file mode 100644 index 0000000..ca3c0ed Binary files /dev/null and b/assets/alien ship/Ship_10.png differ diff --git a/assets/alien ship/Ship_10.png.import b/assets/alien ship/Ship_10.png.import new file mode 100644 index 0000000..9b0db37 --- /dev/null +++ b/assets/alien ship/Ship_10.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://br0by5knq4xcd" +path="res://.godot/imported/Ship_10.png-181656ea5444ce23d5114ccd5959e373.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Ship_10.png" +dest_files=["res://.godot/imported/Ship_10.png-181656ea5444ce23d5114ccd5959e373.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 diff --git a/assets/alien ship/Ship_11.png b/assets/alien ship/Ship_11.png new file mode 100644 index 0000000..e415e93 Binary files /dev/null and b/assets/alien ship/Ship_11.png differ diff --git a/assets/alien ship/Ship_11.png.import b/assets/alien ship/Ship_11.png.import new file mode 100644 index 0000000..d579f49 --- /dev/null +++ b/assets/alien ship/Ship_11.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://1j4agumqwdw" +path="res://.godot/imported/Ship_11.png-a3a8c23e80c087eb2d5a7c1d35454db0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Ship_11.png" +dest_files=["res://.godot/imported/Ship_11.png-a3a8c23e80c087eb2d5a7c1d35454db0.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 diff --git a/assets/alien ship/Ship_2.png b/assets/alien ship/Ship_2.png new file mode 100644 index 0000000..d4b67ee Binary files /dev/null and b/assets/alien ship/Ship_2.png differ diff --git a/assets/alien ship/Ship_2.png.import b/assets/alien ship/Ship_2.png.import new file mode 100644 index 0000000..290d0ae --- /dev/null +++ b/assets/alien ship/Ship_2.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cplj5i7unj0yy" +path="res://.godot/imported/Ship_2.png-836e9742c783279d79702d4d44a9424e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Ship_2.png" +dest_files=["res://.godot/imported/Ship_2.png-836e9742c783279d79702d4d44a9424e.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 diff --git a/assets/alien ship/Ship_3.png b/assets/alien ship/Ship_3.png new file mode 100644 index 0000000..6f20760 Binary files /dev/null and b/assets/alien ship/Ship_3.png differ diff --git a/assets/alien ship/Ship_3.png.import b/assets/alien ship/Ship_3.png.import new file mode 100644 index 0000000..a8725d9 --- /dev/null +++ b/assets/alien ship/Ship_3.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bjqq6luawkquo" +path="res://.godot/imported/Ship_3.png-61c5e728de9904608dc0b31cc30fbb7a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Ship_3.png" +dest_files=["res://.godot/imported/Ship_3.png-61c5e728de9904608dc0b31cc30fbb7a.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 diff --git a/assets/alien ship/Ship_4.png b/assets/alien ship/Ship_4.png new file mode 100644 index 0000000..3f9963a Binary files /dev/null and b/assets/alien ship/Ship_4.png differ diff --git a/assets/alien ship/Ship_4.png.import b/assets/alien ship/Ship_4.png.import new file mode 100644 index 0000000..8dc0438 --- /dev/null +++ b/assets/alien ship/Ship_4.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://n78njgp7dwal" +path="res://.godot/imported/Ship_4.png-f67c211f798817c01fc865d94538d542.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Ship_4.png" +dest_files=["res://.godot/imported/Ship_4.png-f67c211f798817c01fc865d94538d542.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 diff --git a/assets/alien ship/Ship_5.png b/assets/alien ship/Ship_5.png new file mode 100644 index 0000000..0a68422 Binary files /dev/null and b/assets/alien ship/Ship_5.png differ diff --git a/assets/alien ship/Ship_5.png.import b/assets/alien ship/Ship_5.png.import new file mode 100644 index 0000000..f83d562 --- /dev/null +++ b/assets/alien ship/Ship_5.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cvxyk5bmglyty" +path="res://.godot/imported/Ship_5.png-37fadc8084fc4981736a952456fb4138.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Ship_5.png" +dest_files=["res://.godot/imported/Ship_5.png-37fadc8084fc4981736a952456fb4138.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 diff --git a/assets/alien ship/Ship_6.png b/assets/alien ship/Ship_6.png new file mode 100644 index 0000000..cdd2c51 Binary files /dev/null and b/assets/alien ship/Ship_6.png differ diff --git a/assets/alien ship/Ship_6.png.import b/assets/alien ship/Ship_6.png.import new file mode 100644 index 0000000..808c2e7 --- /dev/null +++ b/assets/alien ship/Ship_6.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://oa0h30qdyv7s" +path="res://.godot/imported/Ship_6.png-8d23118a591825259402721fba78c9e5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Ship_6.png" +dest_files=["res://.godot/imported/Ship_6.png-8d23118a591825259402721fba78c9e5.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 diff --git a/assets/alien ship/Ship_7.png b/assets/alien ship/Ship_7.png new file mode 100644 index 0000000..206350b Binary files /dev/null and b/assets/alien ship/Ship_7.png differ diff --git a/assets/alien ship/Ship_7.png.import b/assets/alien ship/Ship_7.png.import new file mode 100644 index 0000000..ca917b5 --- /dev/null +++ b/assets/alien ship/Ship_7.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bagjfcshrnalm" +path="res://.godot/imported/Ship_7.png-d84ed317c35e2276d32cecd19d94ac0f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Ship_7.png" +dest_files=["res://.godot/imported/Ship_7.png-d84ed317c35e2276d32cecd19d94ac0f.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 diff --git a/assets/alien ship/Ship_8.png b/assets/alien ship/Ship_8.png new file mode 100644 index 0000000..7999162 Binary files /dev/null and b/assets/alien ship/Ship_8.png differ diff --git a/assets/alien ship/Ship_8.png.import b/assets/alien ship/Ship_8.png.import new file mode 100644 index 0000000..91b88e5 --- /dev/null +++ b/assets/alien ship/Ship_8.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bxud4dardpa47" +path="res://.godot/imported/Ship_8.png-b437ac630357d3dce483c3827d6a9a9c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Ship_8.png" +dest_files=["res://.godot/imported/Ship_8.png-b437ac630357d3dce483c3827d6a9a9c.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 diff --git a/assets/alien ship/Ship_9.png b/assets/alien ship/Ship_9.png new file mode 100644 index 0000000..3608243 Binary files /dev/null and b/assets/alien ship/Ship_9.png differ diff --git a/assets/alien ship/Ship_9.png.import b/assets/alien ship/Ship_9.png.import new file mode 100644 index 0000000..dd5fc0b --- /dev/null +++ b/assets/alien ship/Ship_9.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dvhou7qrttih3" +path="res://.godot/imported/Ship_9.png-b496d4396a20584600e6a98a4aac1754.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/alien ship/Ship_9.png" +dest_files=["res://.godot/imported/Ship_9.png-b496d4396a20584600e6a98a4aac1754.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 diff --git a/assets/sounds/effects/laser.mp3 b/assets/sounds/effects/laser.mp3 new file mode 100644 index 0000000..d860246 Binary files /dev/null and b/assets/sounds/effects/laser.mp3 differ diff --git a/assets/sounds/effects/laser.mp3.import b/assets/sounds/effects/laser.mp3.import new file mode 100644 index 0000000..83b9e1d --- /dev/null +++ b/assets/sounds/effects/laser.mp3.import @@ -0,0 +1,19 @@ +[remap] + +importer="mp3" +type="AudioStreamMP3" +uid="uid://bghp7splpu7cn" +path="res://.godot/imported/laser.mp3-816204cfe63e0650f9d8b390ba929d65.mp3str" + +[deps] + +source_file="res://assets/sounds/effects/laser.mp3" +dest_files=["res://.godot/imported/laser.mp3-816204cfe63e0650f9d8b390ba929d65.mp3str"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/assets/sounds/effects/machine_gun.mp3 b/assets/sounds/effects/machine_gun.mp3 new file mode 100644 index 0000000..6aedb10 Binary files /dev/null and b/assets/sounds/effects/machine_gun.mp3 differ diff --git a/assets/sounds/effects/machine_gun.mp3.import b/assets/sounds/effects/machine_gun.mp3.import new file mode 100644 index 0000000..067c7e0 --- /dev/null +++ b/assets/sounds/effects/machine_gun.mp3.import @@ -0,0 +1,19 @@ +[remap] + +importer="mp3" +type="AudioStreamMP3" +uid="uid://br7luda5t0bc2" +path="res://.godot/imported/machine_gun.mp3-067bf737875bd99e14222f63e17599ae.mp3str" + +[deps] + +source_file="res://assets/sounds/effects/machine_gun.mp3" +dest_files=["res://.godot/imported/machine_gun.mp3-067bf737875bd99e14222f63e17599ae.mp3str"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/assets/sounds/effects/plasma.mp3 b/assets/sounds/effects/plasma.mp3 new file mode 100644 index 0000000..c388571 Binary files /dev/null and b/assets/sounds/effects/plasma.mp3 differ diff --git a/assets/sounds/effects/plasma.mp3.import b/assets/sounds/effects/plasma.mp3.import new file mode 100644 index 0000000..f3d9555 --- /dev/null +++ b/assets/sounds/effects/plasma.mp3.import @@ -0,0 +1,19 @@ +[remap] + +importer="mp3" +type="AudioStreamMP3" +uid="uid://bp4qhiifnsf4p" +path="res://.godot/imported/plasma.mp3-7e66ec7af2146408dca3aad21a11f1ee.mp3str" + +[deps] + +source_file="res://assets/sounds/effects/plasma.mp3" +dest_files=["res://.godot/imported/plasma.mp3-7e66ec7af2146408dca3aad21a11f1ee.mp3str"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/assets/sounds/effects/rocket.mp3 b/assets/sounds/effects/rocket.mp3 new file mode 100644 index 0000000..69817c7 Binary files /dev/null and b/assets/sounds/effects/rocket.mp3 differ diff --git a/assets/sounds/effects/rocket.mp3.import b/assets/sounds/effects/rocket.mp3.import new file mode 100644 index 0000000..7978567 --- /dev/null +++ b/assets/sounds/effects/rocket.mp3.import @@ -0,0 +1,19 @@ +[remap] + +importer="mp3" +type="AudioStreamMP3" +uid="uid://b64gbvw28wr8b" +path="res://.godot/imported/rocket.mp3-29b0a44c58434d1ba146675ff1d2febf.mp3str" + +[deps] + +source_file="res://assets/sounds/effects/rocket.mp3" +dest_files=["res://.godot/imported/rocket.mp3-29b0a44c58434d1ba146675ff1d2febf.mp3str"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/assets/sounds/music/game_music.mp3 b/assets/sounds/music/game_music.mp3 new file mode 100644 index 0000000..242e2f0 Binary files /dev/null and b/assets/sounds/music/game_music.mp3 differ diff --git a/assets/sounds/music/game_music.mp3.import b/assets/sounds/music/game_music.mp3.import new file mode 100644 index 0000000..ea97fc1 --- /dev/null +++ b/assets/sounds/music/game_music.mp3.import @@ -0,0 +1,19 @@ +[remap] + +importer="mp3" +type="AudioStreamMP3" +uid="uid://ljqp7yre0v51" +path="res://.godot/imported/game_music.mp3-20c889bd0c692c83f686e0a0181665f3.mp3str" + +[deps] + +source_file="res://assets/sounds/music/game_music.mp3" +dest_files=["res://.godot/imported/game_music.mp3-20c889bd0c692c83f686e0a0181665f3.mp3str"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/assets/sounds/music/menu_music.mp3 b/assets/sounds/music/menu_music.mp3 new file mode 100644 index 0000000..c047a53 Binary files /dev/null and b/assets/sounds/music/menu_music.mp3 differ diff --git a/assets/sounds/music/menu_music.mp3.import b/assets/sounds/music/menu_music.mp3.import new file mode 100644 index 0000000..af56aaf --- /dev/null +++ b/assets/sounds/music/menu_music.mp3.import @@ -0,0 +1,19 @@ +[remap] + +importer="mp3" +type="AudioStreamMP3" +uid="uid://hnnarp1pe60q" +path="res://.godot/imported/menu_music.mp3-aa66988442ee0305322e3502470ef258.mp3str" + +[deps] + +source_file="res://assets/sounds/music/menu_music.mp3" +dest_files=["res://.godot/imported/menu_music.mp3-aa66988442ee0305322e3502470ef258.mp3str"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/resources/items/shield_recharger.tres b/resources/items/shield_recharger.tres new file mode 100644 index 0000000..360d643 --- /dev/null +++ b/resources/items/shield_recharger.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="ItemDefinition" load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1_definition"] + +[resource] +script = ExtResource("1_definition") +item_id = "shield_recharger" +display_name = "Generator tarcz" +category = 1 +description = "Odnawia tarcze statku z szybkością 1 punktu na sekundę." +primary_stat = "shield_regeneration" +primary_value = 1.0 +stat_suffix = " tarczy/s" diff --git a/resources/items/tuned_thrusters.tres b/resources/items/tuned_thrusters.tres new file mode 100644 index 0000000..28f2372 --- /dev/null +++ b/resources/items/tuned_thrusters.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="ItemDefinition" load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1_definition"] + +[resource] +script = ExtResource("1_definition") +item_id = "tuned_thrusters" +display_name = "Dostrojone silniki" +category = 4 +description = "Ulepszone dysze zwiększające prędkość maksymalną statku o 20 px/s." +primary_stat = "max_speed" +primary_value = 20.0 +stat_suffix = " px/s" diff --git a/scenes/game/enemy_plasma_projectile.tscn b/scenes/game/enemy_plasma_projectile.tscn new file mode 100644 index 0000000..dcecae7 --- /dev/null +++ b/scenes/game/enemy_plasma_projectile.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=3 format=3] + +[ext_resource type="Script" path="res://scripts/game/enemy_plasma_projectile.gd" id="1_script"] + +[sub_resource type="CircleShape2D" id="PlasmaProjectileCollision"] +radius = 7.0 + +[node name="EnemyPlasmaProjectile" type="Area2D"] +collision_layer = 0 +collision_mask = 3 +monitoring = true +monitorable = false +script = ExtResource("1_script") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("PlasmaProjectileCollision") diff --git a/scenes/game/enemy_ship.tscn b/scenes/game/enemy_ship.tscn new file mode 100644 index 0000000..837acab --- /dev/null +++ b/scenes/game/enemy_ship.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=3 format=3] + +[ext_resource type="Script" path="res://scripts/game/enemy_ship.gd" id="1_enemy"] + +[sub_resource type="CircleShape2D" id="EnemyCollision"] +radius = 22.0 + +[node name="EnemyShip" type="CharacterBody2D"] +collision_layer = 4 +collision_mask = 2 +script = ExtResource("1_enemy") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture_filter = 1 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("EnemyCollision") diff --git a/scenes/game/game.tscn b/scenes/game/game.tscn index aa07676..c722725 100644 --- a/scenes/game/game.tscn +++ b/scenes/game/game.tscn @@ -1,9 +1,9 @@ -[gd_scene load_steps=12 format=3] +[gd_scene format=3 uid="uid://oy4ny275s23s"] -[ext_resource type="Script" path="res://scripts/game/game.gd" id="1_game"] -[ext_resource type="Script" path="res://scripts/game/space_level_background.gd" id="2_background"] +[ext_resource type="Script" uid="uid://d3behbql2g2b7" path="res://scripts/game/game.gd" id="1_game"] +[ext_resource type="Script" uid="uid://b20w2c0ucytmg" path="res://scripts/game/space_level_background.gd" id="2_background"] [ext_resource type="PackedScene" path="res://scenes/game/player_ship.tscn" id="3_player"] -[ext_resource type="Script" path="res://scripts/game/flight_hud.gd" id="4_hud"] +[ext_resource type="Script" uid="uid://bcfvflaqnmfa5" path="res://scripts/game/flight_hud.gd" id="4_hud"] [ext_resource type="PackedScene" path="res://scenes/ui/ship_equipment_panel.tscn" id="5_equipment"] [ext_resource type="PackedScene" path="res://scenes/ui/ship_inventory_panel.tscn" id="6_inventory"] [ext_resource type="PackedScene" path="res://scenes/game/weapon_test_target.tscn" id="7_target"] @@ -20,42 +20,41 @@ size = Vector2(40, 3600) [sub_resource type="RectangleShape2D" id="RightWall"] size = Vector2(40, 3600) -[node name="Game" type="Node2D"] +[node name="Game" type="Node2D" unique_id=1630707678] script = ExtResource("1_game") -[node name="SpaceBackground" type="Node2D" parent="."] +[node name="SpaceBackground" type="Node2D" parent="." unique_id=300719476] z_index = -20 script = ExtResource("2_background") -[node name="WorldBounds" type="StaticBody2D" parent="."] -collision_layer = 1 +[node name="WorldBounds" type="StaticBody2D" parent="." unique_id=1631186063] collision_mask = 0 -[node name="TopWall" type="CollisionShape2D" parent="WorldBounds"] +[node name="TopWall" type="CollisionShape2D" parent="WorldBounds" unique_id=408485617] position = Vector2(0, -1780) shape = SubResource("TopWall") -[node name="BottomWall" type="CollisionShape2D" parent="WorldBounds"] +[node name="BottomWall" type="CollisionShape2D" parent="WorldBounds" unique_id=264280939] position = Vector2(0, 1780) shape = SubResource("BottomWall") -[node name="LeftWall" type="CollisionShape2D" parent="WorldBounds"] +[node name="LeftWall" type="CollisionShape2D" parent="WorldBounds" unique_id=1859447770] position = Vector2(-2580, 0) shape = SubResource("LeftWall") -[node name="RightWall" type="CollisionShape2D" parent="WorldBounds"] +[node name="RightWall" type="CollisionShape2D" parent="WorldBounds" unique_id=1866196697] position = Vector2(2580, 0) shape = SubResource("RightWall") -[node name="PlayerShip" parent="." instance=ExtResource("3_player")] +[node name="PlayerShip" parent="." unique_id=1837545573 instance=ExtResource("3_player")] -[node name="WeaponTestTarget" parent="." instance=ExtResource("7_target")] +[node name="WeaponTestTarget" parent="." unique_id=1240462223 instance=ExtResource("7_target")] position = Vector2(240, 0) -[node name="HUD" type="CanvasLayer" parent="."] +[node name="HUD" type="CanvasLayer" parent="." unique_id=733012261] script = ExtResource("4_hud") -[node name="HUDRoot" type="Control" parent="HUD"] +[node name="HUDRoot" type="Control" parent="HUD" unique_id=539413585] layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 @@ -64,24 +63,51 @@ grow_horizontal = 2 grow_vertical = 2 mouse_filter = 2 -[node name="DebugToggle" type="Button" parent="HUD/HUDRoot"] +[node name="DebugToggle" type="Button" parent="HUD/HUDRoot" unique_id=1861951018] +layout_mode = 0 offset_left = 18.0 offset_top = 16.0 offset_right = 110.0 offset_bottom = 42.0 -flat = true theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1) text = "DEBUG [−]" +flat = true -[node name="DebugInfo" type="Label" parent="HUD/HUDRoot"] +[node name="DebugInfo" type="Label" parent="HUD/HUDRoot" unique_id=604915599] +layout_mode = 0 offset_left = 22.0 offset_top = 48.0 offset_right = 295.0 offset_bottom = 420.0 theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1) theme_override_font_sizes/font_size = 11 -text = "STATEK\nKADŁUB: 100 / 100\nTARCZE: 100 / 100\nENERGIA: 100 / 100" +text = "STATEK +KADŁUB: 100 / 100 +TARCZE: 100 / 100 +ENERGIA: 100 / 100" -[node name="ShipEquipmentPanel" parent="HUD/HUDRoot" instance=ExtResource("5_equipment")] +[node name="ShipEquipmentPanel" parent="HUD/HUDRoot" unique_id=1637844841 instance=ExtResource("5_equipment")] +layout_mode = 0 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -248.0 +offset_top = 14.0 +offset_right = -14.0 +offset_bottom = 454.0 +grow_horizontal = 0 +grow_vertical = 0 -[node name="ShipInventoryPanel" parent="HUD/HUDRoot" instance=ExtResource("6_inventory")] +[node name="ShipInventoryPanel" parent="HUD/HUDRoot" unique_id=1116676462 instance=ExtResource("6_inventory")] +layout_mode = 0 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -195.0 +offset_top = -165.0 +offset_right = 195.0 +offset_bottom = 165.0 +grow_horizontal = 2 +grow_vertical = 2 diff --git a/scenes/game/impact_effect.tscn b/scenes/game/impact_effect.tscn new file mode 100644 index 0000000..0c22abb --- /dev/null +++ b/scenes/game/impact_effect.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/game/impact_effect.gd" id="1_script"] + +[node name="ImpactEffect" type="Node2D"] +script = ExtResource("1_script") diff --git a/scenes/game/player_ship.tscn b/scenes/game/player_ship.tscn index f3d7efe..ef01a50 100644 --- a/scenes/game/player_ship.tscn +++ b/scenes/game/player_ship.tscn @@ -1,20 +1,25 @@ -[gd_scene load_steps=5 format=3] +[gd_scene load_steps=6 format=3] [ext_resource type="Script" path="res://scripts/game/ship_controller.gd" id="1_controller"] [ext_resource type="Script" path="res://scripts/items/ship_inventory.gd" id="2_inventory"] [ext_resource type="Script" path="res://scripts/game/weapon_controller.gd" id="3_weapons"] +[ext_resource type="Script" path="res://scripts/game/shield_visual.gd" id="4_shield"] [sub_resource type="CircleShape2D" id="ShipCollision"] radius = 18.0 [node name="PlayerShip" type="CharacterBody2D"] collision_layer = 2 -collision_mask = 1 +collision_mask = 5 script = ExtResource("1_controller") [node name="Sprite2D" type="Sprite2D" parent="."] texture_filter = 1 +[node name="ShieldVisual" type="Node2D" parent="."] +z_index = 2 +script = ExtResource("4_shield") + [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource("ShipCollision") diff --git a/scenes/game/weapon_projectile.tscn b/scenes/game/weapon_projectile.tscn index d14d3c4..c0fb936 100644 --- a/scenes/game/weapon_projectile.tscn +++ b/scenes/game/weapon_projectile.tscn @@ -7,7 +7,7 @@ radius = 6.0 [node name="WeaponProjectile" type="Area2D"] collision_layer = 0 -collision_mask = 5 +collision_mask = 13 monitoring = true monitorable = false script = ExtResource("1_projectile") diff --git a/scenes/game/weapon_test_target.tscn b/scenes/game/weapon_test_target.tscn index 16237d3..5835e55 100644 --- a/scenes/game/weapon_test_target.tscn +++ b/scenes/game/weapon_test_target.tscn @@ -7,7 +7,7 @@ radius = 27.0 [node name="WeaponTestTarget" type="StaticBody2D"] -collision_layer = 4 +collision_layer = 8 collision_mask = 0 script = ExtResource("1_script") diff --git a/scripts/game/enemy_plasma_projectile.gd b/scripts/game/enemy_plasma_projectile.gd new file mode 100644 index 0000000..6aaa97d --- /dev/null +++ b/scripts/game/enemy_plasma_projectile.gd @@ -0,0 +1,49 @@ +extends Area2D + +const DAMAGE_POPUP_SCENE := preload("res://scenes/game/damage_popup.tscn") +const IMPACT_EFFECT_SCENE := preload("res://scenes/game/impact_effect.tscn") + +var direction := Vector2.UP +var projectile_speed := 300.0 +var damage := 8.0 +var max_range := 1000.0 +var _distance_travelled := 0.0 + +func _ready() -> void: + body_entered.connect(_on_body_entered) + +func configure(start_position: Vector2, travel_direction: Vector2, projectile_damage: float) -> void: + global_position = start_position + direction = travel_direction.normalized() + damage = projectile_damage + rotation = direction.angle() + +func _physics_process(delta: float) -> void: + var step := projectile_speed * delta + var next_position := global_position + direction * step + var query := PhysicsRayQueryParameters2D.create(global_position, next_position, collision_mask, [get_rid()]) + var hit := get_world_2d().direct_space_state.intersect_ray(query) + if not hit.is_empty(): + global_position = hit["position"] + _hit_target(hit.get("collider")) + return + global_position = next_position + _distance_travelled += step + if _distance_travelled >= max_range: + queue_free() + +func _draw() -> void: + draw_circle(Vector2.ZERO, 6.0, Color(1.0, 0.24, 0.32, 0.98)) + draw_circle(Vector2.ZERO, 3.0, Color(1.0, 0.82, 0.7, 1.0)) + +func _on_body_entered(body: Node2D) -> void: + _hit_target(body) + +func _hit_target(target: Variant) -> void: + var effect := IMPACT_EFFECT_SCENE.instantiate() as Node2D + effect.global_position = global_position + get_parent().add_child(effect) + effect.call("configure", false, Color(1.0, 0.32, 0.38)) + if target is Node and target.has_method("take_damage"): + target.call("take_damage", damage) + queue_free() diff --git a/scripts/game/enemy_plasma_projectile.gd.uid b/scripts/game/enemy_plasma_projectile.gd.uid new file mode 100644 index 0000000..add62a2 --- /dev/null +++ b/scripts/game/enemy_plasma_projectile.gd.uid @@ -0,0 +1 @@ +uid://c47empdk2n8j4 diff --git a/scripts/game/enemy_ship.gd b/scripts/game/enemy_ship.gd new file mode 100644 index 0000000..a4bae23 --- /dev/null +++ b/scripts/game/enemy_ship.gd @@ -0,0 +1,94 @@ +extends CharacterBody2D + +const DAMAGE_POPUP_SCENE := preload("res://scenes/game/damage_popup.tscn") +const IMPACT_EFFECT_SCENE := preload("res://scenes/game/impact_effect.tscn") +const PLASMA_PROJECTILE_SCENE := preload("res://scenes/game/enemy_plasma_projectile.tscn") +const WEAPON_AUDIO_SCRIPT := preload("res://scripts/game/weapon_audio.gd") + +@export var max_hull := 50.0 +@export var activation_range := 760.0 +@export var approach_speed := 62.0 +@export var approach_acceleration := 85.0 +@export var turn_speed := 1.8 +@export var weapon_range := 680.0 +@export var weapon_cooldown := 1.5 +@export var weapon_damage := 8.0 + +var hull := 50.0 +var _player: CharacterBody2D +var _activated := false +var _sprite: Sprite2D +var _weapon_timer := 0.0 + +func _ready() -> void: + hull = max_hull + _sprite = $Sprite2D + add_to_group("enemies") + _weapon_timer = randf_range(0.2, weapon_cooldown) + +func configure(player: CharacterBody2D, ship_texture: Texture2D) -> void: + _player = player + _sprite = $Sprite2D + _sprite.texture = ship_texture + var largest_dimension := maxf(ship_texture.get_width(), ship_texture.get_height()) + _sprite.scale = Vector2.ONE * (56.0 / largest_dimension) + +func _physics_process(delta: float) -> void: + if not is_instance_valid(_player): + velocity = velocity.move_toward(Vector2.ZERO, approach_acceleration * delta) + move_and_slide() + return + + var to_player := _player.global_position - global_position + if to_player.length() <= activation_range: + _activated = true + if _activated and to_player.length_squared() > 1.0: + var direction := to_player.normalized() + var desired_rotation := direction.angle() + PI * 0.5 + rotation = rotate_toward(rotation, desired_rotation, turn_speed * delta) + velocity = velocity.move_toward(direction * approach_speed, approach_acceleration * delta) + _weapon_timer = maxf(0.0, _weapon_timer - delta) + if to_player.length() <= weapon_range and _weapon_timer <= 0.0: + _fire_plasma(direction) + _weapon_timer = weapon_cooldown + else: + velocity = velocity.move_toward(Vector2.ZERO, approach_acceleration * delta) + + move_and_slide() + _check_player_collision() + +func _check_player_collision() -> void: + for collision_index in get_slide_collision_count(): + var collision := get_slide_collision(collision_index) + if collision.get_collider() == _player and _player.has_method("register_enemy_collision"): + _player.call("register_enemy_collision", global_position) + +func _fire_plasma(direction: Vector2) -> void: + var projectile := PLASMA_PROJECTILE_SCENE.instantiate() as Area2D + projectile.call("configure", global_position + direction * 28.0, direction, weapon_damage) + get_parent().add_child(projectile) + WEAPON_AUDIO_SCRIPT.play(get_parent(), global_position, ItemDefinition.WeaponKind.PLASMA, -10.0) + +func take_damage(amount: float) -> void: + hull = maxf(0.0, hull - amount) + _show_damage_popup(amount) + if hull <= 0.0: + _spawn_destruction_effect() + queue_free() + +func _spawn_destruction_effect() -> void: + var effect := IMPACT_EFFECT_SCENE.instantiate() as Node2D + effect.global_position = global_position + get_parent().add_child(effect) + effect.call("configure", true, Color(1.0, 0.36, 0.18)) + +func _show_damage_popup(amount: float) -> void: + var popup := DAMAGE_POPUP_SCENE.instantiate() as Label + popup.text = "-%s DMG" % _format_damage(amount) + popup.global_position = global_position + Vector2(randf_range(-16.0, 16.0), -28.0) + get_parent().add_child(popup) + +func _format_damage(amount: float) -> String: + if is_equal_approx(amount, roundf(amount)): + return str(int(roundf(amount))) + return "%.1f" % amount diff --git a/scripts/game/enemy_ship.gd.uid b/scripts/game/enemy_ship.gd.uid new file mode 100644 index 0000000..5220c8e --- /dev/null +++ b/scripts/game/enemy_ship.gd.uid @@ -0,0 +1 @@ +uid://dlnki63o425ys diff --git a/scripts/game/flight_hud.gd b/scripts/game/flight_hud.gd index d8ca5cf..afe2f38 100644 --- a/scripts/game/flight_hud.gd +++ b/scripts/game/flight_hud.gd @@ -30,6 +30,7 @@ KADŁUB: %d / %d TARCZE: %d / %d ENERGIA: %d / %d ENERGIA REGEN: %.1f /s +TARCZE REGEN: %.1f /s RUCH PRĘDKOŚĆ: %.1f px/s @@ -43,6 +44,7 @@ OBRÓT: %.2f rad/s""" % [ roundi(float(player.get("shields"))), roundi(float(player.get("max_shields"))), roundi(float(player.get("energy"))), roundi(float(player.get("max_energy"))), float(player.get("energy_regeneration")), + float(player.get("shield_regeneration")), ship_velocity.length(), ship_velocity.x, ship_velocity.y, ship_position.x, ship_position.y, rad_to_deg(player.rotation), angular_speed, ] diff --git a/scripts/game/game.gd b/scripts/game/game.gd index 4792e17..3e16185 100644 --- a/scripts/game/game.gd +++ b/scripts/game/game.gd @@ -1,6 +1,23 @@ extends Node2D const WORLD_SIZE := Vector2(5200.0, 3600.0) +const ENEMY_COUNT := 20 +const SAFE_ZONE_RADIUS := 440.0 +const ENEMY_MIN_SEPARATION := 240.0 +const ENEMY_SCENE := preload("res://scenes/game/enemy_ship.tscn") +const ENEMY_TEXTURES: Array[Texture2D] = [ + preload("res://assets/alien ship/Ship_1.png"), + preload("res://assets/alien ship/Ship_2.png"), + preload("res://assets/alien ship/Ship_3.png"), + preload("res://assets/alien ship/Ship_4.png"), + preload("res://assets/alien ship/Ship_5.png"), + preload("res://assets/alien ship/Ship_6.png"), + preload("res://assets/alien ship/Ship_7.png"), + preload("res://assets/alien ship/Ship_8.png"), + preload("res://assets/alien ship/Ship_9.png"), + preload("res://assets/alien ship/Ship_10.png"), + preload("res://assets/alien ship/Ship_11.png"), +] @onready var player: CharacterBody2D = $PlayerShip @@ -12,3 +29,31 @@ func _ready() -> void: camera.limit_right = int(WORLD_SIZE.x * 0.5) camera.limit_top = int(-WORLD_SIZE.y * 0.5) camera.limit_bottom = int(WORLD_SIZE.y * 0.5) + _spawn_enemies() + +func _spawn_enemies() -> void: + var rng := RandomNumberGenerator.new() + rng.randomize() + var spawn_positions: Array[Vector2] = [] + var attempts := 0 + while spawn_positions.size() < ENEMY_COUNT and attempts < 3000: + attempts += 1 + var candidate := Vector2( + rng.randf_range(-WORLD_SIZE.x * 0.5 + 130.0, WORLD_SIZE.x * 0.5 - 130.0), + rng.randf_range(-WORLD_SIZE.y * 0.5 + 130.0, WORLD_SIZE.y * 0.5 - 130.0) + ) + if candidate.length_squared() < SAFE_ZONE_RADIUS * SAFE_ZONE_RADIUS: + continue + var too_close := false + for other_position in spawn_positions: + if candidate.distance_squared_to(other_position) < ENEMY_MIN_SEPARATION * ENEMY_MIN_SEPARATION: + too_close = true + break + if not too_close: + spawn_positions.append(candidate) + + for spawn_position in spawn_positions: + var enemy := ENEMY_SCENE.instantiate() as CharacterBody2D + enemy.position = spawn_position + add_child(enemy) + enemy.call("configure", player, ENEMY_TEXTURES[rng.randi_range(0, ENEMY_TEXTURES.size() - 1)]) diff --git a/scripts/game/impact_effect.gd b/scripts/game/impact_effect.gd new file mode 100644 index 0000000..79cec70 --- /dev/null +++ b/scripts/game/impact_effect.gd @@ -0,0 +1,54 @@ +extends Node2D + +var _effect_color := Color(1.0, 0.72, 0.32) +var _elapsed := 0.0 +var _duration := 0.28 +var _is_explosion := false +var _directions: Array[Vector2] = [] +var _speeds: Array[float] = [] +var _sizes: Array[float] = [] + +func configure(is_explosion: bool, effect_color: Color) -> void: + _is_explosion = is_explosion + _effect_color = effect_color + _duration = 0.58 if is_explosion else 0.28 + var rng := RandomNumberGenerator.new() + rng.randomize() + var spark_count := 26 if is_explosion else 9 + for _spark_index in spark_count: + _directions.append(Vector2.RIGHT.rotated(rng.randf_range(0.0, TAU))) + _speeds.append(rng.randf_range(70.0, 230.0) if is_explosion else rng.randf_range(65.0, 155.0)) + _sizes.append(rng.randf_range(2.0, 5.0) if is_explosion else rng.randf_range(1.5, 3.5)) + z_index = 40 + queue_redraw() + +func _process(delta: float) -> void: + _elapsed += delta + if _elapsed >= _duration: + queue_free() + return + queue_redraw() + +func _draw() -> void: + var progress := clampf(_elapsed / _duration, 0.0, 1.0) + var fade := 1.0 - progress + var ring_start := 9.0 if _is_explosion else 3.0 + var ring_growth := 72.0 if _is_explosion else 38.0 + draw_arc( + Vector2.ZERO, + ring_start + ring_growth * progress, + 0.0, + TAU, + 40, + Color(_effect_color.r, _effect_color.g, _effect_color.b, fade * (0.75 if _is_explosion else 0.55)), + 2.5 if _is_explosion else 1.5 + ) + if _is_explosion: + draw_circle(Vector2.ZERO, 18.0 * (1.0 - progress), Color(1.0, 0.82, 0.55, fade * 0.65)) + for spark_index in _directions.size(): + var direction := _directions[spark_index] + var travel := _speeds[spark_index] * _elapsed + var tip := direction * travel + var tail := tip - direction * _sizes[spark_index] * (2.0 + fade * 2.0) + draw_line(tail, tip, Color(_effect_color.r, _effect_color.g, _effect_color.b, fade), _sizes[spark_index]) + draw_circle(tip, maxf(0.7, _sizes[spark_index] * 0.45), Color(1.0, 0.9, 0.72, fade)) diff --git a/scripts/game/impact_effect.gd.uid b/scripts/game/impact_effect.gd.uid new file mode 100644 index 0000000..af0ef35 --- /dev/null +++ b/scripts/game/impact_effect.gd.uid @@ -0,0 +1 @@ +uid://72jgwxdutqml diff --git a/scripts/game/shield_visual.gd b/scripts/game/shield_visual.gd new file mode 100644 index 0000000..707e488 --- /dev/null +++ b/scripts/game/shield_visual.gd @@ -0,0 +1,50 @@ +extends Node2D + +var current_shields := 100.0 +var max_shields := 100.0 +var _hit_flash_timer := 0.0 + +func _process(delta: float) -> void: + visible = current_shields > 0.0 + if not visible: + return + _hit_flash_timer = maxf(0.0, _hit_flash_timer - delta) + queue_redraw() + +func set_shield_values(current: float, maximum: float) -> void: + current_shields = current + max_shields = maxf(1.0, maximum) + visible = current_shields > 0.0 + queue_redraw() + +func flash_hit() -> void: + _hit_flash_timer = 0.22 + queue_redraw() + +func _draw() -> void: + if current_shields <= 0.0: + return + var shield_ratio := clampf(current_shields / max_shields, 0.0, 1.0) + var pulse := 0.035 + (sin(float(Time.get_ticks_msec()) * 0.004) + 1.0) * 0.018 + var flash := clampf(_hit_flash_timer / 0.22, 0.0, 1.0) + draw_circle(Vector2.ZERO, 35.0, Color(0.12, 0.72, 1.0, pulse + flash * 0.08)) + draw_arc( + Vector2.ZERO, + 36.0, + 0.0, + TAU, + 64, + Color(0.35, 0.84, 1.0, 0.3 + shield_ratio * 0.25 + flash * 0.45), + 2.0 + flash * 2.0 + ) + for arc_index in 3: + var start_angle := float(arc_index) * TAU / 3.0 + 0.2 + draw_arc( + Vector2.ZERO, + 40.0, + start_angle, + start_angle + 0.72, + 16, + Color(0.28, 0.78, 1.0, 0.28 + flash * 0.55), + 1.5 + flash + ) diff --git a/scripts/game/shield_visual.gd.uid b/scripts/game/shield_visual.gd.uid new file mode 100644 index 0000000..1669442 --- /dev/null +++ b/scripts/game/shield_visual.gd.uid @@ -0,0 +1 @@ +uid://w0t7eo1lt1b8 diff --git a/scripts/game/ship_controller.gd b/scripts/game/ship_controller.gd index 1d512e7..abe1d3f 100644 --- a/scripts/game/ship_controller.gd +++ b/scripts/game/ship_controller.gd @@ -1,11 +1,12 @@ extends CharacterBody2D const DEFAULT_SHIP_TEXTURE := "res://assets/Ships/Spaceship_0.png" +const IMPACT_EFFECT_SCENE := preload("res://scenes/game/impact_effect.tscn") -@export var max_speed := 420.0 +@export var max_speed := 76.0 @export var reverse_max_speed := 210.0 @export var max_strafe_speed := 210.0 -@export var thrust_acceleration := 260.0 +@export var thrust_acceleration := 90.0 @export var brake_acceleration := 540.0 @export var space_drag := 24.0 @export var max_turn_speed := 2.8 @@ -15,8 +16,9 @@ const DEFAULT_SHIP_TEXTURE := "res://assets/Ships/Spaceship_0.png" @export var base_max_hull := 100.0 @export var base_max_shields := 100.0 @export var base_max_energy := 100.0 -@export var base_max_speed := 420.0 +@export var base_max_speed := 90.0 @export var base_energy_regeneration := 12.0 +@export var base_shield_regeneration := 0.0 @export var max_hull := 100.0 @export var max_shields := 100.0 @export var max_energy := 100.0 @@ -24,9 +26,13 @@ var hull := 100.0 var shields := 100.0 var energy := 100.0 var energy_regeneration := 12.0 +var shield_regeneration := 0.0 var angular_velocity := 0.0 var _sprite: Sprite2D +var _contact_damage_timer := 0.0 +var _is_destroyed := false +@onready var _shield_visual: Node2D = $ShieldVisual func apply_equipment_bonuses(bonuses: Dictionary) -> void: max_hull = base_max_hull + float(bonuses.get("max_hull", 0.0)) @@ -34,11 +40,13 @@ func apply_equipment_bonuses(bonuses: Dictionary) -> void: max_energy = base_max_energy + float(bonuses.get("max_energy", 0.0)) max_speed = base_max_speed + float(bonuses.get("max_speed", 0.0)) energy_regeneration = base_energy_regeneration + float(bonuses.get("energy_regeneration", 0.0)) + shield_regeneration = base_shield_regeneration + float(bonuses.get("shield_regeneration", 0.0)) reverse_max_speed = max_speed * 0.5 max_strafe_speed = max_speed * 0.5 hull = minf(hull, max_hull) shields = minf(shields, max_shields) energy = minf(energy, max_energy) + _update_shield_visual() func _ready() -> void: _ensure_input_action(&"ship_thrust", KEY_W) @@ -58,6 +66,7 @@ func _ready() -> void: _sprite.texture = ship_texture var largest_dimension := maxf(ship_texture.get_width(), ship_texture.get_height()) _sprite.scale = Vector2.ONE * (64.0 / largest_dimension) + _update_shield_visual() func _ensure_input_action(action_name: StringName, physical_key: Key) -> void: if not InputMap.has_action(action_name): @@ -67,8 +76,67 @@ func _ensure_input_action(action_name: StringName, physical_key: Key) -> void: if not InputMap.action_has_event(action_name, event): InputMap.action_add_event(action_name, event) +func take_damage(amount: float) -> void: + if _is_destroyed: + return + var remaining_damage := maxf(0.0, amount) + var shield_damage := minf(shields, remaining_damage) + shields -= shield_damage + remaining_damage -= shield_damage + hull = maxf(0.0, hull - remaining_damage) + if shield_damage > 0.0 and shields > 0.0: + _shield_visual.call("flash_hit") + _update_shield_visual() + if hull <= 0.0: + _destroy_ship() + +func register_enemy_collision(enemy_position: Vector2) -> void: + if _is_destroyed or _contact_damage_timer > 0.0: + return + var push_direction := global_position - enemy_position + if push_direction.length_squared() < 0.001: + push_direction = -velocity if velocity.length_squared() > 0.001 else Vector2.UP.rotated(rotation) + push_direction = push_direction.normalized() + velocity = velocity.bounce(push_direction) * 0.55 + push_direction * 110.0 + _clamp_velocity_to_max_speed() + _contact_damage_timer = 0.8 + _spawn_hit_effect(global_position, Color(0.65, 0.9, 1.0)) + take_damage(max_hull * 0.01) + +func _spawn_hit_effect(at_position: Vector2, effect_color: Color) -> void: + var effect := IMPACT_EFFECT_SCENE.instantiate() as Node2D + effect.global_position = at_position + get_parent().add_child(effect) + effect.call("configure", false, effect_color) + +func _update_shield_visual() -> void: + if is_instance_valid(_shield_visual): + _shield_visual.call("set_shield_values", shields, max_shields) + +func _destroy_ship() -> void: + _is_destroyed = true + velocity = Vector2.ZERO + collision_layer = 0 + collision_mask = 0 + var tween := create_tween() + tween.tween_property(self, "modulate:a", 0.0, 1.1) + _restart_level_after_destruction() + +func _restart_level_after_destruction() -> void: + await get_tree().create_timer(1.1).timeout + if is_inside_tree(): + get_tree().reload_current_scene() + func _physics_process(delta: float) -> void: + if _is_destroyed: + return + _contact_damage_timer = maxf(0.0, _contact_damage_timer - delta) energy = minf(max_energy, energy + energy_regeneration * delta) + if shield_regeneration > 0.0 and shields < max_shields: + var previous_shields := shields + shields = minf(max_shields, shields + shield_regeneration * delta) + if shields != previous_shields: + _update_shield_visual() var turn_input := Input.get_axis("ship_turn_left", "ship_turn_right") if not is_zero_approx(turn_input): angular_velocity = move_toward( @@ -110,4 +178,20 @@ func _physics_process(delta: float) -> void: ): velocity = velocity.move_toward(Vector2.ZERO, space_drag * delta) + _clamp_velocity_to_max_speed() move_and_slide() + _check_enemy_collisions() + _clamp_velocity_to_max_speed() + +func _clamp_velocity_to_max_speed() -> void: + var speed_squared := velocity.length_squared() + var max_speed_squared := max_speed * max_speed + if speed_squared > max_speed_squared: + velocity = velocity.normalized() * max_speed + +func _check_enemy_collisions() -> void: + for collision_index in get_slide_collision_count(): + var collision := get_slide_collision(collision_index) + var collider := collision.get_collider() + if collider is Node and collider.is_in_group("enemies"): + register_enemy_collision(collider.global_position) diff --git a/scripts/game/weapon_audio.gd b/scripts/game/weapon_audio.gd new file mode 100644 index 0000000..55d7e4f --- /dev/null +++ b/scripts/game/weapon_audio.gd @@ -0,0 +1,34 @@ +extends RefCounted +class_name WeaponAudio + +const SOUND_PATHS := { + ItemDefinition.WeaponKind.PLASMA: "res://assets/sounds/effects/plasma.mp3", + ItemDefinition.WeaponKind.MACHINE_GUN: "res://assets/sounds/effects/machine_gun.mp3", + ItemDefinition.WeaponKind.LASER: "res://assets/sounds/effects/laser.mp3", + ItemDefinition.WeaponKind.MISSILE: "res://assets/sounds/effects/rocket.mp3", +} + +static var _streams: Dictionary = {} + +static func play(parent: Node, source_position: Vector2, weapon_kind: int, volume_db: float = -6.0) -> void: + if not is_instance_valid(parent): + return + + if not SOUND_PATHS.has(weapon_kind): + return + if not _streams.has(weapon_kind): + var sound_path: String = SOUND_PATHS[weapon_kind] + _streams[weapon_kind] = AudioStreamMP3.load_from_buffer(FileAccess.get_file_as_bytes(sound_path)) + var stream := _streams[weapon_kind] as AudioStreamMP3 + if stream == null: + return + + var player := AudioStreamPlayer2D.new() + player.stream = stream + player.volume_db = volume_db + player.max_distance = 1500.0 + player.attenuation = 1.0 + parent.add_child(player) + player.global_position = source_position + player.finished.connect(player.queue_free) + player.play() diff --git a/scripts/game/weapon_audio.gd.uid b/scripts/game/weapon_audio.gd.uid new file mode 100644 index 0000000..51988ab --- /dev/null +++ b/scripts/game/weapon_audio.gd.uid @@ -0,0 +1 @@ +uid://dtkvkp37upbru diff --git a/scripts/game/weapon_controller.gd b/scripts/game/weapon_controller.gd index b824ccc..8eb90de 100644 --- a/scripts/game/weapon_controller.gd +++ b/scripts/game/weapon_controller.gd @@ -1,7 +1,9 @@ extends Node const PROJECTILE_SCENE := preload("res://scenes/game/weapon_projectile.tscn") -const RAY_COLLISION_MASK := 5 # World geometry and enemies on physics layer 3. +const IMPACT_EFFECT_SCENE := preload("res://scenes/game/impact_effect.tscn") +const WEAPON_AUDIO_SCRIPT := preload("res://scripts/game/weapon_audio.gd") +const RAY_COLLISION_MASK := 13 # World, enemies, and the weapon test target. @onready var ship: CharacterBody2D = get_parent() @onready var inventory: ShipInventory = ship.get_node("ShipInventory") @@ -104,6 +106,7 @@ func _fire_projectile(definition: ItemDefinition, projectile_damage: float) -> v definition.weapon_range ) ship.get_parent().add_child(projectile) + WEAPON_AUDIO_SCRIPT.play(ship.get_parent(), ship.global_position, definition.weapon_kind) func _fire_laser(slot_index: int, definition: ItemDefinition, beam_damage: float) -> void: var line := _laser_lines[slot_index] @@ -127,8 +130,10 @@ func _fire_laser(slot_index: int, definition: ItemDefinition, beam_damage: float if not _consume_energy(definition.energy_cost): line.visible = false return + WEAPON_AUDIO_SCRIPT.play(ship.get_parent(), ship.global_position, ItemDefinition.WeaponKind.LASER) if not result.is_empty(): _apply_damage(result.get("collider"), beam_damage) + _spawn_laser_impact(endpoint) _laser_pulse_timers[slot_index] = definition.laser_pulse_duration _shot_timers[slot_index] = definition.fire_interval @@ -146,3 +151,9 @@ func _consume_energy(amount: float) -> bool: func _apply_damage(target: Variant, damage: float) -> void: if target is Node and target.has_method("take_damage"): target.call("take_damage", damage) + +func _spawn_laser_impact(at_position: Vector2) -> void: + var effect := IMPACT_EFFECT_SCENE.instantiate() as Node2D + effect.global_position = at_position + ship.get_parent().add_child(effect) + effect.call("configure", false, Color(0.38, 0.9, 1.0)) diff --git a/scripts/game/weapon_projectile.gd b/scripts/game/weapon_projectile.gd index 4640c72..c37780f 100644 --- a/scripts/game/weapon_projectile.gd +++ b/scripts/game/weapon_projectile.gd @@ -1,5 +1,7 @@ extends Area2D +const IMPACT_EFFECT_SCENE := preload("res://scenes/game/impact_effect.tscn") + var direction := Vector2.UP var projectile_speed := 600.0 var damage := 1.0 @@ -7,6 +9,7 @@ var max_range := 800.0 var weapon_kind := ItemDefinition.WeaponKind.PLASMA var _distance_travelled := 0.0 var _already_hit: Dictionary = {} +var _impact_handled := false func _ready() -> void: body_entered.connect(_on_body_entered) @@ -67,12 +70,24 @@ func _on_area_entered(area: Area2D) -> void: _hit_target(area) func _hit_target(target: Node) -> void: + if _impact_handled: + return + _impact_handled = true + var is_explosion := weapon_kind == ItemDefinition.WeaponKind.MISSILE + _spawn_impact_effect(is_explosion) if weapon_kind == ItemDefinition.WeaponKind.MISSILE: _explode_at_target(target) else: _apply_damage_once(target) queue_free() +func _spawn_impact_effect(is_explosion: bool) -> void: + var effect := IMPACT_EFFECT_SCENE.instantiate() as Node2D + effect.global_position = global_position + get_parent().add_child(effect) + var effect_color := Color(1.0, 0.48, 0.22) if is_explosion else Color(1.0, 0.78, 0.38) + effect.call("configure", is_explosion, effect_color) + func _explode_at_target(impact_target: Node) -> void: _apply_damage_once(impact_target) var explosion_shape := CircleShape2D.new() diff --git a/scripts/items/ship_inventory.gd b/scripts/items/ship_inventory.gd index 2797f17..6c22110 100644 --- a/scripts/items/ship_inventory.gd +++ b/scripts/items/ship_inventory.gd @@ -84,7 +84,7 @@ func _recalculate_ship_stats() -> void: for item in weapon_slots + module_slots: if item == null or item.definition == null: continue - for stat_key in ["max_hull", "max_shields", "max_energy", "max_speed", "energy_regeneration"]: + for stat_key in ["max_hull", "max_shields", "max_energy", "max_speed", "energy_regeneration", "shield_regeneration"]: bonuses[stat_key] = float(bonuses.get(stat_key, 0.0)) + item.get_stat_total(stat_key) ship.call("apply_equipment_bonuses", bonuses) @@ -98,6 +98,8 @@ func _add_starter_items() -> void: "res://resources/items/hull_plating.tres", "res://resources/items/compact_generator.tres", "res://resources/items/engine_extension.tres", + "res://resources/items/tuned_thrusters.tres", + "res://resources/items/shield_recharger.tres", ] var cargo_index := 0 var weapon_index := 0