views:

48

answers:

1

Hi guys. I am designing a small game wherein objects are attracted by multiple objects at once. What I am doing is plotting the course that the shots of these objects will take.

To calculate the pull of the planets, I am using this formula: gravityStr/distToTarg^2 (pseudo code). Where my problem lies is in calculating the direction (and subsequently the cos, and sine) that I need the shot to be moved by. Below is the code for my "Shot" class.

Other classes not included here are the "Planet" class, which has an X Y value (where the upper left of the form is 0,0). As well as a gravity (the strength of the pull).

What seems to occur, is the planets REPULSE my shots. I've tried reversing the sign of planetModY and planetModX, but I get even STRANGER effects.

It is worth noting that the shot appears to work when it originates to the upper right of the planet, and when it is traveling down and to the right.

I would really appreaciate some answers, as well as code corrections.

C#:

public class Shot
{
    static public Shot[] Shots = new Shot[0];
    static public int shotSteps = 3000;

    public const double rad = Math.PI / 180;

    PointF[] PointFs = new PointF[0];

    public Shot(int x, int y, int dir, int pow)
    {
        addShot(this);
        double cos = Math.Cos((dir * rad));
        double sin = Math.Sin((dir * rad));

        addPoint(new PointF(x, y));
        addPoint(new PointF((float)(cos * pow + x), (float)(sin * pow + y)));

        for (int step = 2; step < shotSteps; step++)
        {
            PointF prevPrevPoint = PointFs[step - 2];
            PointF prevPoint = PointFs[step - 1];

            Double radians = Math.Atan2(prevPoint.Y - prevPrevPoint.Y, prevPoint.X - prevPrevPoint.X);
            Double curCos = Math.Cos(radians);
            Double curSin = Math.Sin(radians);

            PointF curPoint = new PointF(prevPoint.X + (float)curCos * pow, prevPoint.Y + (float)curSin * pow);


            int planetModX = 0;
            int planetModY = 0;

            for (short index = 0; index < Planet.Planets.Length; index++)
            {
                Planet curPlanet = Planet.Planets[index];
                double planetRadians = Math.Atan2(curPoint.Y - curPlanet.Y, curPoint.X - curPlanet.X);
                double planetCos = Math.Cos(planetRadians);
                double planetSin = Math.Sin(planetRadians);

                double planetShotDist = distTo(curPlanet.X, curPlanet.Y, curPoint.X, curPoint.Y);

                double pullPower = curPlanet.Gravity / (planetShotDist * planetShotDist);
                planetModY += (int)(planetSin * pullPower);
                planetModY += (int)(planetCos * pullPower);
            }

            curPoint.X += planetModX;
            curPoint.Y += planetModY;

            addPoint(curPoint);
        }
    }
+1  A: 

Hint! Each object not only has a position, but also velocity. At each step the velocity changes per the object acceleration, and the position per the velocity (2nd order system). What you need to do if figure out what the total contribution of each gravity pair is the object and add them vectorially.

If I am speaking Greek to you (besides because I am Greek), then you need an introduction to Physics book where they describe vector mechanics.

Also consider the case where two objects are too close to each other resulting in large gravity forces and large distance steps. This is not a trivial problem to make it stable enough to be enjoyable, but it is possible. If you succeed, it will be very gratifying.

Here is what somebody else has done in a similar fashion (Gravity Screensaver)

jalexiou
plus 1 for being awesome
Lavinski