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

Уроки · 27

Отрезок мышью

В уроке «Клик мышью» мы уже пользовались is_mouse_button_down — она проверяет, зажата ли кнопка прямо сейчас, на каждом кадре. Но у мыши есть ещё два момента, у каждого своя функция:

  • is_mouse_button_pressed — истина только в тот самый кадр, когда кнопку только что нажали.
  • is_mouse_button_released — истина только в тот кадр, когда кнопку только что отпустили.

В отличие от is_mouse_button_down, которая истинна на каждом кадре пока кнопка зажата, эти две срабатывают ровно один раз — в момент самого события.

Замени содержимое src/main.rs на это:

src/main.rs
use macroquad::prelude::*;
#[macroquad::main("Отрезок мышью")]
async fn main() {
// Начальные точки — обе в центре, отрезок нулевой длины.
let mut start_x = screen_width() / 2.0;
let mut start_y = screen_height() / 2.0;
let mut end_x = start_x;
let mut end_y = start_y;
loop {
clear_background(BLACK);
let (mouse_x, mouse_y) = mouse_position();
// Истина только в тот кадр, когда кнопку только что нажали —
// обновляем первую точку.
if is_mouse_button_pressed(MouseButton::Left) {
start_x = mouse_x;
start_y = mouse_y;
}
// Истина, пока левая кнопка мыши зажата — обновляем вторую точку.
if is_mouse_button_down(MouseButton::Left) {
end_x = mouse_x;
end_y = mouse_y;
}
// is_mouse_button_released() тоже есть — истина в тот кадр,
// когда кнопку отпустили. Отдельно она здесь не нужна: как
// только is_mouse_button_down() станет false, end перестанет
// обновляться сам собой.
draw_line(start_x, start_y, end_x, end_y, 4.0, YELLOW);
draw_circle(start_x, start_y, 10.0, WHITE);
draw_circle(end_x, end_y, 10.0, WHITE);
next_frame().await;
}
}

Запусти как обычно:

Окно терминала
cargo run

Нажми левую кнопку мыши где угодно на демке — первая точка встанет туда и останется на месте. Веди мышь, не отпуская кнопку — вторая точка следует за курсором, отрезок тянется следом. Отпусти кнопку — вторая точка замирает там, где была в этот момент. Нажми снова в другом месте — отрезок начнётся заново:

  • is_mouse_button_pressed срабатывает один раз, в кадр нажатия — этим моментом мы ставим первую точку и больше её не трогаем.
  • is_mouse_button_down срабатывает на каждом кадре, пока кнопка зажата — этим мы двигаем вторую точку следом за курсором.
  • Отдельная проверка на отпускание не нужна: как только is_mouse_button_down перестаёт быть истиной, if с ней просто не выполняется, и end_x/end_y перестают меняться сами собой — вторая точка застывает на месте.
  • Новое нажатие снова делает is_mouse_button_pressed истинной на один кадр — первая точка переставляется, и всё начинается заново.