Тема: Vivo
Показать сообщение отдельно
Старый 26.04.2012, 07:55   #295
Жека
Дэвелопер
 
Регистрация: 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
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Hulk-DS (26.04.2012)