Уроки · 83
Свой цвет
Давай соберём цвет сами, а не возьмём готовый. До сих пор мы брали
цвета-константы вроде RED и GREEN, как в уроке
«Разноцветные кружки», а в уроке
«else if» выбирали из трёх таких цветов. Способов
создать свой цвет в macroquad несколько, мы разберём один.
Color::new
Заголовок раздела «Color::new»Свой цвет собирает Color::new. Ему нужно четыре числа от 0.0 до
1.0: сколько в цвете красного, зелёного и синего, а четвёртое число
— непрозрачность. С ней пока всё просто: 1.0 значит «полностью
непрозрачный», так и пишем.
// Красный, зелёный, синий и непрозрачность. Красный и зелёный вместе// дают жёлтый.let yellow = Color::new(1.0, 1.0, 0.0, 1.0);Несколько примеров, чтобы почувствовать, как цвета смешиваются:
Color::new(1.0, 0.0, 0.0, 1.0)— красный.Color::new(0.0, 1.0, 0.0, 1.0)— зелёный.Color::new(1.0, 1.0, 0.0, 1.0)— жёлтый: красный и зелёный вместе.Color::new(0.0, 0.0, 0.0, 1.0)— чёрный, аColor::new(1.0, 1.0, 1.0, 1.0)— белый.
Если число меньше 0, функция считает его за 0, а если больше 1, то за
- Так она работает. Например,
Color::new(5.0, 0.0, 0.0, 1.0)даст тот же красный, что иColor::new(1.0, 0.0, 0.0, 1.0).
Цвет по здоровью
Заголовок раздела «Цвет по здоровью»Теперь покрасим полоску из урока «Полоска здоровья»
не ступеньками, а плавно. Возьмём долю здоровья fraction от 0 до 1,
как в уроке «Доля от 0 до 1». Чем здоровья меньше, тем
больше красного. Чем больше, тем больше зелёного:
// Красного столько, сколько здоровья не хватает, зелёного — сколько осталось.let color = Color::new(1.0 - fraction, fraction, 0.0, 1.0);Здоровье полное: fraction равно 1.0, красного 0.0, зелёного
1.0, получается чисто зелёный. Здоровья нет: красного 1.0, зелёного
0.0, получается чисто красный. А посередине красного и зелёного по
0.5, и цвет выходит тусклым.
Чтобы жёлтый был ярким
Заголовок раздела «Чтобы жёлтый был ярким»Давай сделаем так, чтобы на середине оба цвета были на полную. Для этого удвоим оба числа:
// Умножаем на 2: всё, что больше 1.0, функция считает за 1.0.let color = Color::new(2.0 * (1.0 - fraction), 2.0 * fraction, 0.0, 1.0);При половине здоровья красного получается 2.0 * 0.5, то есть 1.0, и
зелёного тоже 1.0: ярко-жёлтый. При полном здоровье зелёного
получается 2.0, но функция считает его за 1.0, поэтому полоска всё
так же чисто зелёная. Лишнее обрезается само, считать это не нужно.
Между зелёным и жёлтым получается светло-зелёный, между жёлтым и красным — оранжевый.
Попробуй сам
Заголовок раздела «Попробуй сам»Кликай по примеру: каждый клик отнимает здоровье, и цвет полоски меняется вместе с ним. Когда здоровье кончится, следующий клик вернёт его полностью. Меняй урон за клик, чтобы цвет менялся мельче или крупнее:
use macroquad::prelude::*;
// Здоровье в начале и его максимум.const MAX_HEALTH: f32 = 100.0;// Сколько здоровья отнимает один клик.const DAMAGE: f32 = 10.0;
// Левый верхний угол полоски, её высота и длина.const BAR_X: f32 = 20.0;const BAR_Y: f32 = 20.0;const BAR_HEIGHT: f32 = 40.0;const BAR_WIDTH: f32 = 400.0;
#[macroquad::main("Свой цвет")]async fn main() { // Текущее здоровье — сначала полное. let mut health = MAX_HEALTH;
loop { clear_background(BLACK);
// Кнопка мыши только что нажата. if is_mouse_button_pressed(MouseButton::Left) { if health <= 0.0 { // Здоровья уже нет — возвращаем полное. health = MAX_HEALTH; } else { // Отнимаем урон. max(0.0) не даёт здоровью уйти ниже нуля. health = (health - DAMAGE).max(0.0); } }
// Доля здоровья от 0 до 1. let fraction = health / MAX_HEALTH;
// Свой цвет: красного тем больше, чем меньше здоровья, а зелёного // тем больше, чем здоровья больше. Умножаем на 2: числа больше 1.0 // функция считает за 1.0, поэтому посередине оба цвета на максимуме // и получается ярко-жёлтый. let color = Color::new(2.0 * (1.0 - fraction), 2.0 * fraction, 0.0, 1.0);
// Серая подложка: вся полоска целиком. draw_rectangle(BAR_X, BAR_Y, BAR_WIDTH, BAR_HEIGHT, GRAY); // Цветная часть поверх неё: ширина — доля от всей полоски. draw_rectangle(BAR_X, BAR_Y, BAR_WIDTH * fraction, BAR_HEIGHT, color);
next_frame().await; }}Что здесь происходит
Заголовок раздела «Что здесь происходит»Color::new(r, g, b, a)собирает свой цвет из четырёх чисел от0.0до1.0: красный, зелёный, синий и непрозрачность.- Непрозрачность
1.0значит «полностью непрозрачный». Пока пишем её именно так. - Число меньше 0 функция считает за 0, а больше 1 за 1.
1.0 - fractionрастёт, когда здоровье падает, и даёт красный.fractionрастёт вместе со здоровьем и даёт зелёный.- Умножение на 2 делает середину ярко-жёлтой, потому что лишнее обрезается.
- Цвет теперь считается формулой, а не выбирается через
if, поэтому меняется плавно. damage— сколько здоровья отнимает клик. Чем он меньше, тем плавнее меняется цвет.