Уроки · 53
Спутник
В уроке «Вращение» разобрались, как крутить вектор
вокруг нуля — angle.cos() и angle.sin() дают его направление, а
рост angle каждый кадр заставляет его вращаться. Применим это на
деле — сделаем маленький кружок, вращающийся вокруг большого, как
спутник вокруг планеты. Разница только в одном: направление теперь
нужно не просто нарисовать из нуля, а прибавить к центру — тем же
приёмом сложения, что и в уроке «Точка плюс вектор», —
тогда вращаться будет вокруг центра, а не вокруг нуля.
// Точка — как в уроке «Точка и прямоугольник».struct Point { x: f32, y: f32,}
// Точка на окружности радиусом radius вокруг center, под углом angle.fn orbit(center: Point, radius: f32, angle: f32) -> Point { // Единичный вектор — направление длиной 1, вычисленное прямо из угла. let direction_x = angle.cos(); let direction_y = angle.sin();
// Растягиваем направление до длины radius и прибавляем к center — // тот же приём сложения, что и в «Точке плюс вектор». Point { x: center.x + direction_x * radius, y: center.y + direction_y * radius, }}Попробуй сам
Заголовок раздела «Попробуй сам»Маленький кружок вращается вокруг большого с постоянной угловой
скоростью. Поменяй speed ниже:
use macroquad::prelude::*;
// Точка — как в уроке «Точка и прямоугольник».struct Point { x: f32, y: f32,}
// Точка на окружности радиусом radius вокруг center, под углом angle.fn orbit(center: Point, radius: f32, angle: f32) -> Point { // Единичный вектор — направление длиной 1, вычисленное прямо из угла. let direction_x = angle.cos(); let direction_y = angle.sin();
// Растягиваем направление до длины radius и прибавляем к центру — // получаем точку на самой окружности (тот же приём сложения, что и // в уроке «Смещение»). Point { x: center.x + direction_x * radius, y: center.y + direction_y * radius, }}
// speed одна и та же на каждом кадре, поэтому это константа (как в// уроке «Константы»), а не переменная внутри loop.const SPEED: f32 = 0.020;
#[macroquad::main("Спутник")]async fn main() { // Угол растёт каждый кадр — mut и вне loop, чтобы помнить прошлый кадр. let mut angle: f32 = 0.0;
loop { clear_background(BLACK);
let center = Point { x: screen_width() / 2.0, y: screen_height() / 2.0 };
// Большой кружок в центре — «планета». draw_circle(center.x, center.y, 40.0, DARKBLUE);
// Маленький кружок на орбите вокруг центра. let point = orbit(center, 150.0, angle); draw_circle(point.x, point.y, 16.0, YELLOW);
// Угол растёт на фиксированную угловую скорость каждый кадр. angle += SPEED;
next_frame().await; }}Что здесь происходит
Заголовок раздела «Что здесь происходит»orbit(center, radius, angle)— считает точку на окружности в два шага: сперва направление(direction_x, direction_y)вокруг нуля, затем растягивает его доradiusи прибавляетcenter— то же сложение, что и в уроке «Смещение».angleрастёт на фиксированную величину каждый кадр —mutи внеloop, ровно как позиция в уроке «Погоня за мышью».- Из-за перевёрнутой оси
y(как в уроке «Координаты») вращение на экране идёт по часовой стрелке. speedв коде —const SPEED, а не переменная внутриloop: значение одно и то же на каждом кадре, пока ты сам его не изменишь, поэтому это константа, как в уроке «Константы».