好 那今天就是專案的收尾了
我先預告一下明天會把一些我從開始學習 Rust 之後陸續得到的學習資源
也就是套件庫 以及 教學 Blog
OK 我們繼續昨天的內容
昨天我們做出了能夠上下左右改變方向的玩家
那麼其實如果要改變位置只要改一小段昨天的代碼改就好了
那今天要做的是 讓箭頭消失 和 記分板
首先先講 讓箭頭消失好了 這個比較簡單
一樣 我就只講一個方向 因為大同小異
fn despawns_monster_up(
mut commands: Commands,
mut arrow_positions: Query<(Entity, &mut Transform, &UpArrow), Without<crate::characters::Main>>,
character: Query<(Entity, &Transform, &crate::characters::Main), Without<UpArrow>>,
mut score: ResMut<ScoreBoard>,
){
let (_entity, transform, _character) = character.single().expect("");
let path = transform.rotation.w;
for (entity, transform, _arrow) in arrow_positions.iter_mut() {
let posx = transform.translation.x;
let posy = transform.translation.y;
if -100. <= posy && posy <= 0. && path == (-0.70710677)
{
score.add_score();
commands.entity(entity).despawn();
}
if posy >= 0. && posx == 0. {
commands.entity(entity).despawn();
}
}
}
可以看到說 我引入了他的角色跟箭頭
因為我們需要角色的轉角跟箭頭的位置
而之中可以看到我們抓了 rotation.w 這個是我在 Character 的 movement 裡面測出來的
if key_input.just_pressed(KeyCode::W) {
transform.rotation = Quat::from_rotation_z(0.5 * PI);
println!("{}", transform.rotation);
}
後面三個方向也是
那麼當轉向的時候就會輸出這些
之後再去看官方的 docs 就能得到角度了
而中間 path 不是使用 PI * -0.5
是因為會有浮點數誤差 所以就改成以輸出的數值為主
然後我是設定說 當到原點時 消失 當方向一致 然後物件在下方 100. 的位置時 消失並且加分
那麼中間那行 add_score 就是計分板的部份了
這邊我定義出了
pub struct ScoreBoard {
score: usize,
}
impl ScoreBoard {
pub fn add_score(&mut self) {
self.score += 1;
}
pub fn get_score(&self) -> usize {
self.score
}
}
上面是記分板的功能
獲取分數跟增加分數
當然 讀者也能自行增加
那麼下面這邊比較複雜
pub fn score_ui(
mut commands: Commands,
asset_server: ResMut<AssetServer>,
mut color_materials: ResMut<Assets<ColorMaterial>>,)
{
let font: Handle<Font> = asset_server.load("font.ttf");
let material = color_materials.add(Color::NONE.into());
commands
.spawn_bundle(NodeBundle {
style: Style {
position_type: PositionType::Absolute,
position: Rect {
left: Val::Px(10.),
top: Val::Px(10.),
..Default::default()
},
..Default::default()
},
material: material.clone(),
..Default::default()
})
.with_children(|parent| {
parent
.spawn_bundle(TextBundle {
text: Text::with_section(
"Score: 0",
TextStyle {
font_size: 40.0,
font: font.clone(),
color: Color::rgb(0.9, 0.9, 0.9),
},
Default::default(),
),
..Default::default()
})
.insert(ScoreText);
});
}
因為我們要做出整個 UI 界面
所以我們要定義出 這個 UI 的位置 然後字體之類等等
而上方的設定是位於左上角
字體是我隨便在 Google 上抓的
然後可以看到說 下面的 text 是我們要的輸出 而 Score: 0 是預設值
pub struct ScoreText;
pub fn update_score_text(score: Res<ScoreBoard>, mut query: Query<(&mut Text, &ScoreText)>) {
if !score.is_changed() {
return;
}
for (mut text, _marker) in query.iter_mut() {
text.sections[0].value = format!(
"Score: {}",
score.get_score(),
);
}
}
那 ScoreText 我定義在下面
而這個 function 的用途就是確認有沒有更動 如果有就去找他現在的值
最後就是初始化的部份了
fn main() {
App::build()
.insert_resource(WindowDescriptor {
title: "owo!".to_string(),
width: 800.,
height: 600.,
..Default::default()
})
.insert_resource(ClearColor(Color::rgb(1., 0.4, 0.4)))
.init_resource::<score::ScoreBoard>()
.add_startup_stage("game_setup", SystemStage::single(characters::spawn_main.system()).with_system(score::score_ui.system()))
.add_startup_system(setup.system())
.add_plugins(DefaultPlugins)
.add_plugin(characters::CharacterPlugin)
//.add_plugin(score::UI)
.add_plugin(arrow::ArrowsPlugin)
.add_system(score::update_score_text.system())
.run();
}
我的 main 函數長這樣
那麼可以看到除了之前的 character 的 Plugin 還有 Arrow 的 Plugin 以外
.init_resource::<score::ScoreBoard>()
.add_startup_stage("game_setup", SystemStage::single(characters::spawn_main.system()).with_system(score::score_ui.system()))
這行格外的重要
這是讓他的資源去進行初始化,且在同一時機
game_setup 是我自己取的 沒什麼重要性
最後成品會長這樣
Source
OK 剩下一天
各位晚安