Dodanie wrogów i dzwieków broni

This commit is contained in:
Tomasz Boruc 2026-10-09 20:04:16 +02:00
parent c08e0482e7
commit 53ac17d6b0
61 changed files with 1166 additions and 31 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

@ -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

Binary file not shown.

View File

@ -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

Binary file not shown.

View File

@ -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

Binary file not shown.

View File

@ -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

Binary file not shown.

View File

@ -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

Binary file not shown.

View File

@ -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

Binary file not shown.

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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")

View File

@ -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")

View File

@ -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" uid="uid://d3behbql2g2b7" 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://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="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_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/ui/ship_inventory_panel.tscn" id="6_inventory"]
[ext_resource type="PackedScene" path="res://scenes/game/weapon_test_target.tscn" id="7_target"] [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"] [sub_resource type="RectangleShape2D" id="RightWall"]
size = Vector2(40, 3600) size = Vector2(40, 3600)
[node name="Game" type="Node2D"] [node name="Game" type="Node2D" unique_id=1630707678]
script = ExtResource("1_game") script = ExtResource("1_game")
[node name="SpaceBackground" type="Node2D" parent="."] [node name="SpaceBackground" type="Node2D" parent="." unique_id=300719476]
z_index = -20 z_index = -20
script = ExtResource("2_background") script = ExtResource("2_background")
[node name="WorldBounds" type="StaticBody2D" parent="."] [node name="WorldBounds" type="StaticBody2D" parent="." unique_id=1631186063]
collision_layer = 1
collision_mask = 0 collision_mask = 0
[node name="TopWall" type="CollisionShape2D" parent="WorldBounds"] [node name="TopWall" type="CollisionShape2D" parent="WorldBounds" unique_id=408485617]
position = Vector2(0, -1780) position = Vector2(0, -1780)
shape = SubResource("TopWall") shape = SubResource("TopWall")
[node name="BottomWall" type="CollisionShape2D" parent="WorldBounds"] [node name="BottomWall" type="CollisionShape2D" parent="WorldBounds" unique_id=264280939]
position = Vector2(0, 1780) position = Vector2(0, 1780)
shape = SubResource("BottomWall") shape = SubResource("BottomWall")
[node name="LeftWall" type="CollisionShape2D" parent="WorldBounds"] [node name="LeftWall" type="CollisionShape2D" parent="WorldBounds" unique_id=1859447770]
position = Vector2(-2580, 0) position = Vector2(-2580, 0)
shape = SubResource("LeftWall") shape = SubResource("LeftWall")
[node name="RightWall" type="CollisionShape2D" parent="WorldBounds"] [node name="RightWall" type="CollisionShape2D" parent="WorldBounds" unique_id=1866196697]
position = Vector2(2580, 0) position = Vector2(2580, 0)
shape = SubResource("RightWall") 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) position = Vector2(240, 0)
[node name="HUD" type="CanvasLayer" parent="."] [node name="HUD" type="CanvasLayer" parent="." unique_id=733012261]
script = ExtResource("4_hud") script = ExtResource("4_hud")
[node name="HUDRoot" type="Control" parent="HUD"] [node name="HUDRoot" type="Control" parent="HUD" unique_id=539413585]
layout_mode = 3 layout_mode = 3
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0
@ -64,24 +63,51 @@ grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 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_left = 18.0
offset_top = 16.0 offset_top = 16.0
offset_right = 110.0 offset_right = 110.0
offset_bottom = 42.0 offset_bottom = 42.0
flat = true
theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1) theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1)
text = "DEBUG [−]" 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_left = 22.0
offset_top = 48.0 offset_top = 48.0
offset_right = 295.0 offset_right = 295.0
offset_bottom = 420.0 offset_bottom = 420.0
theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1) theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1)
theme_override_font_sizes/font_size = 11 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

View File

@ -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")

View File

@ -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/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/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/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"] [sub_resource type="CircleShape2D" id="ShipCollision"]
radius = 18.0 radius = 18.0
[node name="PlayerShip" type="CharacterBody2D"] [node name="PlayerShip" type="CharacterBody2D"]
collision_layer = 2 collision_layer = 2
collision_mask = 1 collision_mask = 5
script = ExtResource("1_controller") script = ExtResource("1_controller")
[node name="Sprite2D" type="Sprite2D" parent="."] [node name="Sprite2D" type="Sprite2D" parent="."]
texture_filter = 1 texture_filter = 1
[node name="ShieldVisual" type="Node2D" parent="."]
z_index = 2
script = ExtResource("4_shield")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("ShipCollision") shape = SubResource("ShipCollision")

View File

@ -7,7 +7,7 @@ radius = 6.0
[node name="WeaponProjectile" type="Area2D"] [node name="WeaponProjectile" type="Area2D"]
collision_layer = 0 collision_layer = 0
collision_mask = 5 collision_mask = 13
monitoring = true monitoring = true
monitorable = false monitorable = false
script = ExtResource("1_projectile") script = ExtResource("1_projectile")

View File

@ -7,7 +7,7 @@
radius = 27.0 radius = 27.0
[node name="WeaponTestTarget" type="StaticBody2D"] [node name="WeaponTestTarget" type="StaticBody2D"]
collision_layer = 4 collision_layer = 8
collision_mask = 0 collision_mask = 0
script = ExtResource("1_script") script = ExtResource("1_script")

View File

@ -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()

View File

@ -0,0 +1 @@
uid://c47empdk2n8j4

View File

@ -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

View File

@ -0,0 +1 @@
uid://dlnki63o425ys

View File

@ -30,6 +30,7 @@ KADŁUB: %d / %d
TARCZE: %d / %d TARCZE: %d / %d
ENERGIA: %d / %d ENERGIA: %d / %d
ENERGIA REGEN: %.1f /s ENERGIA REGEN: %.1f /s
TARCZE REGEN: %.1f /s
RUCH RUCH
PRĘDKOŚĆ: %.1f px/s 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("shields"))), roundi(float(player.get("max_shields"))),
roundi(float(player.get("energy"))), roundi(float(player.get("max_energy"))), roundi(float(player.get("energy"))), roundi(float(player.get("max_energy"))),
float(player.get("energy_regeneration")), float(player.get("energy_regeneration")),
float(player.get("shield_regeneration")),
ship_velocity.length(), ship_velocity.x, ship_velocity.y, ship_velocity.length(), ship_velocity.x, ship_velocity.y,
ship_position.x, ship_position.y, rad_to_deg(player.rotation), angular_speed, ship_position.x, ship_position.y, rad_to_deg(player.rotation), angular_speed,
] ]

View File

@ -1,6 +1,23 @@
extends Node2D extends Node2D
const WORLD_SIZE := Vector2(5200.0, 3600.0) 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 @onready var player: CharacterBody2D = $PlayerShip
@ -12,3 +29,31 @@ func _ready() -> void:
camera.limit_right = int(WORLD_SIZE.x * 0.5) camera.limit_right = int(WORLD_SIZE.x * 0.5)
camera.limit_top = int(-WORLD_SIZE.y * 0.5) camera.limit_top = int(-WORLD_SIZE.y * 0.5)
camera.limit_bottom = 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)])

View File

@ -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))

View File

@ -0,0 +1 @@
uid://72jgwxdutqml

View File

@ -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
)

View File

@ -0,0 +1 @@
uid://w0t7eo1lt1b8

View File

@ -1,11 +1,12 @@
extends CharacterBody2D extends CharacterBody2D
const DEFAULT_SHIP_TEXTURE := "res://assets/Ships/Spaceship_0.png" 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 reverse_max_speed := 210.0
@export var max_strafe_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 brake_acceleration := 540.0
@export var space_drag := 24.0 @export var space_drag := 24.0
@export var max_turn_speed := 2.8 @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_hull := 100.0
@export var base_max_shields := 100.0 @export var base_max_shields := 100.0
@export var base_max_energy := 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_energy_regeneration := 12.0
@export var base_shield_regeneration := 0.0
@export var max_hull := 100.0 @export var max_hull := 100.0
@export var max_shields := 100.0 @export var max_shields := 100.0
@export var max_energy := 100.0 @export var max_energy := 100.0
@ -24,9 +26,13 @@ var hull := 100.0
var shields := 100.0 var shields := 100.0
var energy := 100.0 var energy := 100.0
var energy_regeneration := 12.0 var energy_regeneration := 12.0
var shield_regeneration := 0.0
var angular_velocity := 0.0 var angular_velocity := 0.0
var _sprite: Sprite2D 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: func apply_equipment_bonuses(bonuses: Dictionary) -> void:
max_hull = base_max_hull + float(bonuses.get("max_hull", 0.0)) 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_energy = base_max_energy + float(bonuses.get("max_energy", 0.0))
max_speed = base_max_speed + float(bonuses.get("max_speed", 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)) 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 reverse_max_speed = max_speed * 0.5
max_strafe_speed = max_speed * 0.5 max_strafe_speed = max_speed * 0.5
hull = minf(hull, max_hull) hull = minf(hull, max_hull)
shields = minf(shields, max_shields) shields = minf(shields, max_shields)
energy = minf(energy, max_energy) energy = minf(energy, max_energy)
_update_shield_visual()
func _ready() -> void: func _ready() -> void:
_ensure_input_action(&"ship_thrust", KEY_W) _ensure_input_action(&"ship_thrust", KEY_W)
@ -58,6 +66,7 @@ func _ready() -> void:
_sprite.texture = ship_texture _sprite.texture = ship_texture
var largest_dimension := maxf(ship_texture.get_width(), ship_texture.get_height()) var largest_dimension := maxf(ship_texture.get_width(), ship_texture.get_height())
_sprite.scale = Vector2.ONE * (64.0 / largest_dimension) _sprite.scale = Vector2.ONE * (64.0 / largest_dimension)
_update_shield_visual()
func _ensure_input_action(action_name: StringName, physical_key: Key) -> void: func _ensure_input_action(action_name: StringName, physical_key: Key) -> void:
if not InputMap.has_action(action_name): 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): if not InputMap.action_has_event(action_name, event):
InputMap.action_add_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: 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) 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") var turn_input := Input.get_axis("ship_turn_left", "ship_turn_right")
if not is_zero_approx(turn_input): if not is_zero_approx(turn_input):
angular_velocity = move_toward( angular_velocity = move_toward(
@ -110,4 +178,20 @@ func _physics_process(delta: float) -> void:
): ):
velocity = velocity.move_toward(Vector2.ZERO, space_drag * delta) velocity = velocity.move_toward(Vector2.ZERO, space_drag * delta)
_clamp_velocity_to_max_speed()
move_and_slide() 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)

View File

@ -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()

View File

@ -0,0 +1 @@
uid://dtkvkp37upbru

View File

@ -1,7 +1,9 @@
extends Node extends Node
const PROJECTILE_SCENE := preload("res://scenes/game/weapon_projectile.tscn") 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 ship: CharacterBody2D = get_parent()
@onready var inventory: ShipInventory = ship.get_node("ShipInventory") @onready var inventory: ShipInventory = ship.get_node("ShipInventory")
@ -104,6 +106,7 @@ func _fire_projectile(definition: ItemDefinition, projectile_damage: float) -> v
definition.weapon_range definition.weapon_range
) )
ship.get_parent().add_child(projectile) 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: func _fire_laser(slot_index: int, definition: ItemDefinition, beam_damage: float) -> void:
var line := _laser_lines[slot_index] 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): if not _consume_energy(definition.energy_cost):
line.visible = false line.visible = false
return return
WEAPON_AUDIO_SCRIPT.play(ship.get_parent(), ship.global_position, ItemDefinition.WeaponKind.LASER)
if not result.is_empty(): if not result.is_empty():
_apply_damage(result.get("collider"), beam_damage) _apply_damage(result.get("collider"), beam_damage)
_spawn_laser_impact(endpoint)
_laser_pulse_timers[slot_index] = definition.laser_pulse_duration _laser_pulse_timers[slot_index] = definition.laser_pulse_duration
_shot_timers[slot_index] = definition.fire_interval _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: func _apply_damage(target: Variant, damage: float) -> void:
if target is Node and target.has_method("take_damage"): if target is Node and target.has_method("take_damage"):
target.call("take_damage", 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))

View File

@ -1,5 +1,7 @@
extends Area2D extends Area2D
const IMPACT_EFFECT_SCENE := preload("res://scenes/game/impact_effect.tscn")
var direction := Vector2.UP var direction := Vector2.UP
var projectile_speed := 600.0 var projectile_speed := 600.0
var damage := 1.0 var damage := 1.0
@ -7,6 +9,7 @@ var max_range := 800.0
var weapon_kind := ItemDefinition.WeaponKind.PLASMA var weapon_kind := ItemDefinition.WeaponKind.PLASMA
var _distance_travelled := 0.0 var _distance_travelled := 0.0
var _already_hit: Dictionary = {} var _already_hit: Dictionary = {}
var _impact_handled := false
func _ready() -> void: func _ready() -> void:
body_entered.connect(_on_body_entered) body_entered.connect(_on_body_entered)
@ -67,12 +70,24 @@ func _on_area_entered(area: Area2D) -> void:
_hit_target(area) _hit_target(area)
func _hit_target(target: Node) -> void: 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: if weapon_kind == ItemDefinition.WeaponKind.MISSILE:
_explode_at_target(target) _explode_at_target(target)
else: else:
_apply_damage_once(target) _apply_damage_once(target)
queue_free() 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: func _explode_at_target(impact_target: Node) -> void:
_apply_damage_once(impact_target) _apply_damage_once(impact_target)
var explosion_shape := CircleShape2D.new() var explosion_shape := CircleShape2D.new()

View File

@ -84,7 +84,7 @@ func _recalculate_ship_stats() -> void:
for item in weapon_slots + module_slots: for item in weapon_slots + module_slots:
if item == null or item.definition == null: if item == null or item.definition == null:
continue 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) bonuses[stat_key] = float(bonuses.get(stat_key, 0.0)) + item.get_stat_total(stat_key)
ship.call("apply_equipment_bonuses", bonuses) ship.call("apply_equipment_bonuses", bonuses)
@ -98,6 +98,8 @@ func _add_starter_items() -> void:
"res://resources/items/hull_plating.tres", "res://resources/items/hull_plating.tres",
"res://resources/items/compact_generator.tres", "res://resources/items/compact_generator.tres",
"res://resources/items/engine_extension.tres", "res://resources/items/engine_extension.tres",
"res://resources/items/tuned_thrusters.tres",
"res://resources/items/shield_recharger.tres",
] ]
var cargo_index := 0 var cargo_index := 0
var weapon_index := 0 var weapon_index := 0