Перейти к содержимому

Уроки · 25

Точная остановка

В уроке «Погоня за мышью» кружок мог трястись рядом с курсором: шаг всегда был длиной SPEED, даже если до курсора оставалось меньше. Кружок проскакивал мимо, разворачивался — и так по кругу.

Чинится это одной строкой: шаг не должен быть больше, чем осталось пройти. Если distance меньше SPEED — идём ровно на distance, не дальше:

// Шаг не больше, чем осталось — не проскакиваем мимо цели.
let step = SPEED.min(distance);

SPEED.min(distance) берёт меньшее из двух чисел: пока курсор далеко, distance больше SPEED, и шаг остаётся прежним. А как только курсор оказывается ближе, чем SPEED, в дело вступает distance — последний шаг довозит кружок точно до курсора и на этом останавливается.

Тот же кружок, что и в уроке «Погоня за мышью», но теперь он точно останавливается на курсоре, а не трясётся рядом с ним. Останови мышь и присмотрись к последним шагам:

src/main.rs
use macroquad::prelude::*;
// Скорость одна и та же на каждом кадре, поэтому это константа
// (как в уроке «Константы»), а не переменная внутри loop.
const SPEED: f32 = 8.0;
#[macroquad::main("Точная остановка")]
async fn main() {
// Кружок стартует в центре экрана.
let mut x = screen_width() / 2.0;
let mut y = screen_height() / 2.0;
loop {
clear_background(BLACK);
// Координаты курсора.
let (mouse_x, mouse_y) = mouse_position();
// Вектор от кружка к курсору.
let dx = mouse_x - x;
let dy = mouse_y - y;
let distance = (dx * dx + dy * dy).sqrt();
// Курсор не точно на кружке — есть куда шагать.
if distance > 0.0 {
// Направление на курсор, длиной ровно 1.
let direction_x = dx / distance;
let direction_y = dy / distance;
// Шаг не больше, чем осталось — не проскакиваем мимо цели.
let step = SPEED.min(distance);
x += direction_x * step;
y += direction_y * step;
}
draw_circle(x, y, 30.0, YELLOW);
next_frame().await;
}
}
  • SPEED — та же константа, что и в уроке «Погоня за мышью»: скорость одна и та же на каждом кадре, поэтому это const вне main, как в уроке «Константы».
  • Вдали от курсора SPEED.min(distance) равно SPEED — кружок бежит с той же скоростью, что и раньше.
  • Рядом с курсором SPEED.min(distance) равно distance — шаг укорачивается ровно настолько, чтобы долететь до цели и не перелететь.
  • Курсор не двигается — кружок доходит до него и замирает, а не дрожит на месте, как в уроке «Погоня за мышью».