1
\$\begingroup\$

I am trying to create a program where a character shape will be constantly drawn towards the centre of a planet shape. I have taken on previous advice into using physics equations to generate the desired effect yet I think I am missing some and therefore it does not work (I am only using v^2=u^2+2as). Am I over complicating things? All I need is for the player object to be constantly drawn towards the centre of the planet object; there will be no need for other planet objects to come into play and affect the player's gravity.

edit: To clarify, my question should have been "where did I go wrong?". I have now since solved the problem with the answers posted below, which were present because I wasn't going about trying to achieve what I wanted the right way. I didn't calculate the actual direction to move in as expected, and so the character could not move in the expected direction.

Here is my Main.as:

package
{
import flash.display.InteractiveObject;
import flash.display.Sprite;
import flash.events.Event;
import Math
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.events.KeyboardEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.*;

/**
 * ...
 * @author Me
 */
public class Main extends Sprite 
{
    public var planet1:Planet;
    public var character1:Character;
    public var initialXVelocity:Number = 0;
    public var initialYVelocity:Number = 0;
    public var finalXVelocity:Number;
    public var finalYVelocity:Number;
    public const gravitationalAcceleration:Number = 3;
    public var xDistance:Number;
    public var yDistance:Number;



    public function Main() 
    {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(e:Event = null):void 
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        // entry point
        planet1 = new Planet;
        character1 = new Character;

        //place entites in position to test note: planet 1 is 100*100 pixels, character 1 is 10*10 pixels
        planet1.x = 350;
        planet1.y = 250;
        character1.y = 100; //295
        character1.x = 396; //395
        addChild(planet1);
        addChild(character1);

        //Make sure character has gravity applied constantly
        setInterval(playerMove, 1000);

    }

    public function playerMove():void
    {
        //Calculate the distance between the character and the planet in terms of x and y coordinate
        xDistance = (character1.x + 5) - (planet1.x + 50);
        yDistance = (character1.y + 5) - (planet1.y + 50);

        //Make sure this distance is a positive value
        if (xDistance < 0) {
            xDistance = -xDistance;
        }

        if (yDistance < 0) {
            yDistance = -yDistance;
        }

        //Calculate velocity using physics equation v^2=(u^2)+2as
        finalXVelocity = Math.sqrt((initialXVelocity * initialXVelocity) + (2 * gravitationalAcceleration) * xDistance);
        finalYVelocity = Math.sqrt((initialYVelocity * initialYVelocity) + (2 * gravitationalAcceleration) * yDistance);
        /*trace(initialXVelocity);
        trace(gravitationalAcceleration);
        trace(xDistance);
        trace(finalXVelocity);
        trace(initialYVelocity);
        trace(gravitationalAcceleration);
        trace(yDistance);
        trace(finalYVelocity);*/

        //Make sure the character is moving towards the centre of the planet at all times by reversing the appropriate velocity once it passes the axis of the centre of the planet
        if (planet1.x < character1.x) {
            finalXVelocity = -finalXVelocity;
        }

        if (planet1.y < character1.y) {
            finalYVelocity = -finalYVelocity;
        }

        //Update the current velocity before new velocity is calculated
        initialXVelocity = finalXVelocity;
        initialYVelocity = finalYVelocity;

        //Send the character into the correct direction
        character1.x += finalXVelocity;
        character1.y += finalYVelocity;
    }

}

}
\$\endgroup\$
  • \$\begingroup\$ I think that you should describe better that "this don't work". What exactly is happening? \$\endgroup\$ – DH. Feb 4 '16 at 12:52
  • \$\begingroup\$ Please clarify: player position + 5 and planet position + 50 mean that your coordinates are the top left corner of the object sprite and then you need to add the half extent to move to the center of the sprite, right? Newton should be the answer here even if you are considering only a single planet in the system. \$\endgroup\$ – Hatoru Hansou Apr 6 '16 at 5:50
  • \$\begingroup\$ If the answer from DMGregory was what helped you solve your issue, you should mark it as Accepted :) \$\endgroup\$ – Vaillancourt Apr 12 '16 at 12:02
1
\$\begingroup\$

I'll use vector notation to be concise. You can translate this into individual vectorX and vectorY numbers if you're not using a vector math library, just be careful to calculate the length below using both components.

// Get a vector pointing into the planet.
Vector offset = planetPosition - playerPosition;

// Note that x & y aren't separable:
// you need to consider them together to get the length
// (Pythagorean theorem)
float distance = length(offset);

// Scale the vector to unit length.
Vector direction = offset/length;

// To get constant acceleration regardless of distance:
// (near surface approximation)
Vector acceleration = gravityStrength * direction;

// OR, to get Newtonian gravitation: 
// (weaker further away, following inverse square law)
Vector acceleration = gravityStrength * direction/(length * length);

// Euler integration for simplicity.
// Other options work too.
playerVelocity += acceleration * deltaTime;

playerPosition += velocity * deltaTime;
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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