C++ Builder :: Игрописательство :: Как написать игру за 21 день ?

Главная

Введение

ЛИКБЕЗ
C++ Builder


ЛИКБЕЗ
C++

Глава №1
Глава №2
Глава №3
Глава №4
Глава №5
Глава №6

Исходники
к пособию

Мои исходники

Статьи
&
Книги


Гостевая

Ссылки

About

E-mail

Rambler's Top100


Создай игру на C++Builder за 21 день - Глава №2 (Черновой вариант)
 

Глава №2.

Вот наконец то добрался и до написания второй главы. Сегодня речь пойдет о мышке. Точнее о работе с ней. Управление стрелочками, конечно, это хорошая идея, но не для стратегии. Представьте себе, как бы вы играли в такую классическую игру как Warcraft 2 без мышки. Не получается? Вот так мы и пришли к выводу, что мышка нам просто жизненно необходима.

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

Но начнем все же с мышки. Предположим, что у нас на карте стоит несколько человек. Как узнать какого чувака мы выбрали? По координатам щелка мыши.

У большинства объектов в Билдере есть событие OnMouseDown, а в свою очередь у него есть параметры X,Y , которые и являются координатами клика, также там есть параметр Button, который определяет кнопку мышки, которую вы нажали (левая, правая, средняя).

Допустим у вас есть карта 20х20 с размером клетки 30х30 точек, для простоты возьмем размер чувака также 30х30.

Берем координату, делим на 30, округляем и умножаем на 30. К примеру: кликнули в точке (63, 92) получили координаты (60,90). Проверяем координаты чела, если они такие же, то он становится активным и вы можете его двигать мышкой.

Введем еще также переменную selected, которая присваивается true в случае, если кликнули на него и false, если не на него. В FormRepaint’е определяем прорисовку обводки в случае, когда selected==true.

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

void __factcall Form1MouseDown (X,Y, Button)
{
i f(Button==mbLeft)
{
xx=int(X/30)*30;
yy=int(Y/30)*30;

if(x==xx && y==yy)
selected=true;
else
selected=false;
}
else
{
xx=int(X/30)*30;
yy=int(Y/30)*30;
if(selected)
{ x=xx; y=yy; }
}
}

Введем второго чувака - соответственно вместо одной переменной selected будут две переменные selected1 и selected2.Вместо x и y будут x1, x2 и y1,y2. Причем теперь, потребуется проверять активность чуваков и оставлять активным только одного.

А если ввести третьего, то это будет просто малый геморрой. Поэтому нам потребуется познакомиться с классами и ввести массив, состоящий из объектов. По сути класс - это обобщенная модель однотипных объектов, в которой выделены присущие только им свойства и методы. В этом примере мы введем модель чувака со свойствами X,Y и selected. Дело в том, что в будущем не составит труда добавить сюда же например свойства: сила, выносливость, ловкость, здоровье, патроны … и.т.п.

В этом преимущества классовой модели. Теперь вы поняли, что нам нужен массив объектов. Напишем CHUVAK chuvaki[3]; (класс называется CHUVAK).

А выглядит само объявление класса вот так:

class Chuvak
{
public : // обратить внимание !!! часто забывают прописать public
Chuvak(); // конструктор
~Chuvak(); // деструктор
bool selected; // выделен или нет
int type; // тип
int x1,y1; // координаты начала движения
int x2,y2; // координаты конца движения
int live; // жизни (здоровье или очки или что-то в этом роде)
int boolean_path[20][20];
MyThread *SecondThread; // поток ходьбы
void run_thread(void); // запуск потока
bool create_thread(void); // создание потока
void calc_path(int a[20][20],int h[20][20]); // расчет кратчайшего пути
void draw(TCanvas *Canvas); // отрисовка
};

Теперь обратится к ним можно так:

Chuvaki[1].X=10; // присваивает 2-му челу координату по X’у = 10.

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

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

////////////////////////////////////////////////////////////////////

Потом проверим в цикле всех чубриков на координаты (60, 90). Если такой нашелся, то делаем его активным (у активного чувака рисуется обводка).

Скачать исходник ….

Теперь займемся поиском пути. Когда стен нет, все понятно – двигаемся по гипотенузе т.е по кратчайшему расстоянию:

Из (A;B) в (C;D):

float K=(C-A)/(D-B);
If(K<0) { K=-K; }

K – отношение между сторонами прямоугольника.

А само движение выглядит примерно так:

for(float f=A; f<C; f++)
{
f or(float g=B; g<D; g+=K)
{
Sleep (100);
}
}
Как же мы поступим, если на пути стоят стены. Вы можете очень долго ломать голову, пытаясь написать это, поэтому я дам вам небольшую подсказку. Есть несколько методов поиска пути. Один из самых простых и в тоже время действенных – волновой метод. Суть этого метода состоит в том, что всем клеткам на карте присваиваются значения от меньшего к большему (меньшее – начальная точка).

А линия пути строится от конечной точки к начальной по уменьшению. Т.е если идешь от большего к меньшему, всегда попадешь в начальную точку.

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

Скачать наглядный пример (Пример №8)

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

 

 

 
 
Hosted by uCoz