[object Object]
Регистрация: 01.08.2008
Адрес: В России
Сообщений: 4,355
Написано 2,471 полезных сообщений (для 6,852 пользователей)
|
Ответ: Генерация террайнов
Мой простенький генератор карты высот на базе diamondsquare (blitzmax):
Type THMapGenerator
Field gRoughness:Float
Field gBigSize:Float
Method Generate:Float[,] (iWidth:Int, iHeight:Int, iRoughness:Float)
SeedRnd(0)
Local c1:Float, c2:Float, c3:Float, c4:Float
Local points:Float[,] = New Float[iWidth + 1, iHeight + 1]
'Assign the four corners of the intial grid random color values
'These will end up being the colors of the four corners
c1 = Rnd()
c2 = Rnd()
c3 = Rnd()
c4 = Rnd()
gRoughness = iRoughness
gBigSize = iWidth + iHeight
DivideGrid(points, 0, 0, iWidth, iHeight, c1, c2, c3, c4)
Return points
EndMethod
Method DivideGrid(points:Float[,] Var, x:Float, y:Float, width:Int, height:Int, c1:Float, c2:Float, c3:Float, c4:Float)
Local Edge1:Float, Edge2:Float, Edge3:Float, Edge4:Float, Middle:Float
Local newWidth:Int = Floor(width / 2)
Local newHeight:Int = Floor(height / 2)
If (width > 1 Or height > 1)
Middle = ((c1 + c2 + c3 + c4) / 4) + Displace(newWidth + newHeight) 'Randomly displace the midpoint!
Edge1 = ((c1 + c2) / 2) 'Calculate the edges by averaging the two corners of each edge.
Edge2 = ((c2 + c3) / 2)
Edge3 = ((c3 + c4) / 2)
Edge4 = ((c4 + c1) / 2) '
'Make sure that the midpoint doesn't accidentally "randomly displaced" past the boundaries!
Middle = Rectify(Middle)
Edge1 = Rectify(Edge1)
Edge2 = Rectify(Edge2)
Edge3 = Rectify(Edge3)
Edge4 = Rectify(Edge4)
'Do the operation over again for each of the four new grids.
DivideGrid(points, x, y, newWidth, newHeight, c1, Edge1, Middle, Edge4)
DivideGrid(points, x + newWidth, y, width - newWidth, newHeight, Edge1, c2, Edge2, Middle)
DivideGrid(points, x + newWidth, y + newHeight, width - newWidth, height - newHeight, Middle, Edge2, c3, Edge3)
DivideGrid(points, x, y + newHeight, newWidth, height - newHeight, Edge4, Middle, Edge3, c4)
Else 'This is the "base case," where each grid piece is less than the size of a pixel.
'The four corners of the grid piece will be averaged and drawn as a single pixel.
Local c:Float = (c1 + c2 + c3 + c4) / 4
points[Int(x), Int(y)] = c
If (width = 2) Then
points[Int (x + 1), Int (y)] = c
EndIf
If (height = 2) Then
points[Int(x), Int (y + 1)] = c
EndIf
If ((width = 2) And (height = 2)) Then
points[Int(x + 1), Int(y + 1)] = c
EndIf
EndIf
EndMethod
Method Rectify:Float(iNum:Float)
If (iNum < 0)
iNum = 0
ElseIf (iNum > 1.0)
iNum = 1.0
EndIf
Return iNum
EndMethod
Method Displace:Float(SmallSize:Float)
Local _Max:Float = SmallSize / gBigSize * gRoughness
Return (Rnd() - 0.5) * _Max
EndMethod
EndType
__________________
Retry, Abort, Ignore? █
Intel Core i7-9700 4.70 Ghz; 64Gb; Nvidia RTX 3070
AMD Ryzen 7 3800X 4.3Ghz; 64Gb; Nvidia 1070Ti
AMD Ryzen 7 1700X 3.4Ghz; 8Gb; AMD RX 570
AMD Athlon II 2.6Ghz; 8Gb; Nvidia GTX 750 Ti
|