Files
sijcdu 9dffacd938 Initial commit: Godot 4.7 pixel platformer prototype
Player: move/jump (Space), test flight (F, debug builds only). Key: pickup, hold S to aim with live trajectory preview, release to throw, W to warp to the thrown key. Spring bounce. Spikes deal damage. 3-heart health, Z consumes a heal item for +1 heart and a 5s shield. HUD with hearts and item count. Death screen with fade-to-black and restart. Hidden passages. Assets: Kenney Pixel Platformer (CC0).
2026-10-07 20:32:42 +08:00

84 lines
2.5 KiB
GDScript

extends Node2D
const ATLAS := preload("res://assets/game/tilesets/kenney_tiles_atlas.png")
const TILE := 18
## 隐藏通道:下面这些格子在关卡开始时会被"挖空",
## 原本是实心石壁的地方就变成能穿过去的暗道。
## 坐标是格坐标(格边长 18px),改这里就能挪位置。
@export var hidden_cells: Array = [
# ① 主线走廊上的石柱(第 13 列第 6~7 行)
Vector2i(13, 6), Vector2i(13, 7),
# ② 低层暗道(第 11 行第 12~15 列)
Vector2i(12, 11), Vector2i(13, 11), Vector2i(14, 11), Vector2i(15, 11),
]
## 伪装贴图所在层:要低于角色(z=10)、高于地形(z=0~2)
@export var cover_z_index: int = 3
## 是否给洞口盖上"假墙"(关掉的话洞口会明显地露出来)
@export var hide_with_cover: bool = true
func _ready() -> void:
var layers := _tile_layers()
if layers.is_empty():
return
var base: TileMapLayer = layers[0]
# 先把盖子做好(此时参考的那块墙还在),再挖空
var covers: Array = []
for cell in hidden_cells:
covers.append([cell, _make_cover(cell) if hide_with_cover else null])
for cell in hidden_cells:
for layer in layers:
layer.erase_cell(cell)
for pair in covers:
var sprite: Sprite2D = pair[1]
if sprite != null:
add_child(sprite)
sprite.global_position = base.to_global(base.map_to_local(pair[0]))
func _tile_layers() -> Array:
var out: Array = []
for child in get_children():
if child is TileMapLayer:
out.append(child)
return out
## 借用正下方最近一块实心墙的贴图,做成一个完全没有碰撞的 Sprite2D
func _make_cover(cell: Vector2i) -> Sprite2D:
var found := Vector2i(-1, -1)
for dy in range(1, 6):
for layer in _tile_layers():
var probe: Vector2i = cell + Vector2i(0, dy)
var source_id: int = layer.get_cell_source_id(probe)
if source_id == -1:
continue
var coords: Vector2i = layer.get_cell_atlas_coords(probe)
var source := layer.tile_set.get_source(source_id) as TileSetAtlasSource
if source == null:
continue
var data: TileData = source.get_tile_data(coords, 0)
if data != null and data.get_collision_polygons_count(0) > 0:
found = coords
break
if found.x >= 0:
break
if found.x < 0:
return null
var atlas_texture := AtlasTexture.new()
atlas_texture.atlas = ATLAS
atlas_texture.region = Rect2(found.x * TILE, found.y * TILE, TILE, TILE)
var sprite := Sprite2D.new()
sprite.texture = atlas_texture
sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
sprite.z_index = cover_z_index
return sprite