จัดการข้อมูลนำเข้าและเวลา
ตอบสนองต่อผู้เล่นและนาฬิกา
จัดการข้อมูลนำเข้าและเวลา เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน
อินพุตในฐานะทรัพยากร
สถานะแป้นพิมพ์อยู่ในทรัพยากร ButtonInput<KeyCode> ซึ่งจัดเตรียมโดย DefaultPlugins
ขอการเข้าถึงแบบอ่านอย่างเดียวด้วย Res Bevy จะอัปเดตทรัพยากรนี้ในแต่ละเฟรมก่อนที่ระบบของคุณจะทำงาน คุณจึงเห็นสถานะปัจจุบันอยู่เสมอ
fn read_keys(keys: Res<ButtonInput<KeyCode>>) {
if keys.pressed(KeyCode::Space) {
info!("space held");
}
}pressed กับ just_pressed
pressed เป็นจริงทุกเฟรมที่กดปุ่มค้างไว้ จึงเหมาะกับการเคลื่อนที่ต่อเนื่อง ส่วน just_pressed เป็นจริงเฉพาะเฟรมที่ปุ่มถูกกดลง
ใช้ just_pressed กับการกระทำที่เกิดเป็นครั้ง ๆ เช่น การกระโดดหรือการยิง เพื่อให้การแตะปุ่มหนึ่งครั้งทำงานเพียงครั้งเดียว
fn jump(keys: Res<ButtonInput<KeyCode>>) {
if keys.just_pressed(KeyCode::ArrowUp) {
info!("jump!");
}
}การสร้างเวกเตอร์ทิศทาง
รวมปุ่มหลายปุ่มเข้าด้วยกันเพื่อสร้างทิศทางการเคลื่อนที่ เริ่มจากศูนย์ แล้วเพิ่มค่าหนึ่งหน่วยในแต่ละแกนสำหรับปุ่มที่ถูกกด
ทำให้ผลลัพธ์เป็นเวกเตอร์หน่วย เพื่อป้องกันไม่ให้การเคลื่อนที่แนวทแยงเร็วกว่าแนวตรง
fn direction(keys: Res<ButtonInput<KeyCode>>) -> Vec2 {
let mut d = Vec2::ZERO;
if keys.pressed(KeyCode::KeyW) { d.y += 1.0; }
if keys.pressed(KeyCode::KeyS) { d.y -= 1.0; }
if keys.pressed(KeyCode::KeyA) { d.x -= 1.0; }
if keys.pressed(KeyCode::KeyD) { d.x += 1.0; }
d.normalize_or_zero()
}ทรัพยากรเวลา
อัตราเฟรมแตกต่างกันไปตามเครื่อง ดังนั้นอย่าเคลื่อนที่ด้วยจำนวนคงที่ต่อเฟรม ทรัพยากร Time ให้ค่า delta_secs() ซึ่งคือจำนวนวินาทีตั้งแต่เฟรมก่อนหน้า
การคูณความเร็วด้วยค่า delta ทำให้การเคลื่อนที่ไม่ขึ้นกับอัตราเฟรม
fn move_player(time: Res<Time>, mut q: Query<&mut Transform, With<Player>>) {
let dt = time.delta_secs();
for mut tf in &mut q {
tf.translation.x += 200.0 * dt;
}
}การรวมอินพุตกับเวลา
รูปแบบที่ถูกต้องคือรวมทรัพยากรทั้งสองไว้ในระบบเดียว: อ่านทิศทางจากอินพุต แล้วคูณด้วยความเร็วและ delta
วิธีนี้ทำให้การควบคุมราบรื่นและสม่ำเสมอ ไม่ว่าเกมจะทำงานที่ 30 หรือ 144 เฟรมต่อวินาทีก็ตาม
fn drive(
keys: Res<ButtonInput<KeyCode>>,
time: Res<Time>,
mut q: Query<&mut Transform, With<Player>>,
) {
let mut d = Vec2::ZERO;
if keys.pressed(KeyCode::KeyA) { d.x -= 1.0; }
if keys.pressed(KeyCode::KeyD) { d.x += 1.0; }
let step = d.normalize_or_zero() * 300.0 * time.delta_secs();
for mut tf in &mut q {
tf.translation += step.extend(0.0);
}
}ปุ่มเมาส์
ปุ่มเมาส์ใช้ API ButtonInput เดียวกัน โดยใช้ MouseButton แทน KeyCode
ความสอดคล้องนี้ทำให้แนวทางการใช้ pressed และ just_pressed ที่คุณเรียนรู้จากแป้นพิมพ์ นำมาใช้กับการคลิกได้โดยตรง
fn shoot(buttons: Res<ButtonInput<MouseButton>>) {
if buttons.just_pressed(MouseButton::Left) {
info!("fire");
}
}ตัวจับเวลาสำหรับช่วงหน่วงเวลา
Timer ใช้ติดตามเวลาที่ผ่านไปจนถึงระยะเวลาที่กำหนด ให้เพิ่มค่าเวลาโดยใช้ delta ของเฟรมในการอัปเดตแต่ละครั้ง
ใช้ตัวจับเวลาแบบทำซ้ำเพื่อกำหนดจังหวะการยิง และตรวจสอบ just_finished() เพื่อดูว่าถึงเวลาทำงานแล้วหรือไม่
#[derive(Component)]
struct Cooldown(Timer);
fn tick(time: Res<Time>, mut q: Query<&mut Cooldown>) {
for mut cd in &mut q {
cd.0.tick(time.delta());
if cd.0.just_finished() { info!("ready"); }
}
}การสร้าง Timer
สร้างตัวจับเวลาจากระยะเวลาและ TimerMode โดย Once จะหยุดหลังทำงานครั้งแรก ส่วน Repeating จะเริ่มนับใหม่โดยอัตโนมัติ
เก็บตัวจับเวลาไว้ในคอมโพเนนต์ เพื่อให้แต่ละเอนทิตี เช่น ป้อมปืน มีจังหวะการทำงานของตนเองอย่างเป็นอิสระ
use std::time::Duration;
commands.spawn((
Turret,
Cooldown(Timer::new(Duration::from_millis(500), TimerMode::Repeating)),
));FixedUpdate เพื่อความเป็นกำหนดแน่นอน
ฟิสิกส์และระบบเครือข่ายมักต้องใช้ช่วงเวลาคงที่ ระบบในกำหนดการ FixedUpdate จะทำงานด้วยจำนวนครั้งต่อวินาทีที่คงที่ ไม่ว่าอัตราการเรนเดอร์จะเป็นเท่าใด
ภายในระบบเหล่านี้ ให้ใช้ Time<Fixed> ซึ่งมี delta เท่ากันเสมอ ทำให้การจำลองได้ผลลัพธ์ซ้ำเดิม
App::new()
.add_plugins(DefaultPlugins)
.add_systems(FixedUpdate, physics_step)
.run();เวลาที่ผ่านไปกับ delta
time.delta_secs() คือช่วงเวลาตั้งแต่เฟรมก่อนหน้า ส่วน time.elapsed_secs() คือเวลารวมตั้งแต่เริ่มต้นโปรแกรม
เวลาที่ผ่านไปเหมาะอย่างยิ่งสำหรับแอนิเมชันที่ขับเคลื่อนด้วยคลื่นไซน์ เช่น ไอเท็มที่ลอยขึ้นลง โดยป้อนเวลารวมเข้าไปในฟังก์ชัน
fn bob(time: Res<Time>, mut q: Query<&mut Transform, With<Pickup>>) {
let t = time.elapsed_secs();
for mut tf in &mut q {
tf.translation.y = (t * 2.0).sin() * 10.0;
}
}จำกัดค่าให้อยู่ในขอบเขต
หลังจากเคลื่อนที่แล้ว ให้ผู้เล่นอยู่ภายในหน้าจอด้วยการจำกัดค่า transform ให้อยู่ภายในระยะครึ่งหนึ่งของขนาดหน้าต่าง
f32::clamp จะจำกัดค่าในแต่ละแกน อ่านขนาดหน้าต่างจากคิวรี Window เมื่อต้องการขอบเขตที่แน่นอน
fn clamp(mut q: Query<&mut Transform, With<Player>>) {
for mut tf in &mut q {
tf.translation.x = tf.translation.x.clamp(-300.0, 300.0);
tf.translation.y = tf.translation.y.clamp(-200.0, 200.0);
}
}ตรวจสอบความเข้าใจอย่างรวดเร็ว
ลองพิจารณาการทำงานที่ไม่ขึ้นกับอัตราเฟรม
ทบทวน: อินพุตและเวลา
อินพุตอยู่ในทรัพยากร ButtonInput ให้ใช้ pressed สำหรับการทำงานที่กดค้าง และใช้ just_pressed สำหรับการกดครั้งเดียว ทรัพยากร Time และคอมโพเนนต์ Timer ช่วยให้การเคลื่อนที่และช่วงหน่วงเวลาไม่ขึ้นกับอัตราเฟรม
เมื่อการควบคุมพร้อมแล้ว บทเรียนสุดท้ายจะเพิ่มการชนและการเปลี่ยนสถานะของเกม
คำถามที่พบบ่อย
บทเรียน “จัดการข้อมูลนำเข้าและเวลา” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “จัดการข้อมูลนำเข้าและเวลา” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “จัดการข้อมูลนำเข้าและเวลา”
ตอบสนองต่อผู้เล่นและนาฬิกา คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “จัดการข้อมูลนำเข้าและเวลา” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม
ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- แนวคิดแบบ ECS
- สร้างและเคลื่อนย้ายเอนทิตี
- จัดการข้อมูลนำเข้าและเวลา
- การชนและสถานะเกม