繼續把隨機資源做更完整的互動流程,也就是開寶箱的環節。開寶箱就像抽盲盒一樣,同一個寶箱可能放補給道具,但也有可能是偽裝成寶箱的敵人(芙莉蓮應該最了解)。當玩家按下空白鍵後,究竟是賺到一瓶藥水,還是被寶箱怪追著跑,這是本篇預計要完成的功能。
預計達成的目標:
首先一樣需要新增圖片的資源,放進 /assets/items/chests
中,分別有四張圖片。
個別代表的是未開啟、開啟中、已開啟,跟偽裝的寶箱怪。
核心邏輯寫在 new_demo/src/systems/chest.rs
,主要拆成三段:
spawn_random_chests
會掃描所有 RoomTile
,挑選地板與戶外地板,隨機挑出四個位置產生 Chest
Component。內容物以 25% 機率是 Mimic,否則就是隨機道具。commands.spawn((
Chest::new(contents),
Sprite::from_image(asset_server.load("items/chests/chest_closed.png")),
Transform::from_translation(Vec3::new(base_position.x, base_position.y, CHEST_Z))
.with_scale(Vec3::splat(CHEST_SCALE)),
Name::new("Chest"),
));
input_system
會先搜尋距離玩家最近的關閉寶箱,只要小於 CHEST_INTERACTION_RADIUS
就送出 ChestInteractionEvent
,比門或攻擊的優先還要高。if let Some((entity, _)) = nearest_chest {
chest_events.write(ChestInteractionEvent { chest: entity });
return;
}
chest_interaction_system
依內容物分兩路:
chest_open.png
、加掛 ChestItemReveal
計時器,並生成一個子節點 sprite。chest_mimic.png
、轉成 Enemy + Mimic
,直接進入追擊狀態。道具寶箱的視覺與效果由 chest_item_reveal_system
控制:
ChestItemReveal
,timer 結束後觸發 apply_pickup_effect
,補血、回耐力、解除中毒都走同一支函式。commands.entity(child).despawn()
清掉。CHEST_ITEM_DISPLAY_SCALE
從 2.2 調整成 1.25,避免覆蓋整個寶箱。let item_visual = commands
.spawn((
ChestItemVisual,
Sprite::from_image(asset_server.load(sprite_path)),
Transform::from_translation(Vec3::new(0.0, CHEST_ITEM_DISPLAY_OFFSET, 0.1))
.with_scale(Vec3::splat(CHEST_ITEM_DISPLAY_SCALE)),
))
.id();
玩家不需要額外去按任何鍵,計時器跑完就立即套用效果並換上 chest_empty.png
,同一個寶箱不會再次觸發。
寶箱怪走的是敵人管線:
ChestContents::Mimic
被開啟時,會把原本的寶箱 entity 加上 Enemy
, Mimic
, Health
, Attack
, EnemyPatrol
, EnemyAlert
等 component,初始狀態直接設為 Chasing
。EnemyPlugin
新增 mimic_ai_system
,重用原本的 process_enemy_ai
,讓 Mimic 追擊玩家但仍遵守觸發/牽制半徑。enemy_contact_attack_system
的查詢條件改為同時處理 Slime 與 Mimic,玩家若靠太近就會吃到 CHEST_MIMIC_ATTACK
的傷害,Log 也會顯示「寶箱怪攻擊造成 X 傷害」。for (attacker_transform, mut attack, attack_stat, _is_slime, is_mimic) in &mut attacker_query {
if distance <= attack.radius && attack.cooldown.finished() {
let attacker_name = if is_mimic.is_some() { "寶箱怪" } else { "史萊姆" };
info!(
"{}攻擊造成 {} 傷害,玩家剩餘 HP: {}",
attacker_name, damage, health.current
);
}
}
這樣的安排有兩個好處:
constants.rs
,之後要調整平衡只要改數值。開啟寶箱流程
與寶箱怪戰鬥
目前隨機擺放的寶箱讓房間探索更有期待感,多了一些樂趣在場上,另外也有偽裝的寶箱怪會隨機出現在場上,這也增加了一些不安定的要素,讓玩家在開寶箱的同時也不只是只有好處。
之後想要嘗試的部分,可能可以在寶箱上方放提示圖示,來提醒玩家這個房間還有未開的寶箱。
今日程式碼同步至 repo