Уроки · 80
if как значение
Давай сделаем так, чтобы ветки if не рисовали, а только выбирали
цвет. В уроке «Радиус обнаружения» турель рисовалась в
каждой ветке отдельно:
if player_distance < RADIUS { // Игрок внутри радиуса — красная турель. draw_circle(center_x, center_y, 40.0, RED);} else { // Игрок снаружи — синяя турель. draw_circle(center_x, center_y, 40.0, BLUE);}Ветки отличаются только цветом, а остальное в них повторяется. Давай выберем цвет один раз, а нарисуем после.
if выдаёт значение
Заголовок раздела «if выдаёт значение»if с else целиком можно считать значением: какая ветка сработала,
то и получится. Это значение можно положить в переменную:
// Ветки выбирают цвет. Что выбрала сработавшая, то и попадёт в color.let color = if player_distance < RADIUS { RED } else { BLUE };
// Рисуем один раз, цветом из переменной.draw_circle(center_x, center_y, 40.0, color);Мы уже видели такое в уроке «Свои функции»: там if с
else стоял последним в функции, и то, что выбрала ветка, функция
отдавала наружу. Здесь то же самое, только результат уходит не из
функции, а в переменную color.
Три правила
Заголовок раздела «Три правила»- В обеих ветках значения одного типа:
REDиBLUEоба цвета. Цвет в одной ветке и число в другой не получится. - В конце ветки точку с запятой не ставим. Если поставить, ветка ничего не отдаст.
elseобязателен. Без него не сказано, что отдавать, когда условие неверно.
Одно решение — несколько мест
Заголовок раздела «Одно решение — несколько мест»Выгода не только в том, что код короче. Выбранный цвет можно
использовать сколько угодно раз, не повторяя условие. В демо ниже
color красит и турель, и контур радиуса: решение принято один раз, а
работает в двух местах.
Попробуй сам
Заголовок раздела «Попробуй сам»Белый кружок под курсором — игрок. Заведи его внутрь контура: и турель, и контур покраснеют разом, потому что цвет выбран один раз. Меняй радиус ниже:
use macroquad::prelude::*;
// Радиус один и тот же на каждом кадре, поэтому это константа// (как в уроке «Константы»), а не переменная внутри loop.const RADIUS: f32 = 300.0;
// Своя функция: расстояние между двумя точками, как в уроке «Расстояние».fn distance(from_x: f32, from_y: f32, to_x: f32, to_y: f32) -> f32 { let dx = to_x - from_x; let dy = to_y - from_y; (dx * dx + dy * dy).sqrt()}
#[macroquad::main("if как значение")]async fn main() { loop { clear_background(BLACK);
// Центр экрана — здесь же стоит турель. let center_x = screen_width() / 2.0; let center_y = screen_height() / 2.0;
// Координаты курсора. let (mouse_x, mouse_y) = mouse_position();
// Расстояние от турели до курсора. let player_distance = distance(center_x, center_y, mouse_x, mouse_y);
// if с else выдаёт значение: что выбрала сработавшая ветка, то и // попадёт в color. Игрок внутри радиуса — красный, иначе синий. // После RED и BLUE точку с запятой не ставим. let color = if player_distance < RADIUS { RED } else { BLUE };
// Контур — радиус обнаружения, того же цвета, что и турель. draw_circle_lines(center_x, center_y, RADIUS, 3.0, color);
// Турель. draw_circle(center_x, center_y, 40.0, color);
// Игрок — кружок под курсором. draw_circle(mouse_x, mouse_y, 25.0, WHITE);
next_frame().await; }}Что здесь происходит
Заголовок раздела «Что здесь происходит»let color = if player_distance < RADIUS { RED } else { BLUE };—ifсelseвыдаёт значение. Сработала первая ветка, и вcolorпопадаетRED, сработала вторая, иBLUE.distance— своя функция расстояния между двумя точками, как в уроке «Расстояние», только вынесенная изmain, как в уроке «Свои функции». Результат записан вplayer_distance.REDиBLUEстоят в ветках без точки с запятой: так ветка отдаёт значение наружу.colorиспользуется дважды: для контура радиуса и для самой турели. Условие при этом проверено только один раз.ifкак значение работает не только для цветов, но и для любых значений: чисел, координат, чего угодно, лишь бы в обеих ветках был один и тот же тип.