Я нашел два способа представления карты в памяти - ромб, и зигзаг.
Оба мне не подходят - первый способ дает ромбическую карту, в то время когда нужна прямоугольная, при втором перемещение по вертикали происходит через две клетки, что не очень большая проблема, но все же нервирует.
Поэтому я придумал свой способ, назвем его двойная карта. Если посмотреть на изометрическую корту как на рисунке (за кривость не судите, рисовать не умею абсолютно), то можно заметить что ее можно разбить на две подкарты.
Как вам этот способ - ересь, или все же возможно применять?
А в чем проблема хранить в памяти обычную двумерную карту, а выводить в изометрии?
Я использую обычную матрицу, просто вывожу на экран и координаты обсчитываю по-особому... Пока доволен)
Я же говорю, что при стандартом способе проблема в том, что карта принимает форму ромба.
А при использовании зигзага.. Ну хотя бы усложнится алгоритм поиска пути. Хотя не смертельно.
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));
Либо заранее построить нужную сетку, рассчитав этим алгоритмом координаты вершин ромбов.
Pythoner
> Я же говорю, что при стандартом способе проблема в том, что карта принимает
> форму ромба.
А это проблема?
Так тоже неплохо, но мне не подходит. Дело в том, что карту нужно разбить на множество локаций прямоугольной формы.
Pythoner
> Так тоже неплохо, но мне не подходит. Дело в том, что карту нужно разбить на
> множество локаций прямоугольной формы.
Ромб тоже можно разбить на локации прямоугольной формы с неким процентом неиспользуемых клеток.
А вообще локации можно сделать любой формы, главное ограничить перемещение объектов и камеры.
> 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
Если нужны прямоугольные локации, то сделайте модифицированную изометрию. Наверняка, у нее есть научное название, но я как-то сам до нее дошел, поэтому расскажу, как понимаю.
Берем стандартную изометрию с ромбом 2:1 в основе. Допустим, карта MxN клеток. Назовем осью Z - вертикальную ось. Так вот, мысленно поворачиваем карту вокруг оси Z до того момента, пока она из ромба не превратится в прямоугольник с теми же пропорциями 2:1. Клетки карты теперь не ромбы, а тоже прямоугольники 2:1.
Получаем желаемое - прямоугольную карту той же размерности MxN, которую можно хранить в виде той же матрицы в памяти и не выдумывать "зигзаги". :)
Что в плюсах:
1. Получаем прямоугольник, экономим место на экране, и т.п.
2. Вся графика, если она спрайтовая, остается совершенно без изменений. Всё те же 8 направлений у нас есть, как и в стандарте, наклон камеры и освещение - не изменились. Красота картинки не страдает.
3. Упрощаются алгоритмы отрисовки карты, вычисления глубины объекта на ней и т.п. Ощутимо так упрощаются.
В минусах:
Я х.з. Вроде минусов нет. :) Чуть подкрутить голову придется, и всё. :)
тогда непонятно при чем тут изомерия ?
проще тогда сразу использовать квадрантые спрайты и не нужно будет нечего вертеть
nigga-digga
Ну визуально это будет выглядеть, как-будто это изометрия. Но будет иметь перечисленные плюсы, по сравнению с ней.
Да, прямоугольные тайлы надо делать сразу в таком случае.
На счет "вертеть" - это я просто так объяснил - чтобы понятно было, как преобразовать мысленно изометрию в эту модификацию. Для доходчивости короче. А при разработке, естественно, ничего вертеть уже не надо. :)
Pythoner
Ну что, проверил свой вариант на практике?
Тема в архиве.