Показать сообщение отдельно
Старый 02.07.2011, 18:39   #5
Randomize
[object Object]
 
Аватар для Randomize
 
Регистрация: 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
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Lestar (02.07.2011)