0Pricing
Learn Rust Coding · Pelajaran

Menangani Masukan dan Waktu

Tanggapi pemain dan waktu.

Menangani Masukan dan Waktu adalah pelajaran Learn Rust Coding gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Learn Rust Coding, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Learn Rust Coding mencakup 4 pelajaran total.

Input sebagai Resource

Status papan ketik berada dalam resource ButtonInput<KeyCode>, yang disediakan oleh DefaultPlugins.

Mintalah resource tersebut hanya untuk dibaca dengan Res. Bevy memperbaruinya pada setiap frame sebelum sistem Anda berjalan, sehingga Anda selalu melihat status terkini.

fn read_keys(keys: Res<ButtonInput<KeyCode>>) {
    if keys.pressed(KeyCode::Space) {
        info!("space held");
    }
}

pressed vs just_pressed

pressed bernilai true pada setiap frame saat tombol ditahan — ideal untuk pergerakan berkelanjutan. just_pressed hanya bernilai true pada frame ketika tombol mulai ditekan.

Gunakan just_pressed untuk tindakan diskret seperti melompat atau menembak agar satu ketukan hanya memicu satu kali.

fn jump(keys: Res<ButtonInput<KeyCode>>) {
    if keys.just_pressed(KeyCode::ArrowUp) {
        info!("jump!");
    }
}

Membangun Vektor Arah

Gabungkan beberapa tombol menjadi arah pergerakan. Mulailah dari nol, lalu tambahkan satu unit pada setiap sumbu untuk setiap tombol yang ditekan.

Normalisasi hasilnya agar pergerakan diagonal tidak lebih cepat daripada pergerakan lurus.

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()
}

Resource Waktu

Kecepatan frame berbeda-beda pada setiap mesin, jadi jangan pernah bergerak berdasarkan jumlah tetap per frame. Resource Time menyediakan delta_secs(), yaitu jumlah detik sejak frame terakhir.

Mengalikan kecepatan dengan delta membuat pergerakan tidak bergantung pada kecepatan frame.

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;
    }
}

Menggabungkan Input dan Waktu

Pola sebenarnya menggabungkan kedua sumber daya dalam satu sistem: baca arah dari input, lalu kalikan dengan kecepatan dan delta.

Dengan demikian, kontrol menjadi mulus dan konsisten, baik permainan berjalan pada 30 maupun 144 frame per detik.

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);
    }
}

Tombol Mouse

Tombol mouse menggunakan API ButtonInput yang sama, dengan MouseButton sebagai pengganti KeyCode.

Konsistensi ini berarti kebiasaan menggunakan pressed dan just_pressed yang Anda bangun untuk papan ketik dapat langsung diterapkan pada klik.

fn shoot(buttons: Res<ButtonInput<MouseButton>>) {
    if buttons.just_pressed(MouseButton::Left) {
        info!("fire");
    }
}

Timer untuk Cooldown

Timer melacak waktu yang telah berlalu menuju durasi target. Lakukan tick dengan delta frame pada setiap pembaruan.

Gunakan timer berulang untuk mengatur jeda penembakan dan periksa just_finished() untuk mengetahui kapan harus bertindak.

#[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"); }
    }
}

Membuat Timer

Buat timer dari durasi dan TimerMode. Once berhenti setelah menembak; Repeating mengatur ulang dirinya secara otomatis.

Simpan timer pada komponen agar setiap entitas, seperti menara, memiliki jeda penembakannya sendiri yang independen.

use std::time::Duration;

commands.spawn((
    Turret,
    Cooldown(Timer::new(Duration::from_millis(500), TimerMode::Repeating)),
));

FixedUpdate untuk Determinisme

Fisika dan kode jaringan sering memerlukan langkah waktu tetap. Sistem dalam jadwal FixedUpdate berjalan dalam jumlah tetap setiap detik, terlepas dari laju render.

Di dalamnya, gunakan Time<Fixed> yang delta-nya selalu sama sehingga simulasi dapat direproduksi.

App::new()
    .add_plugins(DefaultPlugins)
    .add_systems(FixedUpdate, physics_step)
    .run();

Waktu Berlalu vs Delta

time.delta_secs() adalah selang waktu sejak frame terakhir. time.elapsed_secs() adalah total waktu sejak mulai.

Waktu yang telah berlalu sangat cocok untuk animasi yang digerakkan gelombang sinus, seperti item yang bergerak naik-turun, dengan memasukkan total waktu ke dalam fungsi.

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;
    }
}

Membatasi pada Batas

Setelah bergerak, jaga pemain tetap di layar dengan membatasi transformasi di dalam setengah ukuran jendela.

f32::clamp membatasi setiap sumbu. Baca ukuran jendela dari kueri Window saat Anda memerlukan batas yang tepat.

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);
    }
}

Pemeriksaan Cepat

Pertimbangkan kemandirian dari laju frame.

Rangkuman: Input dan Waktu

Input berada dalam sumber daya ButtonInput; gunakan pressed untuk tindakan yang ditahan dan just_pressed untuk ketukan. Sumber daya Time dan komponen Timer menjaga pergerakan dan cooldown tetap independen dari laju frame.

Setelah kontrol tersedia, pelajaran terakhir menambahkan tabrakan dan transisi status permainan.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Menangani Masukan dan Waktu” gratis?

Ya — teks lengkap “Menangani Masukan dan Waktu” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Learn Rust Coding, upgrade ke CoddyKit PRO. Kursus Learn Rust Coding mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Menangani Masukan dan Waktu”?

Tanggapi pemain dan waktu. Kamu berlatih Learn Rust Coding dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Learn Rust Coding?

Tidak diperlukan pengalaman sebelumnya. Learn Rust Coding di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Menangani Masukan dan Waktu” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Learn Rust Coding ini?

Ya. Setiap pelajaran Learn Rust Coding menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Pola Pikir ECS
  2. Membuat dan Memindahkan Entitas
  3. Menangani Masukan dan Waktu
  4. Tabrakan dan Keadaan Gim
← Kembali ke Learn Rust Coding