Главная » 2D графика » Изометрия – 2,5 мерное пространство

RSS

Изометрия – 2,5 мерное пространство

Не нравитсяНравится   Рейтинг +6

Изометрия в играх

Сейчас, с появлением полностью 3х мерных технологий, этот способ представления игрового поля называется изометрический, а раньше он назывался 2,5 мерный. Но смысл остался один и тот же. Существует плоскость расположенная под неким углом к неподвижной камере. Эффект перемещения достигается скроллингом карты.

На рисунке показан вид сбоку, где
N – нормаль к поверхности пространства
a – угол обзора камеры.

Для начала стоит упомянуть где использовался этот способ представления : Diablo, Fallout, Gorky 17 ( хотя несколько видоизменено ). С примерами игр, я конечно могу и ошибаться.

Начнем с разработки спрайтов. В отличии от простого 2D представления, они имеют более сложную форму :

Размер выбирайте : … 64×32, 60×30 … 2×1. / В моем примере 60×30 /. Советую сделать спрайтов поверхности штук 30-40 на каждый тип ландшафта.

Наступило время все эти спрайты разместить. Для начала определимся, что карта хранится в массиве, а если точнее то в массиве хранятся индексы этих спрайтов. Сами спрайты будем хранить в TImageList. При написании, я использовал динамический массив составленный из списка. В примере это класс PTable и его описание находится в файле Table.pas. Там все просто:

1
2
3
Procedure Create(Const X,Y:integer);
Procedure Put(X,Y,Number:integer); - поместить в ячейку X,Y элемент Number
Function Get(X,Y:integer):integer; - получить

Первой процедурой создаем таблицу с размерами X,Y. На самом деле можно создавать только квадратные т.е. 2×2, 5×5, 100×100 … NxN. Если хотите сделать произвольного размера то надо вводить 2 списка, но мне кажется, что и квадратной формой можно обойтись. А далее, после создания, работаем как с обычным массивом.
C Table все, хотя я может кого то немножко и озадачил, но использовать массив ( Array ) для задания карт в играх не рекомендую. Причина простая. Допустим, уровни имеют разный размер (в Heroes от 64×63 – 256×256), а с массивом Вы сможете сделать только фиксированный – т.к. размер уровня узнается уже после задания массива. Вторая причина более важна : немножко изменив класс PTable, в нем можно хранить не только индексы спрайтов. Например в каждой ячейке сохраняется информация о :

  • ресурсах которые там находятся – количество леса, камня, руды …
  • степень проходимости для юнитов – по болоту медленнее, чем по дороге
  • высоту над уровнем моря и многое другое

В итоге данные карты хранятся в PTable и теперь все это надо сделать это вывести их на экран. Но это задача не так проста т.к. спрайты не прямоугольной формы и следовательно имеется смещение для нечетных столбцов:

Я решил эту проблему просто. Сначала проходим цикл для четных, потом для нечетных :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Procedure TIFlur.Draw(DestCanvas:TCanvas;SourceRect:TRect);
var
  I,J,dX,dY:integer;
begin
  // рисуем четные столбцы
  dx:=0;dy:=0;
for I:=SourceRect.Left to SourceRect.Left+SourceRect.Right do
begin
  For J:=SourceRect.Top to SourceRect.Top+SourceRect.Bottom do
  begin
    if Odd(I)=False then Resource.Draw(DestCanvas,dX,dY,Map.Get(I,J));
    Inc(dY,30);// !!!!!!!! SpriteHeigth !!!!!!!
  end;
dy:=0;
Inc(dX,30);// !!!!!! SpriteWidth div 2 !!!!!!!
end;
 
// рисуем нечетные столбцы
dx:=0;
dy:=15;// !!!!!! SpriteHeigth div 2 !!!!!!
for I:=SourceRect.Left to SourceRect.Left+SourceRect.Right do
begin
  For J:=SourceRect.Top to SourceRect.Top+SourceRect.Bottom do
  begin
    if Odd(I)=True then Resource.Draw(DestCanvas,dX,dY,Map.Get(I,J));
    Inc(dY,30);// !!!!!!!! SpriteHeigth !!!!!!!
  end;
dY:=15;// !!!!!! SpriteHeigth div 2 !!!!!!
Inc(dX,30);// !!!!!! SpriteWidth div 2 !!!!!!!
end;
end;

Страницы : 1 2