Программирование >>  Рекурсивные объекты и фрактальные узоры 

1 ... 18 19 20 [ 21 ] 22 23 24 ... 43


for(int i = 0; i < 300; i++) {

TurtleCG + ToString(len) + TlO ); len += 0.1;

Идея черепашьей графики восходит, по крайней мере, к языку LOGO (1966 г.). Позже аналогичные возможности были добавлены в популярные версии Бейсика. Сейчас черепаший подход нередко используют, например, при вычерчивании фрактальных изображений.

Теперь осталось реализовать функцию Turtle (). Основная программа должна предоставлять возможность пользователю вводить строку на черепашьем языке и чертить соответствующий рисунок на экране. Все чис-легпшхе аргументы можно считать целыми.

5.3. КОСМИЧЕСКАЯ ДУЭЛЬ, ИЛИ ПРОВОЛОЧНАЯ ГРАФИКА В ДЕЙСТВИИ

Итак, нужно запрограммировать игру для двух человек Space Duel. Суть игры заключается в следующем: в замкнутом пространстве (рис. 5.2) летают два вооружённых космических корабля. Управление каждым кораблём осуществляется с помощью пяти клавиш: поворот влево, поворот вправо, ускорение, торможение и выстрел. Изначально корабли находятся на случайных (но непересекающихся) позициях.

Корабль, достигающий края экрана, отражается от него, сохраняя скорость. Угол падения равен углу отражения. Цель игры - выстрелом поразить корабль соперника.

Рис. 5.2. Игра Space Duel


Если хорошо подумать, можно, конечно, и здесь обойтись функциями вывода точек и отрезков, однако можно и упростить себе задачу, если изменить взгляд на саму идеологию рисования на экране.

Представьте себе, что точке (О, 0) экрана находится так называемая черепашка (при работе с черепашкой обычно считают началом координат левый нижний угол экрана, ось ординат направлена вверх). Эта черепашка умеет ползать по экрану, и по первому вашему требованию направится, куда ни пожелаете. Кроме того, у неё в лапках есть карандаш, которым она может отмечать свой путь.

Единого стандарта черепашьего языка пс существует, но мы вполне можем ограничиться следуюп1ими командами:

и - поднять карандаш, перейдя в режим простого движения (не оставлять за собой следа);

D - опустить карандаш, перейдя в режим рисования;

Gn - пройти вперёд (по направлению движения) п пикселей;

Та - повернуться на угол а градусов (ссли угол положительный, то влево, иначе вправо).

Изначально для черепашки установлен режим простого движения, смотрит она строго вверх.

В качестве простого примера программы на черепашьем языке можно привести процедуру рисования прямоугольника размером 100 х 50 пикселей:

DG50T-90G100T-90G50T-90G100

Если предположить, что функция Turtle () выполняет строку команд на черепашьем языке , то спираль, изображённая на рисунке слева, будет нарисована в результате выполнения довольно простой программы на С++:

вспомогательная функция преобразования числа в строку

std::string ToString(int х)

std::ostringstream stream;

stream x;

return stream.str();

void main() {

перевести черепашку ближе к центру экрана Turtle( T-50G300D ); double len = 1;



Программа должна загружать уровень из файла, а затем передавать упрай-ление пользователю. В случае победы выводится соответствующее сообщение. Должна быть также предусмотрена возможность начать игру заново, если играющий понимает, что он попал в безвыходное положение.

Дополнительное задание. Попробуйте написать программу, которая решает уровни Сокобана автоматически.

Подсказка

Идеологически решение головоломки Сокобан похоже на игру в 15 (п. 4.3.1), поэтому я советую воспользоваться эвристическим поиском А*. Правда, изобрести хорошую эвристику для данной игры гораздо труднее. Насколько мне 1звестно, идеально работающего алгоритма ещё йе изобретено.

Непростая работа для А*

Требуется написать классическую игру Сокобан (что по-японски означает кладовщик ). Цель игры - растолкать ящики по отмеченным на уровне позициям. Уровень условно состоит из клеток, каждая из которых либо пуста, либо содержит непроходимую стену (рис. 5.3). Перемещения по уровню также дискретные: за один ход герой едвигается на одну клетку в любую из четырёх сторон.

Ящики можно лишь толкать (таким образом, затолкав ящик в угол, его не удастся оттуда вытащить). Два (или более) подряд стоящих ящика с места не столкнуть (слишком тяжело). На рис. 5:3 один из шести ящиков (в правой части) уже находится в целевой позиции.


MOUE

0063

PUSH

0015

TIME 0204 LEU: 01

5.5. ВИЗУАЛИЗАЦИЯ ПРОСТОГО ТРЕХМЕРНОГО МИРА

Трехмерный лабиринт

Пусть у нас имеется лабиринт, заданный прямоугольной матрицей из нулей и единиц (как в п. 3.2.1). Нуль означает стену, единица - проход (рис.3.2). Стартовой локацией лабиринта снова считается верхний левый угол, финишной - нижний правый. На сей раз автоматически решать лабиринт не требуется. Вместо этого предлагается написать игру трёхмерный лабиринт , позволяющую блуждать по лабиринту игроку-человеку.

Программа рисует на экране текущую локацию так, как её видит путешественник (рис. 5.4).


Рис 5.3. Mqta Sokt)ban

Рис. 5.4. Вид лабиринта изнутри

Пока выпущенный игроком снаряд находится в полёте, следующий выстрел сделать нельзя (иначе игра превратится в сплоышой обстрел).

Игроку, поразившему соперника, засчитывается одно очко. Если корабли столкнулись между собой, оба корабля взрываются, очки никому не присуждаются. Взорвавшийся корабль возникает в случайном месте экрана (но, естественно, не поверх корабля соперника). Игра заканчивается, как только один из соперников наберёт пять очков.

Корабли проще всего нарисовать с помощью отрезков прямых. Можно выбрать более простые формы, чем изображены на рисунке. Для движения и поворота кораблей используйте функции из п. 2.1.3 Проволочная графика .

5.4. ЭВРИСТИЧЕСКИЙ ПОИСК И СОКОБАН




Рис 5.5. Внешний вид приложения Трехмерный лабиринт

Большую часть формы занимает трёхмерное изображение лабиринта. Вверху расположено поле тМето, содержащее карту лабиринта с отмеченной текущей позицией путешественника. Нулями обозначаются стены, единицами - проходы. Обозначение текущей позиции зависит от направления движения:

- вверх

V - вниз

< - влево

> - вправо

С алгоритмической точки зрения программа не представляет собой ничего сложного, но технические нюансы имеются.

Я предполагаю, что создано приложение с главной формой Main Form, на которой расположен занимающий всю форму элемент DrawingArea типа TImage (на него будет производиться весь графический вывод), а также элемент MazeMap типа ТМето (карта лабиринта). В свойствах Мето-поля лучпге установить какой-либо мононшринный шрифт (например. Courier New), чтобы ширина карты была одной и той же для каждой горизонтали. Кроме того, карта должна быть доступна только для чтения (свойство Readonly).

Основным элементом лабиринта является боковая стена (рис. 5.6).

начатхо стены

OuterH


InnerH

FrontW

Рис 5.6. Боковая стена лабиринта

Движение путешественника управляется курсорными клавишами: (пово рот влево на 90°, поворот вправо на 90°, шаг на локацию вперёд, разворот на 180°). Если достигаута финишная локация, выводится сообщение о победе.

Необязательно реализовывать настоящую трёхмерную графику, поскольку здесь нет ни плавных поворотов, ни непрерывных движений. Достаточно выводить статичный чертёж текущей локации, а после любого действия игрока обновлять содержимое экрана (дискретно, без анимации).

Для простоты можно считать, что в лабиринте нет залов , то есть прямоугольных участков без степ размером 2x2 локации или больпге. Наличие залов порождает новые проблемы. Например, если путешественник видит прямо перед собой больигос помещение, в дальнем правом углу которого располагается одрга стена, эту стену придётся как-то изобразить на экране. Если же залов нет, программе достаточно начертить:

стену лабиринта прямо по курсу;

набор стен и проходов по левую руку;

набор стен и проходов по правую руку.

Таким образом, при вычерчивании текущего вида лабиринта вполне достаточно иззчить коридор до ближайшей стены по ходу движения и содержимое ближайших клеток слева и справа от коридора .

Решение

Перед тем, как приступить к разработке, мне кажется разумным показать скриншот готовой программы, чтобы создать представление о том, что мы в конечном итоге должны получить (рис. 5.5).



1 ... 18 19 20 [ 21 ] 22 23 24 ... 43

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика