Add diamond collection and a level-clear door

The three diamonds and both doors were painted as tiles in TerrainBase, which cannot act as pickups or triggers. Replaced them with real prefabs that reuse the same atlas tiles (diamond = (7,3), doors = (10,6) and (11,5)) and erase their placeholder tile on ready. Collecting all three diamonds unlocks the door; touching it fades to black, pauses the tree and shows the level-clear screen with a next-level button (currently reloads the level, as there is only one). HUD now shows the diamond count.
This commit is contained in:
2026-10-07 21:04:58 +08:00
parent f67bd94605
commit 7c78a088a0
10 changed files with 335 additions and 12 deletions
+24 -4
View File
@@ -1,4 +1,4 @@
[gd_scene load_steps=6 format=3]
[gd_scene load_steps=7 format=3]
[ext_resource type="Texture2D" path="res://assets/game/tilesets/kenney_tiles_atlas.png" id="1_atlas"]
[ext_resource type="Texture2D" path="res://assets/game/collectibles/coin_gold_round.png" id="2_coin"]
@@ -12,6 +12,10 @@ region = Rect2(72, 36, 18, 18)
atlas = ExtResource("1_atlas")
region = Rect2(108, 36, 18, 18)
[sub_resource type="AtlasTexture" id="AtlasTexture_diamond"]
atlas = ExtResource("1_atlas")
region = Rect2(126, 54, 18, 18)
[node name="HUD" type="CanvasLayer"]
script = ExtResource("3_hud")
full_heart_texture = SubResource("AtlasTexture_heart_full")
@@ -54,11 +58,27 @@ theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 12
text = "x0"
[node name="DiamondIcon" type="TextureRect" parent="."]
offset_left = 9.0
offset_top = 45.0
offset_right = 27.0
offset_bottom = 63.0
texture = SubResource("AtlasTexture_diamond")
[node name="DiamondLabel" type="Label" parent="."]
offset_left = 30.0
offset_top = 44.0
offset_right = 130.0
offset_bottom = 64.0
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 12
text = "0 / 3"
[node name="ShieldLabel" type="Label" parent="."]
offset_left = 8.0
offset_top = 46.0
offset_right = 160.0
offset_bottom = 66.0
offset_top = 64.0
offset_right = 170.0
offset_bottom = 84.0
theme_override_colors/font_color = Color(0.55, 0.9, 1, 1)
theme_override_font_sizes/font_size = 12
text = ""
+56
View File
@@ -0,0 +1,56 @@
[gd_scene load_steps=4 format=3]
[ext_resource type="Script" path="res://scripts/level_clear.gd" id="1_clear"]
[sub_resource type="SystemFont" id="SystemFont_cjk"]
font_names = PackedStringArray("Microsoft YaHei UI", "Microsoft YaHei", "SimHei", "Noto Sans CJK SC", "sans-serif")
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_button"]
bg_color = Color(0.16, 0.62, 0.36, 1)
corner_radius_top_left = 3
corner_radius_top_right = 3
corner_radius_bottom_right = 3
corner_radius_bottom_left = 3
content_margin_left = 18.0
content_margin_top = 6.0
content_margin_right = 18.0
content_margin_bottom = 6.0
[node name="LevelClear" type="CanvasLayer" groups=["level_clear"]]
process_mode = 3
layer = 20
script = ExtResource("1_clear")
[node name="Fade" type="ColorRect" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
mouse_filter = 2
color = Color(0, 0, 0, 0)
[node name="Center" type="CenterContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
mouse_filter = 2
[node name="VBox" type="VBoxContainer" parent="Center"]
theme_override_constants/separation = 10
[node name="Title" type="Label" parent="Center/VBox"]
theme_override_colors/font_color = Color(1, 0.85, 0.3, 1)
theme_override_fonts/font = SubResource("SystemFont_cjk")
theme_override_font_sizes/font_size = 26
text = "过关!"
horizontal_alignment = 1
[node name="Subtitle" type="Label" parent="Center/VBox"]
theme_override_colors/font_color = Color(0.8, 0.95, 0.85, 1)
theme_override_fonts/font = SubResource("SystemFont_cjk")
theme_override_font_sizes/font_size = 13
text = "钻石 3 / 3"
horizontal_alignment = 1
[node name="NextButton" type="Button" parent="Center/VBox"]
theme_override_fonts/font = SubResource("SystemFont_cjk")
theme_override_font_sizes/font_size = 14
theme_override_styles/normal = SubResource("StyleBoxFlat_button")
text = "进入下一关 (R)"
+29 -3
View File
@@ -14,6 +14,9 @@
[ext_resource type="PackedScene" path="res://scenes/hud.tscn" id="21_hud"]
[ext_resource type="PackedScene" path="res://scenes/death_screen.tscn" id="22_death"]
[ext_resource type="PackedScene" path="res://scenes/prefabs/hazards/spikes_grey.tscn" id="23_spikesgrey"]
[ext_resource type="PackedScene" path="res://scenes/prefabs/collectibles/diamond.tscn" id="24_diamond"]
[ext_resource type="PackedScene" path="res://scenes/prefabs/interactables/door.tscn" id="25_door"]
[ext_resource type="PackedScene" path="res://scenes/level_clear.tscn" id="26_clear"]
[node name="Main" type="Node2D" unique_id=2061129075]
@@ -21,6 +24,8 @@
[node name="DeathScreen" parent="." unique_id=1952687359 instance=ExtResource("22_death")]
[node name="LevelClear" parent="." instance=ExtResource("26_clear")]
[node name="Level" type="Node2D" parent="." unique_id=1678372922]
[node name="Background" type="Node2D" parent="Level" unique_id=702011751]
@@ -155,7 +160,7 @@ script = ExtResource("19_hidden")
[node name="TerrainBase" type="TileMapLayer" parent="Level/TerrainTileMaps" unique_id=91115499]
position = Vector2(9, 9)
tile_map_data = PackedByteArray("AAAAAAEAAAABAAUAAAAEAAEAAAABAAUAAAAFAAEAAAACAAUAAAAGAAEAAAADAAUAAAAMAAEAAAARAAAAAAANAAEAAAASAAAAAAAOAAEAAAATAAAAAAAAAAIAAAAEAAUAAAADAAIAAAABAAUAAAAEAAIAAAAEAAUAAAAFAAIAAAAEAAAAAAAGAAIAAAADAAcAAAALAAIAAAARAAAAAAAMAAIAAAASAAEAAAANAAIAAAASAAEAAAAOAAIAAAATAAEAAAAAAAMAAAACAAYAAAADAAMAAAACAAcAAAAEAAMAAAACAAcAAAAFAAMAAAADAAcAAAALAAMAAAARAAIAAAAMAAMAAAASAAEAAAANAAMAAAASAAEAAAAOAAMAAAATAAEAAAAVAAMAAAANAAcAAAAWAAMAAAAPAAcAAAAAAAQAAAACAAYAAAAEAAQAAAAJAAMAAAAMAAQAAAARAAEAAAANAAQAAAASAAEAAAAOAAQAAAATAAEAAAAEAAUAAAAJAAQAAAAMAAUAAAARAAIAAAANAAUAAAARAAQAAAAOAAUAAAATAAIAAAAWAAUAAAALAAUAAAAEAAYAAAAJAAQAAAAIAAYAAAAJAAEAAAANAAYAAAAQAAQAAAAQAAYAAAANAAcAAAARAAYAAAAOAAcAAAASAAYAAAAPAAcAAAAUAAYAAAALAAIAAAAWAAYAAAALAAYAAAAXAAYAAAAFAAcAAAACAAcAAAABAAEAAAAEAAcAAAAJAAUAAAAGAAcAAAAIAAQAAAANAAcAAAAQAAUAAAAUAAcAAAALAAMAAAAVAAcAAAABAAUAAAAWAAcAAAACAAUAAAAXAAcAAAADAAUAAAAYAAcAAAAGAAUAAAAZAAcAAAAGAAUAAAACAAgAAAABAAYAAAADAAgAAAACAAYAAAAEAAgAAAACAAEAAAAFAAgAAAACAAEAAAAGAAgAAAADAAEAAAAKAAgA//8HAAEAAAAMAAgAAAASAAUAAAANAAgAAAARAAUAAAAOAAgAAAATAAQAABAPAAgAAAASAAQAABAUAAgAAAALAAMAAAAVAAgAAAABAAYAAAAWAAgAAAACAAYAAAAXAAgAAAAEAAEAAAAYAAgAAAACAAUAAAAZAAgAAAACAAUAAAAAAAkAAAACAAEAAAABAAkAAAACAAEAAAACAAkAAAAFAAEAAAADAAkAAAACAAYAAAAEAAkAAAACAAYAAAAFAAkAAAACAAYAAAAGAAkAAAADAAYAAAANAAkAAAAQAAUAAAASAAkAAAAGAAcAAAAUAAkAAAABAAUAAAAVAAkAAAAFAAEAAAAWAAkAAAAEAAUAAAAXAAkAAAACAAYAAAAYAAkAAAACAAYAAAAZAAkAAAACAAYAAAAAAAoAAAAEAAUAAAABAAoAAAACAAYAAAACAAoAAAACAAYAAAADAAoAAAACAAYAAAAEAAoAAAAEAAUAAAAFAAoAAAACAAYAAAAGAAoAAAAEAAEAAAAHAAoAAAADAAEAAAAIAAoAAAAGAAUAAAANAAoAAAARAAYAAAAPAAoAAAAHAAYAAAARAAoAAAAKAAUAAAATAAoAAAAEAAcAAAAUAAoAAAABAAYAAAAVAAoAAAACAAYAAAAWAAoAAAACAAYAAAAXAAoAAAACAAYAAAAYAAoAAAACAAYAAAAZAAoAAAACAAYAAAAAAAsAAAAEAAUAAAABAAsAAAACAAYAAAACAAsAAAAEAAUAAAADAAsAAAAEAAUAAAAEAAsAAAACAAYAAAAFAAsAAAAEAAUAAAAGAAsAAAACAAYAAAAHAAsAAAAEAAEAAAAIAAsAAAADAAEAAAAKAAsAAAAEAAYAAAAMAAsAAAABAAEAAAANAAsAAAACAAEAAAAOAAsAAAACAAMAAAAPAAsAAAADAAMAAAARAAsAAAAKAAYAAAATAAsAAAABAAUAAAAUAAsAAAAFAAEAAAAVAAsAAAACAAYAAAAWAAsAAAAEAAUAAAAXAAsAAAAEAAUAAAAYAAsAAAAEAAUAAAAZAAsAAAACAAYAAAAAAAwAAAACAAYAAAABAAwAAAACAAYAAAACAAwAAAACAAYAAAADAAwAAAAEAAUAAAAEAAwAAAACAAYAAAAFAAwAAAAEAAUAAAAGAAwAAAAEAAUAAAAHAAwAAAAEAAUAAAAIAAwAAAAEAAEAAAAJAAwAAAACAAEAAAAKAAwAAAACAAEAAAALAAwAAAACAAEAAAAMAAwAAAAFAAEAAAANAAwAAAAEAAUAAAAOAAwAAAAEAAUAAAAPAAwAAAAEAAEAAAAQAAwAAAACAAMAAAARAAwAAAACAAMAAAASAAwAAAACAAMAAAATAAwAAAAFAAEAAAAUAAwAAAACAAYAAAAVAAwAAAAEAAUAAAAWAAwAAAACAAYAAAAXAAwAAAAEAAUAAAAYAAwAAAAEAAUAAAAZAAwAAAACAAYAAAAAAA0AAAAEAAUAAAABAA0AAAACAAYAAAACAA0AAAAEAAUAAAADAA0AAAACAAYAAAAEAA0AAAACAAYAAAAFAA0AAAAEAAUAAAAGAA0AAAACAAYAAAAHAA0AAAACAAYAAAAIAA0AAAAEAAUAAAAJAA0AAAACAAYAAAAKAA0AAAAEAAUAAAALAA0AAAAEAAUAAAAMAA0AAAACAAYAAAANAA0AAAACAAYAAAAOAA0AAAAEAAUAAAAPAA0AAAAEAAUAAAAQAA0AAAAEAAUAAAARAA0AAAACAAYAAAASAA0AAAACAAYAAAATAA0AAAAEAAUAAAAUAA0AAAACAAYAAAAVAA0AAAACAAYAAAAWAA0AAAACAAYAAAAXAA0AAAAEAAUAAAAYAA0AAAACAAYAAAAZAA0AAAAEAAUAAAAAAA4AAAACAAYAAAABAA4AAAACAAYAAAACAA4AAAAEAAUAAAADAA4AAAACAAYAAAAEAA4AAAAEAAUAAAAFAA4AAAACAAYAAAAGAA4AAAAEAAUAAAAHAA4AAAAEAAUAAAAIAA4AAAAEAAUAAAAJAA4AAAAEAAUAAAAKAA4AAAAEAAUAAAALAA4AAAAEAAUAAAAMAA4AAAACAAYAAAANAA4AAAACAAYAAAAOAA4AAAACAAYAAAAPAA4AAAACAAYAAAAQAA4AAAAEAAUAAAARAA4AAAACAAYAAAASAA4AAAACAAYAAAATAA4AAAACAAYAAAAUAA4AAAACAAYAAAAVAA4AAAACAAYAAAAWAA4AAAAEAAUAAAAXAA4AAAAEAAUAAAAYAA4AAAACAAYAAAAZAA4AAAAEAAUAAAD//wkAAAACAAEAAAD//woAAAAEAAAAAAD//wsAAAAEAAAAAAD//wwAAAAFAAAAAAD//wQAAAAFAAAAAAD//wIAAAAFAAAAAAD//wMAAAAFAAAAAAD//wEAAAACAAUAAAAAAAUAAAACAAcAAAD//wUAAAACAAcAAAD//w0AAAAEAAEAAAD//w4AAAAEAAEAAAD//wYAAAAJAAAAAAD//wcAAAAJAAAAAAD//wgAAAAJAAAAAAAKAAkAAAAJAAEAAAAVAAIAAAAKAAAAAAABAAUAAAADAAcAAAABAAQAAAADAAUAAAADAAcAAAADAAEAAAANAAAAAAAIAAMAAAAOAAAAAAAIAAMAAAA=")
tile_map_data = PackedByteArray("AAAAAAEAAAABAAUAAAAEAAEAAAABAAUAAAAFAAEAAAACAAUAAAAGAAEAAAADAAUAAAAMAAEAAAARAAAAAAANAAEAAAASAAAAAAAOAAEAAAATAAAAAAAAAAIAAAAEAAUAAAADAAIAAAABAAUAAAAEAAIAAAAEAAUAAAAFAAIAAAAEAAAAAAAGAAIAAAADAAcAAAALAAIAAAARAAAAAAAMAAIAAAASAAEAAAANAAIAAAASAAEAAAAOAAIAAAATAAEAAAAAAAMAAAACAAYAAAADAAMAAAACAAcAAAAEAAMAAAACAAcAAAAFAAMAAAADAAcAAAALAAMAAAARAAIAAAAMAAMAAAASAAEAAAANAAMAAAASAAEAAAAOAAMAAAATAAEAAAAVAAMAAAANAAcAAAAWAAMAAAAPAAcAAAAAAAQAAAACAAYAAAAEAAQAAAAJAAMAAAAMAAQAAAARAAEAAAANAAQAAAASAAEAAAAOAAQAAAATAAEAAAAEAAUAAAAJAAQAAAAMAAUAAAARAAIAAAANAAUAAAARAAQAAAAOAAUAAAATAAIAAAAWAAUAAAALAAUAAAAEAAYAAAAJAAQAAAAIAAYAAAAJAAEAAAANAAYAAAAQAAQAAAAQAAYAAAANAAcAAAARAAYAAAAOAAcAAAASAAYAAAAPAAcAAAAUAAYAAAALAAIAAAAWAAYAAAALAAYAAAACAAcAAAABAAEAAAAEAAcAAAAJAAUAAAAGAAcAAAAIAAQAAAANAAcAAAAQAAUAAAAUAAcAAAALAAMAAAAVAAcAAAABAAUAAAAWAAcAAAACAAUAAAAXAAcAAAADAAUAAAAYAAcAAAAGAAUAAAAZAAcAAAAGAAUAAAACAAgAAAABAAYAAAADAAgAAAACAAYAAAAEAAgAAAACAAEAAAAFAAgAAAACAAEAAAAGAAgAAAADAAEAAAAMAAgAAAASAAUAAAANAAgAAAARAAUAAAAOAAgAAAATAAQAABAPAAgAAAASAAQAABAUAAgAAAALAAMAAAAVAAgAAAABAAYAAAAWAAgAAAACAAYAAAAXAAgAAAAEAAEAAAAYAAgAAAACAAUAAAAZAAgAAAACAAUAAAAAAAkAAAACAAEAAAABAAkAAAACAAEAAAACAAkAAAAFAAEAAAADAAkAAAACAAYAAAAEAAkAAAACAAYAAAAFAAkAAAACAAYAAAAGAAkAAAADAAYAAAANAAkAAAAQAAUAAAASAAkAAAAGAAcAAAAUAAkAAAABAAUAAAAVAAkAAAAFAAEAAAAWAAkAAAAEAAUAAAAXAAkAAAACAAYAAAAYAAkAAAACAAYAAAAZAAkAAAACAAYAAAAAAAoAAAAEAAUAAAABAAoAAAACAAYAAAACAAoAAAACAAYAAAADAAoAAAACAAYAAAAEAAoAAAAEAAUAAAAFAAoAAAACAAYAAAAGAAoAAAAEAAEAAAAHAAoAAAADAAEAAAAIAAoAAAAGAAUAAAANAAoAAAARAAYAAAAPAAoAAAAHAAYAAAARAAoAAAAKAAUAAAATAAoAAAAEAAcAAAAUAAoAAAABAAYAAAAVAAoAAAACAAYAAAAWAAoAAAACAAYAAAAXAAoAAAACAAYAAAAYAAoAAAACAAYAAAAZAAoAAAACAAYAAAAAAAsAAAAEAAUAAAABAAsAAAACAAYAAAACAAsAAAAEAAUAAAADAAsAAAAEAAUAAAAEAAsAAAACAAYAAAAFAAsAAAAEAAUAAAAGAAsAAAACAAYAAAAHAAsAAAAEAAEAAAAIAAsAAAADAAEAAAAKAAsAAAAEAAYAAAAMAAsAAAABAAEAAAANAAsAAAACAAEAAAAOAAsAAAACAAMAAAAPAAsAAAADAAMAAAARAAsAAAAKAAYAAAATAAsAAAABAAUAAAAUAAsAAAAFAAEAAAAVAAsAAAACAAYAAAAWAAsAAAAEAAUAAAAXAAsAAAAEAAUAAAAYAAsAAAAEAAUAAAAZAAsAAAACAAYAAAAAAAwAAAACAAYAAAABAAwAAAACAAYAAAACAAwAAAACAAYAAAADAAwAAAAEAAUAAAAEAAwAAAACAAYAAAAFAAwAAAAEAAUAAAAGAAwAAAAEAAUAAAAHAAwAAAAEAAUAAAAIAAwAAAAEAAEAAAAJAAwAAAACAAEAAAAKAAwAAAACAAEAAAALAAwAAAACAAEAAAAMAAwAAAAFAAEAAAANAAwAAAAEAAUAAAAOAAwAAAAEAAUAAAAPAAwAAAAEAAEAAAAQAAwAAAACAAMAAAARAAwAAAACAAMAAAASAAwAAAACAAMAAAATAAwAAAAFAAEAAAAUAAwAAAACAAYAAAAVAAwAAAAEAAUAAAAWAAwAAAACAAYAAAAXAAwAAAAEAAUAAAAYAAwAAAAEAAUAAAAZAAwAAAACAAYAAAAAAA0AAAAEAAUAAAABAA0AAAACAAYAAAACAA0AAAAEAAUAAAADAA0AAAACAAYAAAAEAA0AAAACAAYAAAAFAA0AAAAEAAUAAAAGAA0AAAACAAYAAAAHAA0AAAACAAYAAAAIAA0AAAAEAAUAAAAJAA0AAAACAAYAAAAKAA0AAAAEAAUAAAALAA0AAAAEAAUAAAAMAA0AAAACAAYAAAANAA0AAAACAAYAAAAOAA0AAAAEAAUAAAAPAA0AAAAEAAUAAAAQAA0AAAAEAAUAAAARAA0AAAACAAYAAAASAA0AAAACAAYAAAATAA0AAAAEAAUAAAAUAA0AAAACAAYAAAAVAA0AAAACAAYAAAAWAA0AAAACAAYAAAAXAA0AAAAEAAUAAAAYAA0AAAACAAYAAAAZAA0AAAAEAAUAAAAAAA4AAAACAAYAAAABAA4AAAACAAYAAAACAA4AAAAEAAUAAAADAA4AAAACAAYAAAAEAA4AAAAEAAUAAAAFAA4AAAACAAYAAAAGAA4AAAAEAAUAAAAHAA4AAAAEAAUAAAAIAA4AAAAEAAUAAAAJAA4AAAAEAAUAAAAKAA4AAAAEAAUAAAALAA4AAAAEAAUAAAAMAA4AAAACAAYAAAANAA4AAAACAAYAAAAOAA4AAAACAAYAAAAPAA4AAAACAAYAAAAQAA4AAAAEAAUAAAARAA4AAAACAAYAAAASAA4AAAACAAYAAAATAA4AAAACAAYAAAAUAA4AAAACAAYAAAAVAA4AAAACAAYAAAAWAA4AAAAEAAUAAAAXAA4AAAAEAAUAAAAYAA4AAAACAAYAAAAZAA4AAAAEAAUAAAD//wkAAAACAAEAAAD//woAAAAEAAAAAAD//wsAAAAEAAAAAAD//wwAAAAFAAAAAAD//wQAAAAFAAAAAAD//wIAAAAFAAAAAAD//wMAAAAFAAAAAAD//wEAAAACAAUAAAAAAAUAAAACAAcAAAD//wUAAAACAAcAAAD//w0AAAAEAAEAAAD//w4AAAAEAAEAAAD//wYAAAAJAAAAAAD//wcAAAAJAAAAAAD//wgAAAAJAAAAAAAKAAkAAAAJAAEAAAABAAUAAAADAAcAAAABAAQAAAADAAUAAAADAAcAAAADAAEAAAANAAAAAAAIAAMAAAAOAAAAAAAIAAMAAAAWAAIAAAAHAAMAAAAEAAAAAAAHAAMAAAAOAAcAAAAHAAMAAAA=")
tile_set = ExtResource("5_4etix")
[node name="TerrainDetailsA" type="TileMapLayer" parent="Level/TerrainTileMaps" unique_id=1513560262]
@@ -192,11 +197,11 @@ position = Vector2(270, 216)
z_index = 5
position = Vector2(216, 216)
[node name="SpikesGrey_01" parent="Level/PrefabInstances/Hazards" instance=ExtResource("23_spikesgrey")]
[node name="SpikesGrey_01" parent="Level/PrefabInstances/Hazards" unique_id=214833071 instance=ExtResource("23_spikesgrey")]
z_index = 5
position = Vector2(252, 18)
[node name="SpikesGrey_02" parent="Level/PrefabInstances/Hazards" instance=ExtResource("23_spikesgrey")]
[node name="SpikesGrey_02" parent="Level/PrefabInstances/Hazards" unique_id=458791480 instance=ExtResource("23_spikesgrey")]
z_index = 5
position = Vector2(270, 18)
@@ -206,6 +211,15 @@ position = Vector2(270, 18)
z_index = 5
position = Vector2(325, 108)
[node name="Door_01" parent="Level/PrefabInstances/Interactables" instance=ExtResource("25_door")]
z_index = 5
position = Vector2(324, 216)
[node name="Door_02" parent="Level/PrefabInstances/Interactables" instance=ExtResource("25_door")]
z_index = 5
position = Vector2(414, 108)
atlas_region = Rect2(198, 90, 18, 18)
[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_rmlt8")]
@@ -224,4 +238,16 @@ position = Vector2(315, 63)
z_index = 5
position = Vector2(126, 144)
[node name="Diamond_01" parent="Level/PrefabInstances/Collectibles" instance=ExtResource("24_diamond")]
z_index = 5
position = Vector2(90, 18)
[node name="Diamond_02" parent="Level/PrefabInstances/Collectibles" instance=ExtResource("24_diamond")]
z_index = 5
position = Vector2(414, 54)
[node name="Diamond_03" parent="Level/PrefabInstances/Collectibles" instance=ExtResource("24_diamond")]
z_index = 5
position = Vector2(270, 144)
[node name="Signs" type="Node2D" parent="Level/PrefabInstances" unique_id=113197076]
+23
View File
@@ -0,0 +1,23 @@
[gd_scene load_steps=5 format=3]
[ext_resource type="Texture2D" path="res://assets/game/tilesets/kenney_tiles_atlas.png" id="1_atlas"]
[ext_resource type="Script" path="res://scripts/diamond.gd" id="2_diamond"]
[sub_resource type="AtlasTexture" id="AtlasTexture_diamond"]
atlas = ExtResource("1_atlas")
region = Rect2(126, 54, 18, 18)
[sub_resource type="CircleShape2D" id="Shape_diamond"]
radius = 7.0
[node name="Diamond" type="Area2D" groups=["diamond"]]
collision_layer = 16
collision_mask = 2
script = ExtResource("2_diamond")
[node name="Sprite" type="Sprite2D" parent="."]
texture_filter = 1
texture = SubResource("AtlasTexture_diamond")
[node name="PickupArea" type="CollisionShape2D" parent="."]
shape = SubResource("Shape_diamond")
+23
View File
@@ -0,0 +1,23 @@
[gd_scene load_steps=5 format=3]
[ext_resource type="Texture2D" path="res://assets/game/tilesets/kenney_tiles_atlas.png" id="1_atlas"]
[ext_resource type="Script" path="res://scripts/door.gd" id="2_door"]
[sub_resource type="AtlasTexture" id="AtlasTexture_door"]
atlas = ExtResource("1_atlas")
region = Rect2(180, 108, 18, 18)
[sub_resource type="RectangleShape2D" id="Shape_door"]
size = Vector2(18, 18)
[node name="Door" type="Area2D" groups=["door"]]
collision_layer = 8
collision_mask = 2
script = ExtResource("2_door")
[node name="Sprite" type="Sprite2D" parent="."]
texture_filter = 1
texture = SubResource("AtlasTexture_door")
[node name="TriggerArea" type="CollisionShape2D" parent="."]
shape = SubResource("Shape_door")
+26
View File
@@ -0,0 +1,26 @@
extends Area2D
## 钻石:走过去自动收集,集齐后碰门过关
@export var erase_placeholder_tile: bool = true
func _ready() -> void:
body_entered.connect(_on_body_entered)
if erase_placeholder_tile:
_erase_placeholder_tile()
func _on_body_entered(body: Node2D) -> void:
if body.has_method("add_diamond"):
body.add_diamond()
queue_free()
func _erase_placeholder_tile() -> void:
var root: Node = owner if owner != null else get_parent()
if root == null:
return
for layer in root.find_children("*", "TileMapLayer", true, false):
var cell: Vector2i = layer.local_to_map(layer.to_local(global_position))
if layer.get_cell_source_id(cell) != -1:
layer.erase_cell(cell)
+54
View File
@@ -0,0 +1,54 @@
extends Area2D
## 门:集齐钻石后碰到就过关;没集齐则闪一下红色提示。
@export var required_diamonds: int = 3
## 门贴图在图集里的区域(不同门可以不一样)
@export var atlas_region: Rect2 = Rect2(180, 108, 18, 18)
## 开场时擦掉脚下的占位地砖
@export var erase_placeholder_tile: bool = true
const ATLAS := preload("res://assets/game/tilesets/kenney_tiles_atlas.png")
var _sprite: Sprite2D = null
func _ready() -> void:
body_entered.connect(_on_body_entered)
_sprite = get_node_or_null("Sprite")
if _sprite != null:
var tex := AtlasTexture.new()
tex.atlas = ATLAS
tex.region = atlas_region
_sprite.texture = tex
if erase_placeholder_tile:
_erase_placeholder_tile()
func _on_body_entered(body: Node2D) -> void:
if not body.has_method("add_diamond"):
return
if int(body.diamonds) < required_diamonds:
_flash_locked()
return
var clear := get_tree().get_first_node_in_group("level_clear")
if clear != null:
clear.show_clear()
func _flash_locked() -> void:
if _sprite == null:
return
_sprite.modulate = Color(1.0, 0.45, 0.45)
await get_tree().create_timer(0.4).timeout
if is_instance_valid(_sprite):
_sprite.modulate = Color.WHITE
func _erase_placeholder_tile() -> void:
var root: Node = owner if owner != null else get_parent()
if root == null:
return
for layer in root.find_children("*", "TileMapLayer", true, false):
var cell: Vector2i = layer.local_to_map(layer.to_local(global_position))
if layer.get_cell_source_id(cell) != -1:
layer.erase_cell(cell)
+13 -5
View File
@@ -1,6 +1,6 @@
extends CanvasLayer
## 左上角的状态显示:3 颗心 + 回血道具数量 + 护盾剩余时间。
## 左上角的状态显示:3 颗心 + 回血道具数量 + 钻石数量 + 护盾剩余时间。
## 每帧从场景里找带 "player" 组的玩家读取状态。
@export var full_heart_texture: Texture2D
@@ -9,6 +9,7 @@ extends CanvasLayer
var _player: Node = null
var _hearts: Array = []
var _count_label: Label = null
var _diamond_label: Label = null
var _shield_label: Label = null
@@ -18,6 +19,7 @@ func _ready() -> void:
if heart != null:
_hearts.append(heart)
_count_label = get_node_or_null("CountLabel")
_diamond_label = get_node_or_null("DiamondLabel")
_shield_label = get_node_or_null("ShieldLabel")
@@ -37,9 +39,15 @@ func _process(_delta: float) -> void:
_count_label.text = "x%d" % items
_count_label.modulate = Color.WHITE if items > 0 else Color(1.0, 1.0, 1.0, 0.4)
if _diamond_label != null:
var got: int = int(_player.diamonds)
var total: int = maxi(int(_player.diamond_total), got)
_diamond_label.text = "%d / %d" % [got, total]
if total > 0 and got >= total:
_diamond_label.modulate = Color(1.0, 0.9, 0.35)
else:
_diamond_label.modulate = Color.WHITE
if _shield_label != null:
var shield: float = float(_player.shield_left)
if shield > 0.0:
_shield_label.text = "SHIELD %.1fs" % shield
else:
_shield_label.text = ""
_shield_label.text = ("SHIELD %.1fs" % shield) if shield > 0.0 else ""
+72
View File
@@ -0,0 +1,72 @@
extends CanvasLayer
## 过关界面:集齐钻石后碰到门显示。
## 显示时把整棵树暂停,所以这一层的 process_mode 设成 ALWAYS(见 .tscn),
## 不然暂停后自己的动画和按钮也会停。
@export var fade_time: float = 0.8
@export var button_delay: float = 0.3
var _fade: ColorRect = null
var _center: CenterContainer = null
var _button: Button = null
var _title: Label = null
var _subtitle: Label = null
var _elapsed: float = 0.0
var _showing: bool = false
func _ready() -> void:
visible = false
_fade = get_node_or_null("Fade")
_center = get_node_or_null("Center")
_button = get_node_or_null("Center/VBox/NextButton")
_title = get_node_or_null("Center/VBox/Title")
_subtitle = get_node_or_null("Center/VBox/Subtitle")
if _button != null:
_button.pressed.connect(next_level)
if _fade != null:
_fade.color = Color(0.0, 0.0, 0.0, 0.0)
if _center != null:
_center.visible = false
func show_clear() -> void:
if _showing:
return
_showing = true
visible = true
_elapsed = 0.0
if _title != null:
_title.text = "过关!"
if _subtitle != null:
var player := get_tree().get_first_node_in_group("player")
var n: int = 0 if player == null else int(player.diamonds)
_subtitle.text = "钻石 %d / %d" % [n, n]
get_tree().paused = true
func _process(delta: float) -> void:
if not _showing:
return
_elapsed += delta
if _fade != null:
_fade.color = Color(0.0, 0.0, 0.0, clampf(_elapsed / maxf(fade_time, 0.01), 0.0, 1.0))
if _center != null and _elapsed >= fade_time + button_delay:
_center.visible = true
func _unhandled_input(event: InputEvent) -> void:
if not _showing:
return
var key := event as InputEventKey
if key != null and key.pressed and not key.echo:
if key.physical_keycode == KEY_R or key.physical_keycode == KEY_ENTER:
next_level()
## 目前项目里只有一关,所以"下一关"先做成重新加载本关。
## 以后真加了第二关,把这里换成 change_scene_to_file("res://scenes/level2.tscn") 即可。
func next_level() -> void:
get_tree().paused = false
get_tree().reload_current_scene()
+15
View File
@@ -60,6 +60,10 @@ var hurt_count: int = 0
var health: int = 3
## 身上的回血道具数量(捡到的小球)
var heal_items: int = 0
## 已收集的钻石数量
var diamonds: int = 0
## 关卡里钻石总数(开场自动数一遍)
var diamond_total: int = 0
## 无敌盾剩余时间,给 HUD 显示用
var shield_left: float = 0.0
## 生命值归零后进入死亡状态:不能操作,交给死亡界面
@@ -84,6 +88,12 @@ func _ready() -> void:
_measure_feet_offset()
_spawn_point = global_position
health = max_health
# 等一帧再数钻石,确保关卡里所有钻石节点都已经 _ready
_count_diamond_total.call_deferred()
func _count_diamond_total() -> void:
diamond_total = get_tree().get_nodes_in_group("diamond").size()
func _physics_process(delta: float) -> void:
@@ -182,6 +192,11 @@ func add_heal_item() -> void:
heal_items += 1
## 由钻石调用
func add_diamond() -> void:
diamonds += 1
## 按 Z:消耗一个回血道具,回一颗心并获得无敌盾
func use_heal_item() -> bool:
if is_dead or heal_items <= 0: