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
|