Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm currently making a game with my own game engine which I've written in C++ and I'm using the most recent directx SDK.

The game is a top down space shooter (with a pretty interesting twist) and I'm looking to have a sort of nebula effect that the player will fly through. I really want to try and nail that nice tactile feel of hundreds of particles moving out of the way of the player ship as it flies into them. Somewhat like how particles would move out the way of the player in Geomtry Wars on XBLA.

I'm an experienced programmer when it comes to C++. I don't know, however, how to start implementing this effect. Does anyone have any cool ideas or design choices I might want to look into? Feel free to answer to any degree of depth you fancy.

share|improve this question
add comment

1 Answer

up vote 61 down vote accepted

It's a cool idea. You'd need some sort of diffusion gradient around your ship. There are three physical models I can think of that you might want:

  1. You want it to seem almost like it's a liquid medium, where the pressure gradient rebalances, i.e. once you've passed some particles they move back into your wake (like water behind a boat). In this instance, particle's positions are absolute, and it's only their relation to the player which temporarily modifies their rendering position. This is a bit like when you pass a thick magnifying glass over things, and the diffraction seems to make them move -- but only until you move the glass away. In this case, your ship is the glass.

  2. If you want them to move away from the ship, and carry on moving once they've moved. This is like standard physics in generally empty space where there are no (or very small) pressure gradients.

  3. You want to move the particles away from the ship swiftly as it approaches, as in (1) and (2), but once the ship is gone, the particles will slowly rebalance themselves to be equidistant in your wake.

Common to all three solutions: you need to have a diffusion field that moves with your ship. In this example we will make it circular. You then detect vector, call it v1, between the ship and each particle within that region. Push your particle away along that vector. How strongly you will push it away will depend on it's distance from the ship: use 1 - v1.magnitude. This formula will give you a linear strength, however you could modify it to use something else like a circular strength curve that diminishes in strength toward the edges. This would give it more of a look as though there is a spherical rather than circular pressure gradient around the ship.

For solution 1: All you now do is modify the render position of that particle (that is, the sprite position) on every render update, by this vector. Because you're doing it this way, this is purely a rendering effect and has no effect on the particle's actual world position. So you add the world position to the render offset (v1) and you now have nicely displaced particles as you move past toward or beside them, and smoothly reverting particles as you pass by (behind you).

For solution 2: Instead of just applying v1 to the view position, apply it on each logic update, to the particle's position. So, p1.position += v1. So you are applying an accelerative force to the particle, which translates into velocity. Probably, you'll want each particle's velocity to be dampened so that they they will gradually slow down and come to a halt once you've passed. You can see how this solution will result in bunched-up particles in your nebula, because they will never rediffuse. Not very realistic, I'm sure, since nebulae have pressure gradients within them, no matter how weak in reality.

For solution 3: Same as (2), but in this case you're going to have to rediffuse your particles. To do this easily is a bit of a brute force approach, but since these are only particles and thus eye-candy, you probably don't need to cover a huge area of interest (probably only a radius of playerPosition + maxPlayerSpeedPerTick, or whatever rectangular area circumscribes that, for logic purposes). Each particle will apply a force on each other particle in within the area of interest. They will apply forces based, once again, on their distances from one another. Calculate all interparticle forces in a single sweep across the area of interest, and then apply all forces in a single sweep. Lastly, make sure that you only perform this inter-particle force processing on particles that have zero velocity. And once any given particle reaches some minimum speed, cut it's velocity vector to zero, so that it's no longer using up processor time.

There are all kinds of diffusion formulae etc. out there, but I think in this case a simple solution works best.

share|improve this answer
    
Mate, unfortunately I don't currently have the reputation to upvote your answer (and I'd only be able to do it once, which is less than it deserves). You absolutely nailed what I'm looking for in your first solution. Fantastic answer. Honestly. Thanks! –  Matt McDonald Sep 1 '11 at 10:29
    
Total pleasure Matt, it's a good question & worth flexing the brain for! –  Nick Wiggill Sep 1 '11 at 10:30
    
I've also decided that with very little change in code I could have this apply to smaller asteroids within a belt. Thanks again. –  Matt McDonald Sep 1 '11 at 10:36
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.