2D/3D Movement Woes (Please Help)

Started by
8 comments, last by Ichoris 17 years, 10 months ago
I'm trying to do movement of a shot from a gun. The gun base can rotate left and right, the gun tip can go up and down, and the shot speed can be changed. I need a way to calc the path of the shot if the gun is always pointing into the screen using the angles of the gun and the speed of the shot. I want to calc a set of x,y,z values that can be used to plot a sprite on the screen at a x,y location and use the z value to pick from a set of pre-scaled sprites. My hope is that it would seem like the shot is moving on the path into the screen and getting smaller as it does. I want to use a 2D sprite and not a 3D model. I can't figure out how to do this. Any ideas or source code?
Advertisement
What you describe shouldn't be too hard, but to offer suggestions we'll probably need more info, for example what graphics API you're using (if any), and whether the projectile is subject to external forces (gravity, wind) or just goes in a straight line.
I'm not using an API for the graphics but I have the ability to draw sprite frames. I'm using 'C' for my language. The projectile is subject to gravity. This should be a simple problem to solve but I can't figure out how.
Quote:Original post by Ichoris
I'm not using an API for the graphics but I have the ability to draw sprite frames. I'm using 'C' for my language. The projectile is subject to gravity. This should be a simple problem to solve but I can't figure out how.
If I'm understanding correctly, you're wanting to create some simple 3D effects with a 2D graphics API. Based on what you've said, this is how I'd proceed:

- Carry out the simulation internally in 3D, using floating-point variables.

- Find the initial direction of the projectile using the elevation and azimuth of the gun and spherical-to-Cartesian coordinate conversion.

- Find the initial velocity of the projectile as direction*speed.

- Update the projectile position each frame considering acceleration due to gravity and using simple Euler integration.

- Do some simple projection calculations to derive the screen x and y and sprite size from the world x, y and z positions.

There are quite a few details there, but unfortunately trying to do 3D with a 2D API puts more of the math in your hands (in a 3D API such as OpenGL, for example, it would be considerably more straightforward). Perhaps I'm making it more complicated than it needs to be, but I can't think of a simpler approach at the moment.
Yes, I concur with that line of attack. Simple Euler simulations of projectiles under gravity are easy enough.
Thanks for the input. My problem is that I don't have the math/physics skills to figure out the code. That was the point of my post. Can anyone provide a code sample? If not then maybe a few links so I can try to figure out how to do it myself. Thank You.
Trying to simplify the case since its a 2d game meant to appear 3d...

Am I correct in guessing that this is a 'shooting gallery' style interface?
Where your screen looks down a game shooting gallery, the gun can be aimed, and a psuedo 3d projectile travels down it to hit targets?

Rather than do a full 3d sim and 3d-to-2d screen projection...
We might be able to fake it:

assuming that your camera is fixed facing down the gallery, with gravity being perpendicular to your view. Then the projectile recedes at a constant rate. (Z depth from camera is linear to time)
So simply scaling the Sprite sizes linearly as time passes should give a decent impression of traveling away in 3d.

Similarly, as time passes if we push the projectile towards the center of the screen at a constant rate, we should be able to give the appearance of having a perspective effect, without actually calculating the projection matrix.
You can tweak the rate of this central motion till it looks 'real'.

Aiming your gun to the left or the right should be handled by having an initial left or right motion to the bullet, which is scaled (not accelerated) by the above central constant motion. (you want to maintain a linear relationship)

Lastly, for the effect of gravity all we have to do is represent a simple euler integration for the vertical position of the sprite... aiming the gun up or down simply affects the initial velocity here

Of course, all of that is a crazy hack, that requires a lot of artistic tweaking of the rates till it looks right.

To handle detecting Target hits, you'd do a simple 2d sprite overlap test, with the additional check that the bullet and target are scaled to the same 'size/fake-distance' to count as a hit.

I've also never done it before... but If you really want to avoid doing the real math... and can understand all the stuff I said, I think it should look passable. There have been plenty of ancient pre-3d console games who did more or less what I described.


EDIT:
my 'towards the center' motion idea to emulate perspective is possibly wrong.
the rate that an object moves to center should depend on its x(horizontal) location
might look ok as is though...
on the other hand, you might do some simple linear algerbra with triangles to get a more real result than the above 'fake'

[Edited by - haphazardlynamed on May 30, 2006 4:21:01 PM]
Yes. I have exactly a Shooting Gallery type layout. It is exactly as you said. Good idea about trying to fake it. I was hoping to learn the math and physics involved but faking it could be okay. Like you said it would take some tweaking of the numbers to make it work but it might do the trick.
The non-faking way:

  • The initial velocity of the bullet is determined by the orientation of the gun. If you have rotation and elevation angles (call them phi and theta), then the velocity vector is in the direction (cos theta sin phi, cos theta cos phi, sin theta) if sin is a rotation in the horizontal plane from the Y axis, and theta an elevation from horizontal. Those angles correspond to 'across' and 'up/down' with Y into the screen for a shooting-gallery style game. Multiply the appropriate direction vector by the initial speed of the bullet to get its initial velocity vector. The initial position of the bullet should be the end of the barrel, i.e. a known distance along that direction vector from the gun's position. I.e.
    Vector direction = new Vector(cos(theta)*sin(phi), cos(theta)*cos(phi), sin(theta));bullet.Position = gun.Position + (direction * gunLength);bullet.Velocity = direction * bulletSpeed;

  • Each frame, apply gravity (and any other force you like, air resistance maybe? wind?) to the bullet. This involves adding (0, 0, -gt) to its velocity vector for gravity, or more generally (F/m)t where F is the force on the object and m is its mass.
  • Each frame you also update the object's position by adding its velocity vector to its position vector. Whether you do this before applying the acceleration, after or with a combination of the two is up to you. These last two steps are the basic Euler integrator.
  • Now you have the bullet simulated in 3D. You can test for collisions with targets and so on in this space. Now all that remains is converting the 3D coordinates to 2D and a distance for sprite sizing. The simplest answer is to take the Y coordinate away (as the distance) and use (X,Z) for your screen coordinates.


Note that I'm using axes as follows: X is left/right, Y is in/out and Z is up/down.
Thanks for taking the time to post. This is exactly what I was looking for. I will give it a try. Thanks again for the detailed post!

This topic is closed to new replies.

Advertisement