destructible terrain

BlitzMax Forums/BlitzMax Beginners Area/destructible terrain

sandav(Posted 2007) [#1]
I'm working on a scorched earth clone, and want to make the ground destructible. I thought the best way to do this would be to use pixmaps and turn pixels alpha when they are destroyed, I made a test program and have found that this method takes a bit more processing time then I'd prefer.
Is there a better way to do it?

Strict
Const X_RES = 800, Y_RES = 600

Graphics X_RES, Y_RES, 0
SetBlend(ALPHABLEND)
Global map:Timage = CreateImage(X_RES, Y_RES)
Global pixels:TPixmap = LockImage(map) 
Global radius = 20 'radius of terrain to destroy around a click


For Local i% = 0 To X_RES - 1
	For Local j% = Y_RES/2 To Y_RES  - 1
		WritePixel(pixels,i,j, $ff00ff00) 'blue
	Next
Next

UnlockImage(map)


Function destroy(x,y)
	pixels:TPixmap = LockImage(map) 
	For Local i% = x-radius To x+radius
		For Local j% = y-radius To y+radius
			Local pixel% = ReadPixel(pixels,i,j)
			If Hex(pixel) > $00ffffff 'if the pixel is not completely clear
				pixel = ($00ffffff & pixel) 'changes the alpha bits to 0 and preserves the rest
				WritePixel(pixels,i,j,pixel) 
			EndIf	
		Next
	Next
	UnlockImage(map) 
EndFunction

'UnlockImage(map)
While Not KeyHit(key_escape)
	If MouseHit(1) Then 
		Local time = MilliSecs()
		'For Local i% = 1 To 100
			destroy(MouseX(),MouseY())
		'Next
		Print MilliSecs() - time
	EndIf
	
	SetColor(255,0,0)
	DrawRect(0,0,X_RES,Y_RES)
	SetColor(255,255,255)
	DrawImage(map,0,0)
Flip;Cls
Wend



Perturbatio(Posted 2007) [#2]
Searching for scorched earth on the forum returns these (and more)
http://www.blitzbasic.com/Community/posts.php?topic=42962#480701
http://www.blitzbasic.com/Community/posts.php?topic=48215#536207
http://www.blitzbasic.com/Community/posts.php?topic=48169
http://www.blitzbasic.com/Community/posts.php?topic=52296#584273


sandav(Posted 2007) [#3]
I had searched for "destructible terrain" and turned up nothing, so I thought it was safe to post. Sorry if this is a topic everyone's sick of hearing about. Thanks for the links.


Jesse(Posted 2007) [#4]
I know this is not what you are looking for but this way is sligthly faster:



the unlock function is just dead weight. don't waste your time using it.
<edit>
This way only works with 32 bit pixmap.


QuietBloke(Posted 2007) [#5]
I wrote a sample of terrain deformation a few weeks ago.

http://www.blitzmax.com/Community/posts.php?topic=72736

The code uses two techniques. The first uses a single image and locks it, changes the pixels and unlocks it.

In the second one I I turned the whole screen into tiles. That way when I deform I only change the tiles affected. For each tile I lock the image, set the affected pixels to zero and unlock it ( I realize unlock does nothing but I figured Id leave it in in case a future update of BMax requires it ).
It turned out to be pretty fast even on my old machine.


sandav(Posted 2007) [#6]
Jesse: Thanks, that optimization does speed it up a bit, I didn't know the pixel array could be accessed directly like that.

I don't quite understand why the method of dividing the screen up into tiles helps so much. You're changing the same number of pixels either way, It seems to me that you'd actually be doing more operations that way because you have to lock and unlock more, and use more variables. But running your test, the tiles technique seems to work way faster.


ImaginaryHuman(Posted 2007) [#7]
It's to do with how much data has to be transferred from the graphics card memory to main memory in order to change the pixels and then move it back to graphics card memory. Obviously if you're locking an entire screen-sized image (or bigger) and then reuploading the changes thats a huge amount more transferring over the graphics bus than if you're only transferring a small percentage of the screen area. Since transferring stuff over the bus is generally slow compared with drawing images from graphics memory, you want to minimize it as much as possible which is what the tile system does.


sandav(Posted 2007) [#8]
Ok, I see how that works, thanks for all the help.