iT邦幫忙

2025 iThome 鐵人賽

DAY 12
0

dead demo

現在玩家血量歸零只會在 log 看到死亡訊息,畫面不會有任何反饋,也沒有真正回到起點。所以這篇預計要把整個死亡 — 重生的流程補齊,順便讓敵人也會重置,體驗終於像個 Rogue-lite 了。

這次的改動分成三個部分:

  • 透過事件驅動的死亡偵測與計時資源,統一掌控死亡狀態
  • 顯示類似 Elden Ring「YOU DIED」的訊息,並鎖住玩家操作
  • 在計時結束後復活玩家並重生或重置所有敵人

事件驅動的死亡狀態

health_system 現在會將血量歸零的玩家標記成 PlayerDead 並送出 PlayerDiedEvent,接著 start_player_death_sequence_system 會抽掉傷害殘影、鎖定輸入,並啟動 PlayerDeathState 內的計時器:

// src/systems/health.rs
if health.current <= 0 && dead_marker.is_none() {
    commands.entity(entity).insert(PlayerDead);
    death_events.write(PlayerDiedEvent);
}

// 啟動死亡計時
death_state.start(PLAYER_DEATH_DISPLAY_SECONDS);

所有控制輸入、移動與攻擊的系統都改成查詢 Without<PlayerDead>,只要角色處於死亡狀態就完全不能動作,讓死亡演出期間保持一致的體驗。

Elden Ring 風格死亡疊圖

我在 assets/fonts 補了一份 NotoSans-Regular.ttf,並在 constants.rs 放入相關常數。新系統 spawn_player_death_screen 會監聽 PlayerDiedEvent,生成全螢幕遮罩與紅色文字,直到 PlayerRespawnedEvent 才移除:

// src/systems/ui.rs
commands
    .spawn((DeathScreenRoot, Node { /*...*/ }, BackgroundColor(overlay_color)))
    .with_children(|parent| {
        parent.spawn((
            DeathScreenText,
            Text::new(PLAYER_DEATH_MESSAGE),
            TextFont { font: font_handle.clone(), font_size: PLAYER_DEATH_FONT_SIZE, ..Default::default() },
            TextColor(text_color),
        ));
    });

這段疊圖被掛進 UiPluginUpdate 排程,確保死亡當幀就出現提示,並於 PostUpdate 監聽復活事件清理畫面。

重生點與敵人重置

計時器跑完後,player_respawn_system 會把玩家傳回房間入口(沿用 EntranceLocation 資源),恢復滿血並移除 PlayerDead 標記。這時也廣播 PlayerRespawnedEvent,讓敵人可以同步重置:

// src/systems/health.rs
transform.translation = spawn_position;
health.current = health.max;
commands.entity(entity).remove::<PlayerDead>();
respawn_events.write(PlayerRespawnedEvent);

reset_enemies_on_player_respawn 會掃描所有敵人,還原血量、AI 狀態、冷卻,並移除淡出效果;如果場上已經沒有史萊姆或獨眼巨人,還會透過共用的 spawn_*_internal 重新生成。為了避免與敵人查詢衝突,地板查詢都改成 Query<(&Transform, &RoomTile), Without<Enemy>>

// src/systems/enemy.rs
if slime_entities.iter().next().is_none() {
    spawn_slime_internal(&mut commands, asset_server.as_ref(), &floor_query);
}
if cyclops_entities.iter().next().is_none() {
    spawn_cyclops_internal(&mut commands, asset_server.as_ref(), &floor_query);
}

這樣玩家復活後戰鬥場景就會重新整理,避免敵人殘留在死亡位置或整個房間空掉。

dead demo

小結

目前的遊戲進度算是可以讓玩家有一個處罰的機制,必須要小心的操作,才能避免生命值被扣光。這裡可以再做的更好的地方有加上音效這類加深體驗的功能,預計之後會有幫這個遊戲加上音效的功能。

今天的程式碼分享在 repo


上一篇
玩家近戰攻擊命中與門的互動優化
下一篇
增加角色屬性數值
系列文
Bevy Rogue-lite 勇者冒險篇 × Rust 遊戲開發筆記18
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言