destructible terrain
BlitzMax Forums/BlitzMax Beginners Area/destructible terrain
| ||
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 |
| ||
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 |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
Ok, I see how that works, thanks for all the help. |