astroids

Started by
2 comments, last by flucknugget 22 years, 2 months ago
I''m pretty new to game programming, and programming in general, so I wasn''t sure if I''d post this here or in the beginners forum. I didn''t have to move my mouse as far to go to this forum, so I decided to post it here. Alright, here''s the dilly yo. I''m making a 2d astroids clone, hopefully with muchos powerups and special features and stuff. So far I have a ship that can shoot, a bunch of astroids that break into smaller astroids when they get shot, and these badass looking moving layered stars in the background. The way I had the physics of the ship work before is if you press up, it just increases the ship''s speed variable and sets the ship''s movement angle to the ship''s current facing angle, and if you press down it does the same thing only decreases the speed. After playing a different astroids clone, I realized that astroids is actually not like that at all. There''s only thrust, no slow down, and when you thrust it doesn''t just change the direction the ship is moving in, it sort of changes it a little bit.. and if you want to slow down, you have to turn the ship around and thrust some. If that didn''t make any sense, just go play astroids again to see what I''m talking about. I''ve been trying to figure out how to emulate those astroids ship physics for a couple of hours now, to no avail. So, for any of you experienced astroids programmers out there, what happens to the speed and the move angle based on the direction the ship is facing when you thrust? Let''s call the speed "speed" and the angle the ship is moving in "move_angle" and the angle the ship is facing "ship_angle". I was thinking that if you thrust, if ship_angle is within 90 degrees of move_angle, then it speeds up and changes move_angle to halfway between move_angle and ship_angle, and if it''s not within 90 degrees it just slows down the ship. I tried that, and I failed miserably. Either that just isn''t how it works, or my code was horribly screwed up, I''m not sure which. But anyway, any code would be helpful, or even just an explanation of what happens when you thrust. Thanks. flucknugget
- f l u c k y p o o
Advertisement
Are you familiar with vectors? That is basically how the physics in Asteroids work. Your ship has an X speed and a Y speed (together they form your velocity). Depending on what angle you are facing, your thrust is going to effect the X and Y speeds differently.

Going into a whole dissertation about vectors and acceleration (and the associated trigonometry) is enough to fill a chapter in a physics book, so I''d just recommend looking up vector mathematics on google or something.

-------------
SpaceRook
Latest Project: Paper Shredder
Visit my homepage for other projects!
Ok, thanks. I'll try doing that, and learning some physics while I'm at it...

Edited by - flucknugget on February 6, 2002 8:25:54 PM
- f l u c k y p o o
This forum is certainly appropriate for your post.

I can add some details to what SpaceRook posted. Basically, for asteroids you''re looking to do simple particle physics. This is very nearly the simplest kind of physics you can do. The ship itself rotates visually, and the angle of the ship determines the direction of thrust. A very important thing to note is that you do not need to deal with the physics of rotating bodies. The ship in asteroids does not behave in a physical way due to rotation. Physics is only used for translation of the center of mass of the ship. (And this is the case with particle physics in general.)

Thrust is a force vector. There''s this cool law called Newton''s second law of motion, which looks like this:

F = ma

F is a force vector. For asteroids, it is just exactly the thrust. M is mass. You can just pick mass = 1, and adjust your thrust magnitude to get things to look good. a is acceleration, also a vector. So, once you have thrust you can calculate acceleration. I''ll separate the vectors into their components to give you something you may be able to use:

a.x = Thrust.x / m;a.y = Thrust.y / m;a.z = Thrust.z / m; 


Now, that acceleration causes the slight change in velocity (another vector!). At each frame you have to update velocity according to acceleration. So, first calculate thrust (based on angle of ship and some magnitude you picked to look good (magnitude is zero unless you hold down the button to apply thrust). Then calculate acceleration. There are a few ways to update velocity. The high school physics way to do it is with a closed form solution, but in game development you often proceed rapidly to numerical methods, which is what I''ll outline here. To update acceleration, you have to recognize that by definition:

a = dv/dt,

where v is velocity vector and t is time. The d''s represent a derivative. Acceleration is the change in velocity over time. You can "integrate" dv/dt to get v. I won''t give the closed form solution---its in any elementary physics book. There are also many many different numerical ways to integrate dv/dt. I''ll give you the simplest method, which should work fine for this problem. It''s called the explicit Euler method (aka simple Euler). It goes like this:

a = (v(new frame) - v(previous frame))/dt

where dt = time(new frame) - time(previous frame)

You want to find v(new frame), so solve algebraically:

v(new frame) = dt*a + v(previous frame)

Or, expanding out into working code

v.x = dt*a.x + v.x;v.y = dt*a.y + v.y;v.z = dt*a.z + v.z; 


Its that simple! Now, you''ll no doubt need a good way to calculate dt. In reality, the time between frames will always fluctuate slightly, and for sophisticated physics (more sophisticated than this), it can be a good idea to quantize dt so its a fixed value from frame to frame. This is for stability and consistency reasons. You shouldn''t have a problem here. Just choose a method for measuring the time between frames and use that. With Windows, you can use the QueryPerformanceCounter() function.

The thrust for asteroids will always be something like:

Thrust.x = thrust_magnitude * cos(rotation_angle);
Thrust.y = thrust_magnitude * sin(rotation_angle);
Thrust.z = 0.;

And for the first frame, you want the ship to be stopped:

v.x = 0.; v.y = 0.; v.z = 0.;

You''ll notice that this simple physics works in 2D or 3D. It would be moderately easy to deal with realistic collisions, say if two asteroids of different sizes bump into each other and bounce apart.

So, that should get you started quickly!

Graham Rhodes
Senior Scientist
Applied Research Associates, Inc.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net

This topic is closed to new replies.

Advertisement