Уроки · 89
Пауза
Давай сделаем паузу: нажал клавишу, и всё замерло, нажал ещё раз, и движение продолжилось с того же места. Нам понадобится одна переменная и одна новая функция.
Нажата или зажата
Заголовок раздела «Нажата или зажата»В уроке «Ввод с клавиатуры» мы проверяли клавишу через
is_key_down. Она верна на каждом кадре, пока клавиша зажата. Для
паузы это не подходит: человек держит клавишу долю секунды, но за это
время проходит несколько кадров, и пауза бы то включалась, то
выключалась.
Нам нужна другая функция, is_key_pressed. Она верна только на одном
кадре, в момент нажатия. С мышью мы уже так делали: там
is_mouse_button_down и is_mouse_button_pressed, как в уроке
«Автоматический огонь». С клавишами всё устроено так
же:
// Клавишу P только что нажали.if is_key_pressed(KeyCode::P) { // Включаем или выключаем паузу. paused = !paused;}Переключатель
Заголовок раздела «Переключатель»paused — переменная типа bool: true, когда игра на паузе, и
false, когда нет. Запись paused = !paused переворачивает её значение.
! мы видели в уроке «Порядок отрисовки»: он меняет
true на false, а false на true. Нажали P один раз, и пауза
включилась. Нажали второй раз, и выключилась.
Что останавливается
Заголовок раздела «Что останавливается»Паузе нужно остановить движение, а рисование оставить как есть.
Поэтому всё, что двигает круг, лежит внутри if !paused { ... }:
// Круг двигается, только пока игра не на паузе.if !paused { x += SPEED * dt;}Рисуем мы всё равно на каждом кадре, поэтому круг остаётся на экране. А
dt каждый кадр считается заново из времени последнего кадра, поэтому
после паузы круг продолжает ровно с того места, где остановился, и не
прыгает вперёд.
Замени содержимое src/main.rs на это:
use macroquad::prelude::*;
// Скорость круга в пикселях в секунду.const SPEED: f32 = 300.0;
#[macroquad::main("Пауза")]async fn main() { // Где сейчас круг по горизонтали. let mut x: f32 = 0.0; // Игра сейчас на паузе? Сначала нет. let mut paused = false;
loop { clear_background(BLACK);
// dt (delta time) — сколько секунд прошло между прошлым кадром и этим. let dt = get_frame_time();
// Клавишу P только что нажали — включаем или выключаем паузу. if is_key_pressed(KeyCode::P) { paused = !paused; }
// Круг двигается, только пока игра не на паузе. if !paused { // Шаг за кадр — скорость, умноженная на dt. x += SPEED * dt; // Круг ушёл за правый край — возвращаем к левому. if x > screen_width() { x = 0.0; } }
// Рисуем круг на каждом кадре, даже на паузе. draw_circle(x, screen_height() / 2.0, 40.0, YELLOW);
// На паузе пишем об этом в углу. if paused { draw_text("Pause", 30.0, 110.0, 100.0, WHITE); }
next_frame().await; }}Запусти как обычно:
cargo runНажимай P, и круг будет то останавливаться, то снова бежать. Сначала кликни по чёрной области, чтобы нажатия клавиш доходили до неё, как сказано в уроке «Как читать уроки». Попробуй прямо здесь:
Что здесь происходит
Заголовок раздела «Что здесь происходит»is_key_pressed(KeyCode::P)верна один кадр, в момент нажатия. Аis_key_downверна, пока клавиша зажата.paused— этоbool:true, когда игра на паузе. Объявлена она доloop, чтобы помнить своё значение от кадра к кадру.paused = !pausedкаждым нажатием переворачивает значение на противоположное.if !paused { ... }пропускает движение, пока включена пауза. Рисуется всё по-прежнему на каждом кадре.if paused { draw_text(...) }пишет «Pause» только на паузе. Подпись английская, потому что шрифт по умолчанию не знает русских букв.