Destructable Landscapes
Blitz3D Forums/Blitz3D Beginners Area/Destructable Landscapes
| ||
How could you make 2D destructable landscapes like in Worms or Dome Wars? I'm thinking of making a Dome Wars remake depending on how hard this is. |
| ||
You would need to calculate the explosion size, then subtract the image of the explosion from the landscape. Say, drawing a black oval onto the landscape image, would probably do the trick, as long as black is your masking colour :o) |
| ||
How would you manipulate images like that? Or do you mean just draw a black oval over the image? |
| ||
setbuffer imagebuffer(mylandscapeimage) color 0,0,0 oval x,y,width,height,1 setbuffer backbuffer() |
| ||
I've never understood that image buffer thing. I guess it's time to learn. So, that kindof like... opens the image for editing in a way? And then you can draw an oval on it? |
| ||
setbuffer() sets the (I probably should have had some brackets above) current drawing buffer. Using an imagebuffer allows you to draw to an image rather than to the back or front buffer. |
| ||
Oh cool. I never took the time to learn that. Now I understand it. Thanks. I think I can figure out the rest now. |
| ||
I've run into a problem. The drawing the oval on the landscape works, but it draws the oval in the wrong place. It's supposed to draw the oval right where the shot landed on the ground, but it shows the oval a little to the left and farther down. I'm wondering if drawing on the image does not use the same coordinates? Does 0 become the corner of the image instead of the corner of the screen when I setbuffer to the image? If you need to see it to help me, you can download it here http://www.antibox.net/grant/Test.zip Right now, I'm just testing all the aspects of the game in that .bb file. I'm going to restart after I figure them all out because that file isn't coded very well and it's very messy. Just wanted everyone to know that :-) Also, how do you make links that aren't the whole url. HTML doesn't seem to work in these forums. |
| ||
Does 0 become the corner of the image instead of the corner of the screen when I setbuffer to the image? Yes. Also, how do you make links that aren't the whole url. http://www.blitzbasic.com/faq/faq_entry.php?id=2 |
| ||
If 0 becomes the corner of the image, how can I tell it to make an oval at the right coordinate? The coordinates of the shot that hit the ground won't work. |
| ||
Subtract the image's coordinates from your target coordinates. If your image's top left corner is at (100,100) and you want to draw an oval on that image at (101,101), then you'd want to centre your oval at (1,1) on the image. |
| ||
Well, I found a way around that anyways for now. But, the collisions aren't right at all. I can't explain it. You'll have to download the test from the post a little ways up. It's like, sometimes the collisions make an oval and sometimes they don't. |
| ||
Your program always draws an oval at the wrong place. There are two reasons for this: 1. The x,y coordinates you pass to oval() are for the top-left corner. If you want the oval centred, you need to subtract half the width and height from its origin. 2. Much more importantly, you aren't subtracting the background image's offset as I explained in my last post. Exasperating the problem is the fact that you're using AutoMidHandle True and positioning your background image arbitrarily: the image size is 1152,684 and you're positioning its midpoint at 512,350 - this means you have an offset of -64,-82. |
| ||
Oops, I forgot to update the images size. I had made the image the same size as the window so I didn't need to subtact the background image's offset. Sorry about that. It's updated now if you want to download it again and try it. I'll try to fix number 1 while I wait though. |
| ||
Hey man, change your function TestShotsGround() to :Function TestShotsGround() For s.shot = Each shot If ImagesCollide(s\Image,s\x,s\y,0,TestForg,512,350,0) SetBuffer ImageBuffer(TestForg) Color 0,0,0 Oval s\x-50,s\y-50,100,100,1 ; SetBuffer BackBuffer() Delete s End If Next End Function I would also encourage you to tab your code. It helps alot when debuging and following th program flow. So you code looks like: ;Initialize Graphics Mode Graphics 1024,700 SetBuffer BackBuffer() AutoMidHandle True SeedRnd MilliSecs() ;Load Graphics Global Silo1 = LoadImage("p1silo.bmp") MaskImage Silo1,255,255,255 Global Turret1 = LoadImage("p1turret.bmp") Global shot = LoadImage("shot.bmp") MaskImage shot,0,0,0 Global TestForg = LoadImage("Testforg.bmp") MaskImage TestForg,0,0,0 ;Arrays Dim tur1(45) RotateImage Turret1,-45 tur1(0) = Turret1 For i = 1 To 45 tur1(i) = CopyImage(Turret1) RotateImage tur1(i),2 * i Next ;Turret direction Array Dim dir(45) dir(0) = 135 For i = 1 To 45 dir(i) = dir(i-1) + 2 Next ;Variables Global x = 400 Global y = -10 Global rot = 0 Global velocity Global gravity# = 0.2 ;Types Type shot Field x,y Field vx#,vy# Field id$ Field Image Field radius End Type While Not ImagesCollide(Silo1,x,y,0,TestForg,512,350,0) y = y + 1 Wend ;Main Loop While Not KeyHit(1) TestInput() DrawGrounds() DrawPlayers() UpdateShots() TestShotsGround() Flip Cls Wend End Function TestInput() rot = rot + MouseXSpeed() If rot < 0 rot = 0 Else If rot > 45 rot = 45 End If If MouseHit(1) s.shot = New shot s\x = x s\y = y s\vx# = -Sin(dir(rot)) * 9 s\vy# = Cos(dir(rot)) * 9 s\id$ = "ICBM" s\Image = CopyImage(shot) s\radius = 5 End If End Function Function DrawGrounds() DrawImage TestForg,512,350 End Function Function DrawPlayers() DrawImage tur1(rot),x,y -6 DrawImage Silo1,x,y End Function Function UpdateShots() For s.shot = Each shot DrawImage s\Image,s\x,s\y s\x = s\x + s\vx# s\y = s\y + s\vy# s\vy# = s\vy# + gravity# Next End Function Function TestShotsGround() For s.shot = Each shot If ImagesCollide(s\Image,s\x,s\y,0,TestForg,512,350,0) SetBuffer ImageBuffer(TestForg) Color 0,0,0 Oval s\x-50,s\y-50,100,100,1 ; SetBuffer BackBuffer() Delete s End If Next End Function |
| ||
I've slightly changed your aiming control, just incase you think it's better. Basically, moving the mouse to a place on the screen and the cannon will roughly aim that way. I've marked the lines i've changed and added.;Initialize Graphics Mode Graphics 1024,768 SetBuffer BackBuffer() AutoMidHandle True SeedRnd MilliSecs() ;Load Graphics Global Silo1 = LoadImage("p1silo.bmp") MaskImage Silo1,255,255,255 Global Turret1 = LoadImage("p1turret.bmp") Global shot = LoadImage("shot.bmp") MaskImage shot,0,0,0 Global TestForg = LoadImage("Testforg.bmp") MaskImage TestForg,0,0,0 ;Arrays Dim tur1(45) RotateImage Turret1,-45 tur1(0) = Turret1 For i = 1 To 45 tur1(i) = CopyImage(Turret1) RotateImage tur1(i),2 * i Next ;Turret direction Array Dim dir(45) dir(0) = 135 For i = 1 To 45 dir(i) = dir(i-1) + 2 Next ;Variables Global x = 400 Global y = -10 Global rot% = 0 Global velocity Global gravity# = 0.2 ;Types Type shot Field x,y Field vx#,vy# Field id$ Field Image Field radius End Type While Not ImagesCollide(Silo1,x,y,0,TestForg,512,350,0) y = y + 1 Wend ;Main Loop While Not KeyHit(1) TestInput() DrawGrounds() DrawPlayers() UpdateShots() TestShotsGround() Flip Cls Wend End Function TestInput() temp# = (MouseX()/1024.0)*45.0 ; ADDED******** rot = temp ; CHANGED********************** If rot < 0 rot = 0 Else If rot > 45 rot = 45 End If If MouseHit(1) s.shot = New shot s\x = x s\y = y s\vx# = -Sin(dir(rot)) * 9 s\vy# = Cos(dir(rot)) * 9 s\id$ = "ICBM" s\Image = CopyImage(shot) s\radius = 5 End If End Function Function DrawGrounds() DrawImage TestForg,512,350 End Function Function DrawPlayers() DrawImage tur1(rot),x,y -6 DrawImage Silo1,x,y End Function Function UpdateShots() For s.shot = Each shot DrawImage s\Image,s\x,s\y s\x = s\x + s\vx# s\y = s\y + s\vy# s\vy# = s\vy# + gravity# Next End Function Function TestShotsGround() For s.shot = Each shot If ImagesCollide(s\Image,s\x,s\y,0,TestForg,512,350,0) SetBuffer ImageBuffer(TestForg) Color 0,0,0 Oval s\x-50,s\y-50,100,100,1 ; SetBuffer BackBuffer() Delete s End If Next End Function |