|
Программирование >> Рекурсивные объекты и фрактальные узоры
с-*- - мастер-класс. 85 нетривиальных проектов, решений и задач 2.2.3. Бильярд Расчёт траекторий шаров после столкновения Требуется реализовать игру в бильярд по правилам программы Video Pool (рис. 2.2). В начале игры на столе располагается пирамида из шести шаров и один бьющий шар. Игроку даётся пять попыток для того, чтобы загнать один из шаров пирамиды в любую лузу. После этого количество попыток снова возрастает до пяти, а игрок получает бонус в размере НомерУровня х Но-мерШара х ЦенаЛузы очков (игра начинается с первого уровня). Управление ударом сводится к заданию скорости и направления бьющего шара; реализовывать дополнительные возможности вроде подкрутки шара не требуется. Если игрок случайно загнал в лузу бьющий шар, либо не попал ни по одному нумерованному шару, либо израсходовал безрезультатно все пять попыток, у него отнимается одна жизнь , и ход переходит к оппоненту. Каждому участнику в начале игры даётся всего три жизни . При переходе на следующий уровень игрок премируется допшшительной жизнью . Участник, исчерпавший все жизни , выбывает из игры. Как только все шесть нумерованных шаров оказываются в лузах, игра переходит на следующий уровень, на котором игрокам даётся уже не по пять, а всего по четыре попытки.
Рис 2.2. Игра Video Pool Глава 2. Решение математических задач Игра заканчивается после прохождения всех пяти уровней (на пятом уровне у каждого из игроков есть лишь одна попытка для того, чтобы провести шар в лузу), либо после исчерпания лимита жизней всеми игроками. Победителем объявляется игрок, набравший большее количество очков. Подсказка Основная сложность при написании бильярда - расчёт скоростей и траекторий шаров после соударения. Для центрального столкновения эта проблема уже была решена (см. п. 2.2.2 Столкновение ), здесь же ситуация и проще, и сложнее одновременно. Проще потому, что массы шаров теперь одинаковы, с/южнее потому, что кроме результирующих скоростей придётся определять и результирующие траектории. Сразу замечу ещё одно отличие. В модели Столкновение потери энергии при движении считались нулевыми, поэтому моделирование прекращалось лишь по требованию пользователя. В бильярде движение каждого шара рано или поздно должно прекратиться. Мне кажется разумным просто умножать на очередной итерации моделирования скорость каждого из шаров на какую-либо константу меньше единицы. Как только скорость становится совсем небольшой, шар считается остановившимся. Займёмся теперь расчётом траекторий. Предположим, произошло столкновение (рис. 2.3). Пусть в момент удара первый шар находится в точке (X Y,) и движется под углом Aj к оси абсцисс. Скорость первого шара равна V,. Соответственно, второй шар располагается в точке (Х, траектория его движения задана углом Aj. Скорость второго шара равна Vj. Рис 23. Оюма столкновения билыщных шаров Остаётся лишь повернуть оси координат в обратном направлении: А1 += alpha; А2 += alpha; На этом вся математика заканчивается, можно садиться и писать бильярд. 2.2.4. Баллистическая игра Расчёт траекторий снарядов В случайных (но достаточно удалённых друг от друга) точках случайным образом сгенерированной холмистой поверхности расположены две пушки, принадлежащие двум игрокам. Игроки ходят по очереди. С помощью курсорных клавиш игрок определяет угол наклона ствола и силу выстрела. При нажатии клавиши Enter происходит выстрел. Снаряд летит по параболе, определяемой углом и силой. Если снаряд сталкивается с поверхностью, происходит взрыв, и вся земля в радиусе R от места столкновения заменяется пустым пространством. Цель каждого игрока - поразить противника, то есть сделать так, чтобы противник оказался не далее чем в R пикселях от места взрыва, после чего игра заканчивается. Если не ошибаюсь, первой игрой этого жанра была Scorched Earth. Подсказка Для генерации поверхности можно соединить плавной линией несколько точек на экране, выбранных случайным образом (см. задачу 2.1). Чтобы организовать движение снаряда по параболе, можно воспользоваться следующим методом. Пусть изначально снаряд находится в точке (X, У) и летит по экрану с горизонтальной скоростью VX и вертикальной скоростью VY: Введём новый параметр - g (ускорение свободного падения). Если скорость измеряется в пикселях за итерацию моделирования, то разумное значение для g может варыфоваться примерто от 0.5 до 3. Теперь движение снаряда описывается псевдокодом: обрабртаЗ? текущую ситуахдию Y - Д +VY , Первым делом необходимо определить угол наклона а прямой, соединяющей центры шаров (обозначим её т): double alpha = atan2(Y2 - Yl, X2 - Xl) ; Теперь повернём систему координат таким образом, чтобы ось абсцисс стала параллельна прямой т, а ось ординат - параллельна перпендикуляру к т. Для этого нужно всего лишь вычесть а из углов, определяющих направление даижения шаров: А1 -= alpha; А2 -= alpha; Скорость каждого шара раскладывается на две составляющие: радиальную (скорость движения вдоль прямой т) и тангенциальную (скорость движения вдоль перпендикуляра к т). При ударе тангенциальная составляющая скорости каждого шара не меняется, а для радиальной работают законы сохранения энергии и импульса, в точности как в задаче Столкновение . Если подставить в формулы задачи Столкновение одно и то же значение массы для обоих шаров, станет видно, что при соударении просто происходит обмен скоростями. В нашем случае это означает обмен радиальными составляющими скоростей. Поскольку оси координат направлены вдоль прямой т и перпендикуляра к т, составляющие скоростей определяются просто как проекции на оси: double VX1 = Vl*cos(Al), VYl = Vl*sin(Al); double VX2 = V2*cos(A2), VY2 = V2*sin(A2); Телерь можно поменять местами радиальные составляющие скоростей: std: : swap (VXl, VX2) ; Поскольку одна из составляющих скорости каждого шара изменилась, не-обзодимо пересчитать значения и VI = sqrt (VXl*VX1 .+ VY1*VY1); V2 = sqrt(VX2*VX2 + VY2*VY2) ; Новые значения углов A, и можно определить с помопц>ю арктангенсов (так же, как мы вычисляли угол а). Нужно только помнить о том, что шар может вовсе не двигаться. В этом случае обе составляющие скорости равны нулю, и функция atan2 () завершится аварийно: double ALMOST ZERO = 0.0001; почти нуль А1 = VI < ALMOST ZERO ? О : atan2(VYl, VXl); А2 = V2 < AIiMOST ZERO ? О : atan2(VY2, VX2) ; Лис 2.4. Игра DefMctor PC Смысл игры в том, чтобы, управляя зеркалами (то есть вращая их), разбить сначала лазером все серые шары, а затем установить контакт с приёмником. На скриншоте приёмник находится прямо под лазером; его передняя сторона закрыта кирпичами, пока остаются неразбитые шары. Решение По большей части эта задача, конечно же, математическая, однако одной только математикой здесь не обойтись. Сначала рассмотрим общую идею решения, затем разберём каждый требующий того элемент по отдельности. Первая проблема связана с окончанием работы алгоритма. Дело в том, что лдзер может вообще не покинуть пределов экрана (вариант с выходом луча за экран как раз прост для анализа), бесконечно отражаясь от образующих замкнутый многоугольник зеркал. Выйти из затруднения можно двумя способами. Во-первых, вполне разумно ограничить анализируемое число отражений. Если спустя N отражений лазер всё ещё не покинул пределы экрана, выполнение алгоритма следует прекратить. Во-вторых (и мы воспользуемся этим способом) можно запрограммировать пошаговый алгоритм. На главной форме приложения располагаются две кнопки. Первая отвечает за инициализацию программы, вторая вызывает процедуру черчения очередного отражения луча. Таким образом, пользователь сам сможет определять количество отображенных на экране отражений. Поскольку инициализация и поиск очередного отражения - процедуры независимые, можно уже сейчас начать разработку программы. На главной форме F Main располагаются две кнопки BInitialize (инициализация) и B Step (вывод очередного отражения луча), а также поле MInitialize типа ТМето. В нём будет храниться информация о конфигурации лазера и зеркал. Например, шесть строк 20 700 60 440 310 135 50 450 520 15 150 240 320 35 150 540 120 35 150 340 120 35 150 указывают, что лазер находится в точке (20, 700) экрана и наклонён под углом в 60°. Следующие строки задают параметры зеркал (Х,, Y, угол наклона, длина). Определим типы данных TLaser и TMirror, описывающие лазерный луч и зеркало соответственно: Здесь предполагается, что сопротивление среды снаряду несущественно (поэтому горизонтальная составляющая скорости не меняется). 2.2.5. Лабиринт для лазера Угол падения равен углу отражения Вот еще одна задача на моделирование траекторий, но уже не физического тела, а луча. Пусть в точке (Хс, Yc) экрана находится лазерная пушка. Её направление (отклонение от оси абсцисс) задано углом а. Кроме того, задано множество отрезков, символизирующих плоские зеркала, каждое из которых отражает с обеих сторон. Каждый отрезок описывается точкой (Х, Y) его центра, длиной Lj, и углом поворота относительно оси абсцисс. Требуется отобразить на экране путь, проделанный лазером. Луч отражается от зеркал согласно правилу угол падения равен углу отражения . Объединив решение Лабиринта для лазера с формулами для задачи Бильярд , можно разработать игру в бильярд на столе в форме произвольного многоугольника с различными (также многоугольными) препятствиями. Но можно также развить идею и написать компьютерную игру в стиле Deflektor (рис. 2.4).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |