用 Rust 開發遊戲 - 4 跳躍
在《用 Rust 開發遊戲 - 3 地面和重力》部分我們添加了重力和碰撞檢測。這一部分將實現如何跳躍。
跳躍基礎
我們將從定義跳躍組件開始,這個組件集中了所有跳躍邏輯。
struct Jumper {
jump_impulse: f32,
}
在 spawn_player 方法中,我們將把這個新組件添加到玩家中:
.insert(Jumper { jump_impulse: 10. });
然後我們將添加一個玩家跳躍系統並將其註冊到我們的應用程序中:
// In main, register a player movement system
.add_system(player_jumps.system())
// Define a player movement system
fn player_jumps(
keyboard_input: Res<Input<KeyCode>>,
mut players: Query<(&Jumper, &mut RigidBodyVelocity), With<Player>>
) {
for (jumper, mut velocity) in players.iter_mut() {
if keyboard_input.pressed(KeyCode::Up) {
velocity.linvel = Vec2::new(0., jumper.jump_impulse).into();
}
}
}
keyboard_input: Res<Input> 參數檢測我們按下的鍵。
mut players: Query<(&Jumper, &mut RigidBodyVelocity), With> 參數返回所有帶有 Jumper, RigidBodyVelocity 和 Player 組件的實體。
該方法中的代碼將玩家的向上速度設置爲 Jumper 組件上定義的 jump_impulse。
如果你運行 cargo run,並按下向上鍵,你應該看到我們的玩家上升,然後下降,直到到達地面。
禁用多個跳躍
在我們當前的代碼中,如果你一直按上鍵,玩家就會一直往上走,直到鬆開爲止。我們需要一種方法去阻止玩家在空中時跳躍。
一種方法是給 Jumper 組件添加一個 is_jumping 布爾屬性。
struct Jumper {
jump_impulse: f32,
is_jumping: bool
}
// ...
.insert(Jumper { jump_impulse: 10., is_jumping: false })
然後,只有當布爾值爲 false 時,我們才允許跳躍,當玩家在空中時,我們將該值設爲 true。
fn player_jumps(
keyboard_input: Res<Input<KeyCode>>,
mut players: Query<(&mut Jumper, &mut RigidBodyVelocity), With<Player>>
) {
for (mut jumper, mut velocity) in players.iter_mut() {
if keyboard_input.pressed(KeyCode::Up) && !jumper.is_jumping {
velocity.linvel = Vec2::new(0., jumper.jump_impulse).into();
jumper.is_jumping = true
}
}
}
如果你運行應用程序,玩家在空中就不能再跳。唯一的問題是它只能跳一次……
當玩家停止跳躍的時候,我們需要一種重置 is_jumping 標誌的方法。
重置標誌
爲了做到這一點,Rapier 擁有一個事件系統,即當兩個實體發生接觸時便會觸發事件。我們將利用它重置我們的標誌。
添加一個新的 jump_reset 系統,並在我們的應用程序中註冊它:
// In main
.add_system(jump_reset.system())
// ...
pub fn jump_reset(
mut query: Query<(Entity, &mut Jumper)>,
mut contact_events: EventReader<ContactEvent>,
) {
for contact_event in contact_events.iter() {
for (entity, mut jumper) in query.iter_mut() {
set_jumping_false_if_touching_floor(entity, &mut jumper, contact_event);
}
}
}
fn set_jumping_false_if_touching_floor(entity: Entity, jumper: &mut Jumper, event: &ContactEvent) {
if let ContactEvent::Started(h1, h2) = event {
if h1.entity() == entity || h2.entity() == entity {
jumper.is_jumping = false
}
}
}
這個系統檢索所有跳躍組件和所有發生的接觸事件。然後,它會查看其中一個接觸事件是否涉及給定的跳躍者。如果是這樣,它將 Jumper 的 is_jump 設置爲 false。
如果我們想要實現這一點,我們就需要激活玩家碰撞器的接觸事件:
flags: ColliderFlags {
active_events: ActiveEvents::CONTACT_EVENTS,
..Default::default()
},
運行 cargo run ,按下鍵盤上的 up 鍵。我們的玩家不能再雙跳了,它可以在觸地後重新跳躍。
本文翻譯自:
https://dev.to/sbelzile/making-games-in-rust-part-4-jumps-2jne
coding 到燈火闌珊 專注於技術分享,包括 Rust、Golang、分佈式架構、雲原生等。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/gI6pMW4zBHOfpwkK0LJcdA