From acc7901c2acad5a745af0b91425a49cb50999022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?sijcdu=E7=9A=84=E6=B8=B8=E6=88=8F?= Date: Wed, 7 Oct 2026 22:51:56 +0800 Subject: [PATCH] Add level 3: bullet rain from the sky, and ropes that only block bullets The tileset gained a second physics layer (collision_layer 2) and the rope tile (11,4) now carries its 18x6 polygon on that layer instead of layer 0, so it is invisible to anything that does not ask for layer 2. The player's mask stays 1 and the key copies it, so both fall straight through ropes; the bullet probe mask went from 1 to 3 so falling bullets are stopped by them. New bullet_rain prefab drops bullets at random x across the level on a jittered timer, sparse by default (1.0s +- 0.6s), and level 3 places one spanning the whole width. Level 3 has no lasers, and level 2's clear screen now leads into it. --- .../game/tilesets/kenney_terrain_tileset.tres | 2 + scenes/level2.tscn | 1 + scenes/level3.tscn | 255 ++++++++++++++++++ scenes/prefabs/enemies/bullet.tscn | 2 +- scenes/prefabs/enemies/bullet_rain.tscn | 6 + scripts/bullet_rain.gd | 64 +++++ scripts/bullet_rain.gd.uid | 1 + 7 files changed, 330 insertions(+), 1 deletion(-) create mode 100644 scenes/level3.tscn create mode 100644 scenes/prefabs/enemies/bullet_rain.tscn create mode 100644 scripts/bullet_rain.gd create mode 100644 scripts/bullet_rain.gd.uid diff --git a/assets/game/tilesets/kenney_terrain_tileset.tres b/assets/game/tilesets/kenney_terrain_tileset.tres index 29e44c6..86788ff 100644 --- a/assets/game/tilesets/kenney_terrain_tileset.tres +++ b/assets/game/tilesets/kenney_terrain_tileset.tres @@ -132,6 +132,7 @@ use_texture_padding = false 9:4/0 = 0 10:4/0 = 0 11:4/0 = 0 +11:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-9, -3, 9, -3, 9, 3, -9, 3) 12:4/0 = 0 13:4/0 = 0 14:4/0 = 0 @@ -264,4 +265,5 @@ use_texture_padding = false [resource] tile_size = Vector2i(18, 18) physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 sources/0 = SubResource("TileSetAtlasSource_afvjv") diff --git a/scenes/level2.tscn b/scenes/level2.tscn index bb2b14b..1222b26 100644 --- a/scenes/level2.tscn +++ b/scenes/level2.tscn @@ -28,6 +28,7 @@ [node name="DeathScreen" parent="." unique_id=1952687359 instance=ExtResource("2_cqal4")] [node name="LevelClear" parent="." unique_id=1589634220 instance=ExtResource("3_o3sye")] +next_level_scene = "res://scenes/level3.tscn" [node name="Level" type="Node2D" parent="." unique_id=1678372922] diff --git a/scenes/level3.tscn b/scenes/level3.tscn new file mode 100644 index 0000000..03bcd40 --- /dev/null +++ b/scenes/level3.tscn @@ -0,0 +1,255 @@ +[gd_scene format=4 uid="uid://csvqda2jbvh2o"] + +[ext_resource type="PackedScene" path="res://scenes/hud.tscn" id="1_07lh1"] +[ext_resource type="PackedScene" path="res://scenes/death_screen.tscn" id="2_6uuvf"] +[ext_resource type="PackedScene" path="res://scenes/level_clear.tscn" id="3_x008a"] +[ext_resource type="Texture2D" uid="uid://djmk0srfgyafe" path="res://assets/game/backgrounds/cloud_left.png" id="4_atr84"] +[ext_resource type="Texture2D" uid="uid://dptqmtay4plwp" path="res://assets/game/backgrounds/cloud_trees.png" id="5_qyu38"] +[ext_resource type="Texture2D" uid="uid://dys7320ghojh6" path="res://assets/game/backgrounds/cloud_hills.png" id="6_8vbrh"] +[ext_resource type="Texture2D" uid="uid://1b8hp0rm864l" path="res://assets/game/backgrounds/cloud_right.png" id="7_d5gix"] +[ext_resource type="Script" uid="uid://dxwa7fxghp3a2" path="res://scripts/hidden_passages.gd" id="8_7hs6g"] +[ext_resource type="TileSet" uid="uid://dkowcf1ljh41j" path="res://assets/game/tilesets/kenney_terrain_tileset.tres" id="9_yeq8b"] +[ext_resource type="PackedScene" uid="uid://c1u8k6ny02t4y" path="res://scenes/player.tscn" id="10_invaa"] +[ext_resource type="PackedScene" path="res://scenes/prefabs/hazards/spikes_double.tscn" id="11_88b2t"] +[ext_resource type="PackedScene" path="res://scenes/prefabs/hazards/spikes_grey.tscn" id="12_0ydwj"] +[ext_resource type="PackedScene" path="res://scenes/prefabs/interactables/spring_red.tscn" id="15_usk20"] +[ext_resource type="PackedScene" path="res://scenes/prefabs/interactables/door.tscn" id="16_y8u0o"] +[ext_resource type="PackedScene" path="res://scenes/prefabs/collectibles/coin_gold_round.tscn" id="17_16ffm"] +[ext_resource type="PackedScene" path="res://scenes/prefabs/collectibles/key_gold.tscn" id="18_kvrlk"] +[ext_resource type="PackedScene" path="res://scenes/prefabs/collectibles/diamond.tscn" id="19_85fmh"] +[ext_resource type="PackedScene" path="res://scenes/prefabs/enemies/bullet_rain.tscn" id="20_rain"] + +[node name="Main" type="Node2D" unique_id=2061129075] + +[node name="HUD" parent="." unique_id=215179112 instance=ExtResource("1_07lh1")] + +[node name="DeathScreen" parent="." unique_id=1952687359 instance=ExtResource("2_6uuvf")] + +[node name="LevelClear" parent="." unique_id=1589634220 instance=ExtResource("3_x008a")] + +[node name="Level" type="Node2D" parent="." unique_id=1678372922] + +[node name="Background" type="Node2D" parent="Level" unique_id=702011751] + +[node name="SkyColor" type="Polygon2D" parent="Level/Background" unique_id=22763597] +z_index = -30 +color = Color(0.8509804, 0.9411765, 0.9372549, 1) +polygon = PackedVector2Array(0, 0, 468, 0, 468, 130.0972, 468, 270, 0, 270) + +[node name="CloudBand_01" type="Sprite2D" parent="Level/Background" unique_id=589633713] +z_index = -20 +texture_filter = 1 +position = Vector2(12, 150) +texture = ExtResource("4_atr84") + +[node name="CloudBand_02" type="Sprite2D" parent="Level/Background" unique_id=225493882] +z_index = -20 +texture_filter = 1 +position = Vector2(36, 150) +texture = ExtResource("5_qyu38") + +[node name="CloudBand_03" type="Sprite2D" parent="Level/Background" unique_id=646834403] +z_index = -20 +texture_filter = 1 +position = Vector2(60, 150) +texture = ExtResource("6_8vbrh") + +[node name="CloudBand_04" type="Sprite2D" parent="Level/Background" unique_id=1012727532] +z_index = -20 +texture_filter = 1 +position = Vector2(84, 150) +texture = ExtResource("7_d5gix") + +[node name="CloudBand_05" type="Sprite2D" parent="Level/Background" unique_id=1685434781] +z_index = -20 +texture_filter = 1 +position = Vector2(108, 150) +texture = ExtResource("4_atr84") + +[node name="CloudBand_06" type="Sprite2D" parent="Level/Background" unique_id=1425986424] +z_index = -20 +texture_filter = 1 +position = Vector2(132, 150) +texture = ExtResource("5_qyu38") + +[node name="CloudBand_07" type="Sprite2D" parent="Level/Background" unique_id=1333305041] +z_index = -20 +texture_filter = 1 +position = Vector2(156, 150) +texture = ExtResource("6_8vbrh") + +[node name="CloudBand_08" type="Sprite2D" parent="Level/Background" unique_id=55356860] +z_index = -20 +texture_filter = 1 +position = Vector2(180, 150) +texture = ExtResource("7_d5gix") + +[node name="CloudBand_09" type="Sprite2D" parent="Level/Background" unique_id=379152848] +z_index = -20 +texture_filter = 1 +position = Vector2(204, 150) +texture = ExtResource("4_atr84") + +[node name="CloudBand_10" type="Sprite2D" parent="Level/Background" unique_id=325990577] +z_index = -20 +texture_filter = 1 +position = Vector2(228, 150) +texture = ExtResource("5_qyu38") + +[node name="CloudBand_11" type="Sprite2D" parent="Level/Background" unique_id=1505438200] +z_index = -20 +texture_filter = 1 +position = Vector2(252, 150) +texture = ExtResource("6_8vbrh") + +[node name="CloudBand_12" type="Sprite2D" parent="Level/Background" unique_id=190709163] +z_index = -20 +texture_filter = 1 +position = Vector2(276, 150) +texture = ExtResource("7_d5gix") + +[node name="CloudBand_13" type="Sprite2D" parent="Level/Background" unique_id=349156114] +z_index = -20 +texture_filter = 1 +position = Vector2(300, 150) +texture = ExtResource("4_atr84") + +[node name="CloudBand_14" type="Sprite2D" parent="Level/Background" unique_id=1838903106] +z_index = -20 +texture_filter = 1 +position = Vector2(324, 150) +texture = ExtResource("5_qyu38") + +[node name="CloudBand_15" type="Sprite2D" parent="Level/Background" unique_id=169474301] +z_index = -20 +texture_filter = 1 +position = Vector2(348, 150) +texture = ExtResource("6_8vbrh") + +[node name="CloudBand_16" type="Sprite2D" parent="Level/Background" unique_id=156763289] +z_index = -20 +texture_filter = 1 +position = Vector2(372, 150) +texture = ExtResource("7_d5gix") + +[node name="CloudBand_17" type="Sprite2D" parent="Level/Background" unique_id=161240142] +z_index = -20 +texture_filter = 1 +position = Vector2(396, 150) +texture = ExtResource("4_atr84") + +[node name="CloudBand_18" type="Sprite2D" parent="Level/Background" unique_id=1823235224] +z_index = -20 +texture_filter = 1 +position = Vector2(420, 150) +texture = ExtResource("5_qyu38") + +[node name="CloudBand_19" type="Sprite2D" parent="Level/Background" unique_id=2092676382] +z_index = -20 +texture_filter = 1 +position = Vector2(444, 150) +texture = ExtResource("6_8vbrh") + +[node name="CloudBand_20" type="Sprite2D" parent="Level/Background" unique_id=124375716] +z_index = -20 +texture_filter = 1 +position = Vector2(468, 150) +texture = ExtResource("7_d5gix") + +[node name="TerrainTileMaps" type="Node2D" parent="Level" unique_id=652327492] +script = ExtResource("8_7hs6g") + +[node name="TerrainBase" type="TileMapLayer" parent="Level/TerrainTileMaps" unique_id=91115499] +position = Vector2(9, 9) +tile_map_data = PackedByteArray("AAD//wkAAAACAAEAAAD//woAAAAEAAAAAAABAA0AAAACAAYAAAACAA0AAAAEAAUAAAACAA4AAAAEAAUAAAADAA0AAAACAAYAAAABAAoAAAACAAYAAAAAAAoAAAAEAAUAAAAAAAkAAAACAAEAAAACAAsAAAAEAAUAAAAAAA0AAAAEAAUAAAD//w0AAAAEAAEAAAAFAA0AAAAEAAUAAAAEAA4AAAAEAAUAAAADAA4AAAACAAYAAAAAAA4AAAACAAYAAAABAA4AAAACAAYAAAAHAAwAAAACAAEAAAALAAwAAAACAAEAAAAKAA0AAAAEAAUAAAAIAA4AAAAEAAUAAAALAA4AAAAEAAUAAAAMAA4AAAACAAYAAAANAA0AAAACAAYAAAAOAA0AAAAEAAUAAAAPAA0AAAAEAAUAAAAQAA0AAAAEAAUAAAARAAwAAAACAAUAAAATAAwAAAACAAUAAAAVAAsAAAACAAYAAAAWAAsAAAAEAAUAAAAUAAwAAAACAAYAAAAQAAwAAAACAAMAAAAKAA4AAAAEAAUAAAAJAA4AAAAEAAUAAAAFAA4AAAACAAYAAAAGAA4AAAAEAAUAAAAHAA4AAAAEAAUAAAANAA4AAAACAAYAAAAOAA4AAAACAAYAAAAPAA4AAAACAAYAAAASAA0AAAACAAYAAAATAA0AAAAEAAUAAAAUAA0AAAACAAYAAAAVAA0AAAACAAYAAAAWAA0AAAACAAYAAAAXAA0AAAAEAAUAAAALAA0AAAAEAAUAAAAMAA0AAAACAAYAAAAPAAwAAAACAAMAAAAXAAsAAAAEAAUAAAAYAAsAAAAEAAUAAAAZAAsAAAACAAYAAAAZAAwAAAACAAYAAAAYAAwAAAAEAAUAAAAZAA4AAAAEAAUAAAAXAA4AAAAEAAUAAAAWAA4AAAAEAAUAAAAVAA4AAAACAAYAAAAUAA4AAAACAAYAAAATAA4AAAACAAYAAAASAA4AAAACAAYAAAAYAA4AAAACAAYAAAARAA4AAAACAAYAAAAEAA0AAAACAAYAAAD//w4AAAAEAAEAAAABAAkAAAACAAEAAAAIAAwAAAACAAEAAAAOAAwAAAACAAMAAAANAAwAAAACAAMAAAAMAAwAAAACAAMAAAAUAAkAAAABAAUAAAAUAAoAAAABAAYAAAAPAAgAAAASAAQAABAWAAoAAAACAAYAAAAXAAcAAAACAAUAAAAYAAkAAAACAAYAAAAYAAoAAAACAAYAAAAXAAoAAAACAAYAAAAXAAkAAAACAAYAAAAZAAkAAAACAAYAAAAZAAoAAAACAAYAAAAQAA4AAAAEAAUAAAARAA0AAAACAAYAAAASAAwAAAACAAUAAAAVAAoAAAACAAYAAAAWAAkAAAACAAUAAAAXAAgAAAAEAAEAAAAUAAsAAAAFAAEAAAAVAAwAAAAEAAUAAAAWAAwAAAACAAYAAAAXAAwAAAAEAAUAAAAYAA0AAAACAAYAAAAZAA0AAAAEAAUAAAAAAAwAAAACAAYAAAACAAwAAAACAAYAAAADAAwAAAAEAAUAAAAEAAwAAAACAAYAAAAFAAwAAAAEAAUAAAAGAAwAAAAEAAUAAAAGAA0AAAACAAYAAAAHAA0AAAACAAYAAAAIAA0AAAAEAAUAAAAJAA0AAAACAAYAAAAKAAwAAAACAAEAAAD//wwAAAAFAAAAAAD//wsAAAAEAAAAAAAAAAsAAAAEAAUAAAABAAsAAAACAAYAAAABAAwAAAACAAYAAAAYAAcAAAACAAUAAAAZAAcAAAADAAUAAAAYAAgAAAACAAYAAAAZAAgAAAACAAYAAAAVAAkAAAACAAUAAAADAAsAAAACAAYAAAAEAAsAAAACAAEAAAAFAAsAAAACAAEAAAAGAAsAAAACAAEAAAACAAoAAAACAAEAAAADAAoAAAACAAEAAAARAAcAAAAOAAcAAAASAAcAAAAOAAcAAAAQAAcAAAAOAAcAAAAPAAcAAAANAAcAAAAIAAYAAAANAAcAAAATAAcAAAAPAAcAAAAMAAYAAAAPAAcAAAALAAYAAAAOAAcAAAAKAAYAAAAOAAcAAAABAAgAAAARAAYAAAABAAcAAAAQAAUAAAABAAYAAAARAAUAAAABAAUAAAAQAAUAAAAAAAQAAAASAAIAAAABAAQAAAASAAIAAAACAAQAAAASAAIAAAD//wQAAAARAAIAAAAEAAQAAAATAAIAAAADAAQAAAASAAIAAAAAAAMAAAASAAEAAAABAAMAAAASAAEAAAACAAMAAAASAAEAAAADAAMAAAASAAAAAAAEAAMAAAATAAAAAAD//wMAAAARAAEAAAD//wIAAAARAAEAAAD//wEAAAARAAEAAAAAAAEAAAASAAEAAAAAAAIAAAASAAEAAAABAAEAAAASAAEAAAABAAIAAAASAAEAAAACAAEAAAASAAEAAAACAAIAAAASAAEAAAACAAYAAAATAAQAAAAJAAYAAAAOAAcAAAAJAAwAAAACAAEAAAAIAAMAAAALAAQAAAAHAAMAAAALAAQAAAAGAAMAAAALAAQAAAATAAQAAAALAAQAAAAUAAQAAAALAAQAAAAVAAQAAAALAAQAAAAWAAQAAAALAAQAAAAMAAkAAAALAAQAAAAOAAkAAAALAAQAAAA=") +tile_set = ExtResource("9_yeq8b") + +[node name="TerrainDetailsA" type="TileMapLayer" parent="Level/TerrainTileMaps" unique_id=1513560262] +z_index = 1 +position = Vector2(9, 9) +tile_map_data = PackedByteArray("AAADAA0AAAADAAYAAAABAAwAAAABAAYAAAABAA0AAAABAAYAAAACAAsAAAACAAEAAAADAAsAAAADAAEAAAACAAwAAAACAAYAAAACAA4AAAACAAYAAAAXAAsAAAADAAUAAAAXAAwAAAADAAYAAAAXAA0AAAADAAYAAAAXAA4AAAADAAYAAAAWAAoAAAAEAAcAAAAWAAsAAAACAAUAAAAWAAwAAAAEAAUAAAAWAA0AAAACAAYAAAAWAA4AAAAEAAUAAAAVAAsAAAABAAUAAAAVAAwAAAABAAYAAAAVAA0AAAABAAYAAAAVAA4AAAABAAYAAAAQAA4AAAADAAYAAAAOAA4AAAAEAAUAAAAPAA4AAAACAAYAAAAQAA0AAAADAAMAAAANAA4AAAABAAYAAAAOAAwAAAAEAAYAAAAPAA0AAAACAAMAAAAOAA0AAAACAAMAAAANAA0AAAABAAMAAAAKAAMAAAARAAAAAAALAAMAAAASAAAAAAAMAAMAAAATAAAAAAAOAAIAAAARAAAAAAAPAAIAAAASAAAAAAADAAwAAAADAAYAAAAQAAIAAAATAAAAAAACAA0AAAAEAAUAAAABAA4AAAABAAYAAAADAA4AAAADAAYAAAABAAsAAAABAAEAAAAUAPz/AAASAAcAAAA=") +tile_set = ExtResource("9_yeq8b") + +[node name="TerrainDetailsB" type="TileMapLayer" parent="Level/TerrainTileMaps" unique_id=478648603] +z_index = 2 +position = Vector2(9, 9) +tile_map_data = PackedByteArray("AAAGAAwAAAADAAEAAAAGAA0AAAADAAYAAAAFAA4AAAACAAYAAAAFAAsAAAAFAAYAAAAFAAwAAAACAAEAAAAFAA0AAAAEAAUAAAAGAA4AAAADAAYAAAADAAwAAAABAAEAAAADAA0AAAABAAYAAAADAA4AAAABAAYAAAAEAAwAAAACAAEAAAAEAA0AAAACAAYAAAAEAA4AAAAEAAUAAAA=") +tile_set = ExtResource("9_yeq8b") + +[node name="ActorsAndCharacters" type="Node2D" parent="Level" unique_id=2036761714] + +[node name="Player" parent="Level/ActorsAndCharacters" unique_id=1343528246 instance=ExtResource("10_invaa")] +z_index = 10 +position = Vector2(144, 215) +rotation = -3.1415927 +scale = Vector2(1, -1) + +[node name="PrefabInstances" type="Node2D" parent="Level" unique_id=2013556771] + +[node name="Structures" type="Node2D" parent="Level/PrefabInstances" unique_id=1811607442] + +[node name="Hazards" type="Node2D" parent="Level/PrefabInstances" unique_id=888595377] + +[node name="Spikes_01" parent="Level/PrefabInstances/Hazards" unique_id=1025977450 instance=ExtResource("11_88b2t")] +z_index = 5 +position = Vector2(270, 216) + +[node name="Spikes_02" parent="Level/PrefabInstances/Hazards" unique_id=1262276584 instance=ExtResource("11_88b2t")] +z_index = 5 +position = Vector2(335, 127) + +[node name="SpikesGrey_01" parent="Level/PrefabInstances/Hazards" unique_id=214833071 instance=ExtResource("12_0ydwj")] +z_index = 5 +position = Vector2(109, 199) + +[node name="SpikesGrey_02" parent="Level/PrefabInstances/Hazards" unique_id=458791480 instance=ExtResource("12_0ydwj")] +z_index = 5 +position = Vector2(331, 216) + +[node name="Enemies" type="Node2D" parent="Level/PrefabInstances" unique_id=93211253] + +[node name="BulletRain_01" parent="Level/PrefabInstances/Enemies" instance=ExtResource("20_rain")] +position = Vector2(234, 0) + +[node name="Interactables" type="Node2D" parent="Level/PrefabInstances" unique_id=769532488] + +[node name="SpringRed_01" parent="Level/PrefabInstances/Interactables" unique_id=34192139 instance=ExtResource("15_usk20")] +visible = false +z_index = 5 +position = Vector2(448, 125) + +[node name="Door_01" parent="Level/PrefabInstances/Interactables" unique_id=1264725697 instance=ExtResource("16_y8u0o")] +z_index = 5 +position = Vector2(288, 37) + +[node name="Collectibles" type="Node2D" parent="Level/PrefabInstances" unique_id=2086540192] + +[node name="CoinGoldRound_01" parent="Level/PrefabInstances/Collectibles" unique_id=926105584 instance=ExtResource("17_16ffm")] +z_index = 5 +position = Vector2(447, 130) + +[node name="CoinGoldRound_02" parent="Level/PrefabInstances/Collectibles" unique_id=1674416025 instance=ExtResource("17_16ffm")] +z_index = 5 +position = Vector2(67, 184) + +[node name="CoinGoldRound_03" parent="Level/PrefabInstances/Collectibles" unique_id=1087706364 instance=ExtResource("17_16ffm")] +z_index = 5 +position = Vector2(182, 109) + +[node name="KeyGold_01" parent="Level/PrefabInstances/Collectibles" unique_id=2060959680 instance=ExtResource("18_kvrlk")] +z_index = 5 +position = Vector2(145, 220) + +[node name="Diamond_01" parent="Level/PrefabInstances/Collectibles" unique_id=909237898 instance=ExtResource("19_85fmh")] +z_index = 5 +position = Vector2(399, 161) + +[node name="Diamond_02" parent="Level/PrefabInstances/Collectibles" unique_id=234727210 instance=ExtResource("19_85fmh")] +z_index = 5 +position = Vector2(204, 217) + +[node name="Diamond_03" parent="Level/PrefabInstances/Collectibles" unique_id=1261326529 instance=ExtResource("19_85fmh")] +z_index = 5 +position = Vector2(288, 125) + +[node name="Signs" type="Node2D" parent="Level/PrefabInstances" unique_id=113197076] diff --git a/scenes/prefabs/enemies/bullet.tscn b/scenes/prefabs/enemies/bullet.tscn index 6deaa8e..61bdef4 100644 --- a/scenes/prefabs/enemies/bullet.tscn +++ b/scenes/prefabs/enemies/bullet.tscn @@ -17,6 +17,6 @@ texture_filter = 1 shape = SubResource("Shape_bullet") [node name="Probe" type="RayCast2D" parent="."] -collision_mask = 1 +collision_mask = 3 hit_from_inside = true target_position = Vector2(-12, 0) diff --git a/scenes/prefabs/enemies/bullet_rain.tscn b/scenes/prefabs/enemies/bullet_rain.tscn new file mode 100644 index 0000000..c710cfe --- /dev/null +++ b/scenes/prefabs/enemies/bullet_rain.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/bullet_rain.gd" id="1_rain"] + +[node name="BulletRain" type="Node2D"] +script = ExtResource("1_rain") diff --git a/scripts/bullet_rain.gd b/scripts/bullet_rain.gd new file mode 100644 index 0000000..856ade0 --- /dev/null +++ b/scripts/bullet_rain.gd @@ -0,0 +1,64 @@ +extends Node2D + +## 子弹雨:从天上随机横坐标往下落子弹,密度可以调得很疏。 +## +## 落下来的子弹撞到地形、或撞到你铺的「绳子/木板桥」就会消失 —— +## 绳子的碰撞放在 TileSet 的第 2 物理层,只有子弹的探针(mask = 3)会检测它, +## 玩家(mask = 1)和钥匙(跟着玩家的 mask)都不受影响,能直接穿过去。 + +const BULLET := preload("res://scenes/prefabs/enemies/bullet.tscn") + +@export var enabled: bool = true +## 平均多少秒落一颗(数值越大越稀疏) +@export var interval: float = 1.0 +## 间隔随机浮动范围(0 = 完全固定节奏) +@export var interval_jitter: float = 0.6 +## 开场后第一次落下的延迟 +@export var start_delay: float = 1.5 +## 生成高度(相对自己的 y,负数 = 从屏幕上方外面) +@export var spawn_y: float = -30.0 +## 水平撒落范围:以自己的 x 为中心,左右各一半 +@export var span: float = 468.0 +## 下落速度 +@export var fall_speed: float = 70.0 +@export var damage: int = 1 +@export var bullet_color: Color = Color(0.55, 0.8, 1.0) +## 固定随机种子(0 = 每次运行都不同) +@export var random_seed: int = 0 + +var _timer: float = 0.0 +var _rng := RandomNumberGenerator.new() +var dropped: int = 0 + + +func _ready() -> void: + add_to_group("bullet_rain") + if random_seed != 0: + _rng.seed = random_seed + else: + _rng.randomize() + _timer = start_delay + + +func _physics_process(delta: float) -> void: + if not enabled: + return + _timer -= delta + if _timer > 0.0: + return + _timer = maxf(interval + _rng.randf_range(-interval_jitter, interval_jitter), 0.05) + drop() + + +func drop() -> void: + var bullet := BULLET.instantiate() + # 这几个属性必须在 add_child 之前设好 + bullet.bullet_color = bullet_color + bullet.speed = fall_speed + bullet.damage = damage + get_parent().add_child(bullet) + bullet.global_position = Vector2( + global_position.x + _rng.randf_range(-span * 0.5, span * 0.5), + global_position.y + spawn_y) + bullet.launch(Vector2(0.0, 1.0), fall_speed) + dropped += 1 diff --git a/scripts/bullet_rain.gd.uid b/scripts/bullet_rain.gd.uid new file mode 100644 index 0000000..5399284 --- /dev/null +++ b/scripts/bullet_rain.gd.uid @@ -0,0 +1 @@ +uid://dbpe6r76gao3w