Exploding lemming effect.
Blitz3D Forums/Blitz3D Beginners Area/Exploding lemming effect.
| ||
I'm having a bit of a problem with my sines and cosines. I thought I'd have a go at making an effect like the exploding lemmings from 'Lemmings', and I've nearly sort of succeeded.Type bits ;type for the particles Field x Field y Field angle Field power Field r Field g Field b End Type fps=CreateTimer(10) anglenumber=180 ;set angle to 180 for the first particle AppTitle("Exploding Lemming Type Thing","Quit?") Graphics 800,600,0,2 SetBuffer BackBuffer() While Not KeyDown(1) WaitTimer(fps) Cls If MouseDown(1) ;when mouse is down For n=1 To 15 ;make dots from 180 to 360 If anglenumber=<360 ;at 15 degree intervals anglenumber=anglenumber+15 Else anglenumber=180 EndIf explode.bits=New bits explode\x=MouseX() ;where the mouse is explode\y=MouseY() explode\r=Rnd(0,255) explode\g=Rnd(0,255) explode\b=Rnd(0,255) explode\angle=anglenumber explode\power=1 Next EndIf For explode.bits=Each bits If explode\power>=10 If explode\angle<=90 explode\x=explode\x+explode\power*Cos(explode\angle) explode\y=explode\y+explode\power*Sin(explode\angle) Else explode\x=explode\x+explode\power*Cos(explode\angle) explode\y=explode\y+explode\power*Sin(explode\angle) explode\angle=explode\angle-15 EndIf Else explode\x=explode\x+explode\power*Cos(explode\angle) explode\y=explode\y+explode\power*Sin(explode\angle) explode\power=explode\power+1 EndIf Color explode\r,explode\g,explode\b Rect explode\x,explode\y,2,2,1 If explode\y>610 Delete explode EndIf Next Flip Wend End The problem is, when the bits finally run out of gas and start falling back down to earth they all loop around the left. I want them really to just fall straight downwards instead of looking like some sort of pixel aerial acrobatics team. Does anyone have any advice on how I could do this? |
| ||
[ code ] & [ / code ] Ahh but yes, I had a problem with this to. Well I believe it's in the function that you used to turn it (obviously) and you need to limit so it stops turning, usualy when it points straight down. Using maybe EntityPitch, but I have'nt looked through your code. |
| ||
Ah cheers. Didn't notice that. =) The program won't use EntityPitch since it's in 2D. I'm using sin and cos to do turning, but it usually confuses me a bit. I usually end up messing about with it, until I get it right. But I'm stumped as to what I should do now though. I've got a feeling it's something to do with this bit : If explode\angle<=90 explode\x=explode\x+explode\power*Cos(explode\angle) explode\y=explode\y+explode\power*Sin(explode\angle) Else explode\x=explode\x+explode\power*Cos(explode\angle) explode\y=explode\y+explode\power*Sin(explode\angle) explode\angle=explode\angle-15 EndIf Especially that last but one line. |
| ||
After waking up in the middle of the night, and jotting a few things down on a notepad. I think I've got it sussed. I've added If explode\angle<=90 Or explode\angle>=450 explode\x=explode\x+explode\power*Cos(explode\angle) explode\y=explode\y+explode\power*Sin(explode\angle) Else explode\x=explode\x+explode\power*Cos(explode\angle) explode\y=explode\y+explode\power*Sin(explode\angle) If explode\angle<270 explode\angle=90 ElseIf explode\angle>270 explode\angle=90 ElseIf explode\angle=270 explode\angle=90 EndIf EndIf It now seems to look similar to exploding lemmings. Just not quite right. |
| ||
I remember Lemmings on the Amiga and the explosion effect had nothing at all to do with sines and cosines during the explosion. Use them to precalculate the start-points, nothing else. I believe this is what you're looking for: **EDIT** Obviously, change the writepixel to a rect and replace the argb% with separate r% g% and b% values. This is about the most expandable and fastest way I can think of to accomplish the effect you needed. I took a shortcut with precalculating the explosion, the initial veocities for the particles depend solely on the starting position. I think that works quite well though. **EDIT #2** Giving the lemmings their own x and y coords and having the particles x and y separate is a good idea if you want to impletement this in a real game. **EDIT #3** The way the explosion is calculated is just by creating a 180 degree arc so that it is more or less symmetrical. This means it looks good with only a few particles (no lopsided explosions). With too many particles, you can see that it just forms a semi-circular explosion. To get the 180 degree arc, I just divided 180 degrees into EXPLOSION_PARTICLES% which is a constant (needs to be!). For an explanation on the use of Types, please see http://www.blitzbasic.com/Community/posts.php?topic=51581 |
| ||
I think you're might be going about this wrong. You should probably use vectors. It makes everything much simpler. A vector is like a line pointing in a direction with an arrow on one end. You can imagine the starting point of the vector is at 0,0 which is the center of whatever object you are moving. So: Cx, Cy = The center of your lemming. Px, Py = The location of the pixel. Each pixel in the lemming should fly away from the center. The direction it goes is defined by a vector. That vector will be pointing in the same direction as the point is in relation to the center of the lemming. So, we calculate our vector like so: Vx# = Px# - Cx# Vy# = Py# - Cy# Then, we need to normalize our vector. Normalizing means making the vector's length equal 1. We do this so we can use it as a direction, and multiply it by a speed to tell us how far to move the pixel. Get the length of the vector: D# = Sqr(Vx#^2 + Vy#^2) And divide the X and Y components of the vector by the length: Nx# = Vx# / D# Ny# = Vy# / D# If we now calculate D again we would get 1. We now have a NORMAL. The normal tells us how far and in which direction the point should move on each axis for each 1 unit of speed. If we want to the pixel to move at 10 pixels per second, we multiply Nx and Ny by 10, and then add Nx and Ny to the position of our pixel each frame. Anyway, we now have a normal for each pixel. Calculate this and put it in your type. In addition, store a value Speed#. You may want to store the value D# which you calculate when creating your normal, in Speed#. You may want to multiply it by some constant though. If you do this, then pixels which are 4 pixela away from the center of the lemming will move at a speed of 4 pixels per second away from the center. Pixels near the center will not move as quickly. This will look realistic and cool. If you multiply it by like 10, that is. So: Pixel\Speed# = D# * 10.0 Once you have stored all your pixels in your type, loop through them each frame, and move them like so: Pixel\Px# = Pixel\Px# + (Pixel\Nx# * Pixel\Speed# * SecondsPassed#) Pixel\Py# = Pixel\Py# + (Pixel\Ny# * Pixel\Speed# * SecondsPassed#) SecondsPassed# is the number of seconds the last frame took to render. To calculate it, store the time at which the last frame was rendered, and subtract that from the tme at which the current frame is being rendered. That is the number of milliseconds which has passed. Divide this number by 1000 to get the number of seconds, which will be much less than 1.0. Like so: SecondsPassed# = Float(MillisecondsPassed) / 1000.0 There's one other major thing you need to do though. If you just do the above, everything will fly out from the center, but never fall. You need to add gravity. Before moving the pixel each frame, add gravity to it's normal and speed like so: Vx# = Pixel\Nx# * Pixel\Speed# Vy# = Pixel\Ny# * Pixel\Speed# Vy# = Vy# + Gravity#*SecondsPassed# Then convert back to speed and direction like so: Pixel\Speed# = Sqr(Vx#^2 + Vy#^2) Pixel\Nx# = Vx# / Pixel\Speed# Pixel\Ny# = Vy# / Pixel\Speed# THEN move the pixel. Now the center pixels will just fall from where they are, and the putside ones will fly out with great force, and then fall. |
| ||
sswift: Pretty sure that Psygnosis weren't calculating square roots for their lemming explosions, not on a 7MHz Amiga ;) Nice solution though. |
| ||
Cor! That looks loads better! It also looks more like the lemmings I remember now too. I'll have a look through that code, and try to figure out how it all fits together. Thanks! =) |
| ||
If you want to ask how or why concerning any of the code, I'll be at the keyboard for most of the day ;) |
| ||
After reading through it, it's fairly straight forward. Although the first line..Const EXPLOSION_PARTICLES% = 10 -1 ..has me a bit puzzled. Is the -1 meant to be there? If so, what does it do? I took EXPLOSION_PARTICLES% as being 10 when I looked through the code. |
| ||
That's just a habit of mine. I like to make my code as readable as possible. I read that line as:EXPLOSION_PARTICLES% gives me 10 when using an array. |
| ||
sswift: I think trig is a simpler. vinylpusher: Personally, I prefer: Const EXPLOSION_PARTICLES% = 10 Dim startexplosion_x#(EXPLOSION_PARTICLES - 1) For i = 0 to EXPLOSION_PARTICLES - 1 etc. Finally, here's my remix of vinylpusher's code: |
| ||
Hmm, yes. You've removed the distinction between an explosion and the particles associated with it. Your version is nicer to read and easier to follow. I had the Lemmings game in mind when I was scribbling my code. Could expand my code quite nicely into an unlimited Lemming state machine thingy without too much head-scratching. Yours as well, of course, but I still like mine ;) |
| ||
Hmm Why would you NEED to do any SQRing? You could cheat and just use CX#=Rnd(-1,1):CY#=RND(.2,1) [code] For each pixel and just use [code] cy#=cy#-.1 on each frame which adds gravity. I will code it a bit simpler later, its not difficult at all and i dont understand why Sswift is using SQR and squaring at all, though his general technique is goo. |
| ||
You don't NEED to use square root, but if you want to do things the RIGHT way, you should. :-) |
| ||
Don't need to do things the Right way for it to look good! ;) [edit] By the way- I meant Good, not goo :) |
| ||
You've removed the distinction between an explosion and the particles associated with it. Once an explosion has occurred, I can't think of any reason to need to know which particles came from which lemming or vice versa. Also, the lemming that exploded will likely no longer exist. ;) Each pixel in the lemming should fly away from the center. Oh, I somehow missed this statement. sswift is going for a completely different effect than the rest of us. It's been too long since I played the game, so I don't recall which is correct (I'm betting on sswift though.) An alternate approach would involve Atan() to find the angle to the pixel, then Sin() and Cos(). sswift's method (involving Sqr()) is probably simpler. |
| ||
Here is a picture of a lemming exploding: http://home.wanadoo.nl/lemmings-solution/lemmings/images/lemmings%20tricky/18%20-%20It's%20Lemmingentry%20Watson.gif Apparently whatever dirt they take out is also part of the explosion. That means that the center of the explosion must be below the surface of the ground beneath the lemming. |
| ||
Hey thanks for these little explosion effects! Quite useful even to apply to a single object, giving it a random angle. |