ПрограммированиеФорум2D графика и изометрия

Представление изометрической карты в памяти

#0
11:51, 10 окт 2013

Я нашел два способа представления карты в памяти - ромб, и зигзаг.
Оба мне не подходят - первый способ дает ромбическую карту, в то время когда нужна прямоугольная, при втором перемещение по вертикали происходит через две клетки, что не очень большая проблема, но все же нервирует.
Поэтому я придумал свой способ, назвем его двойная карта. Если посмотреть на изометрическую корту как на рисунке (за кривость не судите, рисовать не умею абсолютно), то можно заметить что ее можно разбить на две подкарты.
Изображение
Как вам этот способ - ересь, или все же возможно применять?

#1
14:00, 10 окт 2013

А в чем проблема хранить в памяти обычную двумерную карту, а выводить в изометрии?

#2
15:35, 10 окт 2013

Я использую обычную матрицу, просто вывожу на экран и координаты обсчитываю по-особому... Пока доволен)

#3
15:48, 10 окт 2013

Я же говорю, что при стандартом способе проблема в том, что карта принимает форму ромба.
А при использовании зигзага.. Ну хотя бы усложнится алгоритм поиска пути. Хотя не смертельно.

#4
16:11, 10 окт 2013

Pythoner
>Я же говорю, что при стандартом способе проблема в том, что карта принимает форму ромба.
Ребята тебе дело говорят.
По сути для отображения такой карты нужно сделать примерно так:

for (int y = 0; y < cy; ++y)
  for (int x = 0; x < cx; ++x)
    drawTile(((x % 2) ? 0.5f * x : x), ((y % 2) ? 0.5f * y : y));

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

#5
16:13, 10 окт 2013

Pythoner
> Я же говорю, что при стандартом способе проблема в том, что карта принимает
> форму ромба.
А это проблема?

+ Показать
#6
10:30, 11 окт 2013

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

#7
11:16, 11 окт 2013

Pythoner
> Так тоже неплохо, но мне не подходит. Дело в том, что карту нужно разбить на
> множество локаций прямоугольной формы.
Ромб тоже можно разбить на локации прямоугольной формы с неким процентом неиспользуемых клеток.
А вообще локации можно сделать любой формы, главное ограничить перемещение объектов и камеры.

#8
23:42, 29 ноя 2013

> Pythoner
Незнаю подойдет или нет. 

я  в своей игре для отрисовки спрайтов на экран замутил следующее.  Правда работает только с КРАДРАТНЫМИ текстурами

Он берет данные из обычтого двумерного массива masiv[x,y]  и поворачивает их на 45 градусов (типа "Изоморфирует" =)))  и обрезает ненужные куски ромба. Выводит только  прямоугольник (то что помещается на экран).
Рисование начинаеться с верхнего правого угла.(с учетом изометрии чтобы рисунки не перекрывали друг друга).  Как точка опоры вокруг которой будем рисовать, берется квадрат на котором находится камера. Этот квадрат будет в центре экрана. 
Допустим есть карта 500на 500 клеток а ссылки на текстуры у нас лежат в двумерном массиве Map[500,500].  А камера в данный момент допустим у нас находится в клекте с координатами 100/100. также нужно знать координаты камеры на экране (тоесть центр экрана )

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

Point Kamera = new Point(100, 100);  // координаты камеры в игре
int resolutionHalf_X = 1200/2;                 // координаты камеры на экране (Центр экрана)
int resolutionHalf_Y = 800/2;                   // у меня размер игрового поля  1200 на 800
int halfblocksize = 44 / 2;         //  половина ширины клетки/текстуры   ( у меня текстуры имеют размер 44 на 44 поэтому halfblocksize=22)

// эти 2 переменные НУЖНО ИЗМЕНИТЬ смотри в рисунки
int popravka = 5;  //смещение по Х (на рисунке зеленый цвет)
int diapazon = 23 ; // 18 + 5  =  popravka + Диоганаль  (на рисунке диагональ красный цвет)
// Все настроино теперь должно работать нормально

int n = 0;
int nx = 0;
int left = 0;  //obrezanije levogo kraja


for (int y = - diapazon; y < diapazon; y++)    // от -23 до  23
        {
                n--; //
                if (y < popravka)   // при необходимости заменить "popravka" на  значение         popravka +- (1или3)
                { nx += 2; } 
                if (y > popravka) { left +=2; }

                for (int tx = left; tx < nx; tx++)
                {
                        //пробегаем по клеткам масива, которые попадают в экран
                        int MX = Kamera.X + (popravka + n + tx) ; 
                        int MY = Kamera.cameraY + y ;
                        Textura = MAP[ MX  ,  MY   ];     

                        // а тут непосредственно само преобразование игровых координат( тоесть координат массива) в координаты экрана с учетом изометрии
                        screen_X = resolutionHalf_X + (popravka + n + tx) * halfblocksize      -   y * halfblocksize  ;
                        screen_Y = resolutionHalf_Y + y * halfblocksize         + (popravka + n + tx) * halfblocksize  ;

                        // ну а дальше уже некая функция рисующая текстуру на экран
                        draw(Textura ,   screen_X  , screen_Y )
                  }
       }

Pythoner

Для настройки смотри сюда
Изображение
http://yadi.sk/d/yW2xbA57DXyee

Вот так оно рисует. Почти точно по размерам экрана
Изображение
http://yadi.sk/d/kZYRRCuXDXxyS

#9
18:02, 18 янв 2014

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

Берем стандартную изометрию с ромбом 2:1 в основе. Допустим, карта MxN клеток. Назовем осью Z - вертикальную ось. Так вот, мысленно поворачиваем карту вокруг оси Z до того момента, пока она из ромба не превратится в прямоугольник с теми же пропорциями 2:1. Клетки карты теперь не ромбы, а тоже прямоугольники 2:1.
Получаем желаемое - прямоугольную карту той же размерности MxN, которую можно хранить в виде той же матрицы в памяти и не выдумывать "зигзаги". :)

Что в плюсах:
1. Получаем прямоугольник, экономим место на экране, и т.п.
2. Вся графика, если она спрайтовая, остается совершенно без изменений. Всё те же 8 направлений у нас есть, как и в стандарте, наклон камеры и освещение - не изменились. Красота картинки не страдает.
3. Упрощаются алгоритмы отрисовки карты, вычисления глубины объекта на ней и т.п. Ощутимо так упрощаются.

В минусах:
Я х.з. Вроде минусов нет. :) Чуть подкрутить голову придется, и всё. :)

#10
18:12, 20 янв 2014

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

#11
18:21, 20 янв 2014

nigga-digga
Ну визуально это будет выглядеть, как-будто это изометрия. Но будет иметь перечисленные плюсы, по сравнению с ней.
Да, прямоугольные тайлы надо делать сразу в таком случае.
На счет "вертеть" - это я просто так объяснил - чтобы понятно было, как преобразовать мысленно изометрию в эту модификацию. Для доходчивости короче. А при разработке, естественно, ничего вертеть уже не надо. :)

#12
13:57, 11 фев 2014

Pythoner
Ну что, проверил свой вариант на практике?

ПрограммированиеФорум2D графика и изометрия

Тема в архиве.