Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Ответ: Vivo
Я написал псевдо-код с комментариями, посмотри, может тебе пригодится такое.
Global chunks.TChunk[9] ;ближайшие к игроку чанки
Dim IMAGES%(100) ;масив для картинок-тайлов, идентификатор тайла соответствует идентификатору массива
;при старте уровня можно создать сколько-нибудь чанков
;при создании чанков указываем их соседей, тогда можно при движении в стороны сразу выцеплять соседей
Local xx%, yy%, countX% = 100, countY% = 100
Local ch.TChunk, ch2.TChunk
Dim temp.TChunk(countX*countY) ;тут временно сохраним чанки, чтоб соседей назначить
;Local dx# = 32*16, dy# = 32*16
Local index%
For xx = 0 To countX-1
For yy = 0 To countY-1
ch = CreateChunk(xx,yy)
temp(xx*yy) = ch
;тут соседей назначаем
If(xx > 0)
index = GetLinearIndex(xx-1,yy,countX) ;чанк слева от нового
ch2 = temp(index)
ch\chunks[0] = ch2
ch2\chunks[2] = ch ;а этому ставим правого соседа
EndIf
If(yy > 0)
index = GetLinearIndex(xx,yy-1,countX) ;чанк сверху от нового
ch2 = temp(index)
ch\chunks[1] = ch2
ch2\chunks[3] = ch ;а этому ставим нижнего соседа
EndIf
Next
Next
;назначаем начальные чанки из середины поля
Local x0% = Rand(40,60)
Local y0% = Rand(40,60)
For xx=0 To 2
For xx=0 To 2
chunks[xx*yy] = temp(GetLinearIndex(x0+xx,y0+yy,countX))
Next
Next
;в игровом цикле нужно рисовать только наши 9 чанков
For k% = 0 To 8
DrawChunk(chunks[k], scrollX, scrollY) ;рисуем с учётом скролла
Next
;при движении игрока в сторону - по достижении границы чанков - делаем сдвиг чанков
ShiftChunks(direction) ;direction - направление: 0-влево, 1-вверх, 2-вправо, 3-вниз
;получение индекса в одномерном массиве через значения индексов двухмерного
Function GetLinearIndex%(x%, y%, dimX%)
Return y*dimX + x
End Function
;сдвигаем, беря соседние в зависимости от направления
;и сохраняем то что уходит за экран
;если соседа нет, то загружаем из файла или генерируем
Function ShiftChunks(direction%)
Local ch.TChunk;, ch2.TChunk
Local xx%, yy%
Select(direction)
Case 0 ;сдвиг влево, сохраняем правый ряд
For yy=0 To 2
ch = chunks[GetLinearIndex(2,yy,3)]
SaveChunk(ch)
chunks[GetLinearIndex(2,yy,3)] = GetNextChunk(ch, 0) ;получаем соседний чанк
Delete(ch) ;и удаляем тех кто ушёл за экран
Next
Case 1 ;сдвиг вверх, сохраняем нижний ряд
For xx=0 To 2
SaveChunk(chunks[GetLinearIndex(xx,2,3)])
Next
Case 2 ;сдвиг вправо, сохраняем левый ряд
For yy=0 To 2
SaveChunk(chunks[GetLinearIndex(0,yy,3)])
Next
Case 3 ;сдвиг вниз, сохраняем верхний ряд
For xx=0 To 2
SaveChunk(chunks[GetLinearIndex(xx,0,3)])
Next
End Select
For xx=0 To 2
For xx=0 To 2
chunks[xx*yy] = temp(GetLinearIndex(x0+xx,y0+yy,countX))
Next
Next
End Function
;получаем соседний чанк, если он есть
;если нет, то пробуем загрузить из файла
;если файла нет, то генерируем новый
Function GetNextChunk.TChunk(ch.TChunk, dir%)
Local chunk.TChunk = ch\chunks[dir]
If(chunk <> Null) Then Return chunk
;пробуем из файла
Local path$
If(dir = 0) ;влево идём
path$ = "ch-"+(ch\cellX-1)+"-"+ch\cellY+".txt"
Else If(dir = 0) ;влево вверх
path$ = "ch-"+ch\cellX+"-"+(ch\cellY-1)+".txt"
Else If(dir = 0) ;влево вправо
path$ = "ch-"+(ch\cellX+1)+"-"+ch\cellY+".txt"
Else If(dir = 0) ;влево вниз
path$ = "ch-"+ch\cellX+"-"+(ch\cellY+1)+".txt"
EndIf
If(FileType(path) = 1)
;грузим
chunk = New TChunk
LoadChunk(chunk, path)
Return chunk
Else
chunk = GenerateChunk() ;генерируем
EndIf
;здесь нужно указать соседство левого с правым и т.д. для всех направлений
;и другие параметры/ cellX, cellY
Return chunk
End Function
Function GenerateChunk.TChunk()
End Function
Function LoadChunk(ch.TChunk, path$)
End Function
Function SaveChunk(ch.TChunk)
;тут записываем в файл с именем ch-x-y.txt инфу о тайлах
;x - ch\cellX
;y - ch\cellY
End Function
;создание чанка
Function CreateChunk.TChunk(cellX%, cellY%, dimX%=15, dimY%=15, size%=32)
Local ch.TChunk = New TChunk
ch\dimX = dimX ;16-1
ch\dimY = dimY ;16-1
ch\size = size
ch\cellX = cellX
ch\cellY = cellY
ch\x0 = cellX*size*(dimX+1)
ch\y0 = cellY*size*(dimY+1)
GenerateTiles(ch) ;генерим тайлики в чанк
Return ch
End Function
;генерим тайлы для чанка - если есть файл с таким чанком то надо загрузить из файла
Function GenerateTiles(ch.TChunk)
Local xx%, yy%
For xx = 0 To ch\dimX
For yy = 0 To ch\dimY
ch\imagesId[xx*yy] = Rand(0, IMAGES_COUNT-1) ;в реале конечно простой рандом не прокатит, это пример получения идентификатора картинки
Next
Next
End Function
;рисование чанка, х и у - сдвиг, который позволяет скроллировать карту
Function DrawChunk(chunk.TChunk, x#, y#)
Local xx%, yy%
For xx = 0 To chunk\dimX
For yy = 0 To chunk\dimY
DrawImage(IMAGES(chunk\imagesId[xx*yy]), x+chunk\x0, y+chunk\y0)
Next
Next
End Function
Type TChunk
Field cellX%, cellY% ;индекс чанка в глобальном мире
Field x0#, y0# ;координаты левого верхнего угла, относительно которых будем рисовать
Field dimX%, dimY% ;количество тайлов в чанке по х и по у, н-р: 16x16, или на 1 меньше хранить, чтоб в циклах не отнимать каждый раз
Field size% ;размер тайла, н-р: 32
Field imagesId%[16*16] ;идентификаторы картинок-тайлов. т.к. двумерный массив тут нельзя добавить, в одномерный вставим
Field chunks.TChunk[4] ;соседи слева-справа-сверху-снизу
End Type
|