Рисунок 8
Как видно из рисунка 8, если в матрице 5×5 лежит в некоторой ячейке число 20, то индекс переходной текстуры будет равен 4 (20 mod 16), индекс типа земли равен 1 (20 div 16), а индекс цельной текстуры земли равен 16 (Индекс типа земли * 16). Номер ячейки, где лежит число 20, и индекс переходной текстуры (4) — входные параметры в таблицу BaseTable. Если мы на выходе получим, к примеру число 8, то нужно к индексу цельной текстуры прибавить 8, чтобы получить индекс новой переходной текстуры. ( Индекс типа земли * 16 + 8 = 24 ) Это будет новое число, которое мы поместим на карту.
Следующий кусок кода:
else begin
Vector[12] := BrushIndex*16;
for i := 0 to 24 do begin
BaseIndex := GetBaseIndex(Vector[i]);
AdditionalIndex := GetAdditionalIndex(Vector[i]);
if BaseIndex = BrushIndex then begin
if EqualTable[i,AdditionalIndex] 16 then Vector[i] := BaseIndex*16 + EqualTable[i,AdditionalIndex];
end else begin
if NotEqualTable[i,AdditionalIndex] else if NotEqualTable[i,AdditionalIndex]> 16 then Vector[i] := BrushIndex*16+ NotEqualTable[i,AdditionalIndex] – 16;
end;
end;
end;
end;
Делает все то же самое, для двух оставшихся случаев. Голубым выделены те строчки, которые по моему мнению можно удалить, но при этом исправить в таблице NotEqualTable числа больше 16 на эти же числа минус 16. Все, с технологией покончено!!!
Следующие страницы я посвящу некоторым особенностям вывода карты на экран в моем примере. Кого интересовала только технология расчета плавных перетеканий текстур, дальше, если нет желания, могут не читать.
Как я уже говорил, в примере я использовал компоненты для DirectX, написанные каким-то хорошим китайцем. Имя у него соответственно самое что ни на есть китайское, по этому я его не помню.
Конкретно для вывода карты на экран использовались компоненты TDXDraw, TDXImageList и TDXTimer.
TDXDraw — в основном используется для переключения страниц видеопамяти. Что это такое объяснять не буду.
TDXImageList — хранит в качестве элементов файлы со спрайтами выстроенными в одну цепочку. Соответственно к конкретному спрайту можно обратится по имени файла и номеру спрайта в нем. Также в этом компоненте есть две переменные PatternWidth, PatternHeight для указания ширины и высоты спрайтов, и переменная TransparentColor для указание прозрачного цвета.
TDXTimer — используется для генерации события DXTimerTimer с частотой заданной или рассчитанной в ходе выполнения программы.
Итак, текстуры выполнены в виде одного файла внутри которого выстроены в цепочку в соответствии с принципами изложенными выше и помещены в TDXImageList под именем "West". ( TDXImageList позволяет находить файлы внутри себя по их имени)
Нам нужно вывести на экран некоторую часть карты, причем карта наша состоит из кусочков и нам нужно вывести только те кусочки, которые видны в данный момент.
Можно сделать окно вывода кратным размеру текстур, а скроллинг организовать потекстурно с шагом равным ширине/высоте текстуры, тогда нет проблем, но это смотрится не очень красиво. Наша задача состоит в том, чтобы организовать скроллинг попиксельно и дать возможность задать окно вывода любого размера. Для того, чтобы это сделать нужно рассчитать сколько текстур по горизонтали и сколько текстур по вертикали мы должны отрисовать в окне вывода, включая и те текстуры которые в данный момент времени видны только частично.
Рисунок 9
На рисунке 9 клеточками изображена карта. Черным контуром показано окно вывода. Как видно – не все ячейки карты целиком влезли в окно, но их тоже надо отрисовать. Положение окна вывода на карте определяется координатами его левого верхнего угла относительно карты.( TopLeftCorner.x, TopLeftCorner.y) Их величины в пикселях(Нам же надо сделать попиксельный скроллинг) При создании новой карты они приравниваются нулям, и в дальнейшем определяются положением полос прокрутки. Вот часть кода:
procedure TMainForm.RedrawMap;
Var
OffsPoint : TPoint;
TopLeftElem : TPoint;
ElemCount : TPoint;
HelpVar1 : Integer;
HelpVar2 : Integer;
i,j : Integer;
x,y : Integer;
Index : Integer;
begin
OffsPoint.x := TopLeftCorner.x mod ElemWidth;
OffsPoint.y := TopLeftCorner.y mod ElemHeight;
Данные две строчки позволяют получить смешение левого верхнего угла экрана внутри левой верхней ячейки(См. рисунок 9). Глобальные переменные ElemWidth,ElemHeight это высота и ширина ячейки(текстуры). Теперь нам необходимо получить номер строки и столбца ячейки где находится левый верхний угол окна вывода:
TopLeftElem.x := TopLeftCorner.x div ElemWidth;
TopLeftElem.y := TopLeftCorner.y div ElemHeight;
Далее необходимо рассчитать сколько у нас целых текстур влезает в окно вывода по вертикали и горизонтали:
Читать дальше