0

So I am trying to move a projectile in the direction that is indicated by the mouse position on the screen. I already have converted the mouse coordinates into in-game coordinates however I can't figure out how to correctly move the projectile into the proper direction. I am trying to use a slope to move the projectile but it doesn't seem to want to grab the correct slope so I end up with them flying in completely wrong directions. Here are some bits of code that I am using. Any help on this would be greatly appreciated as I am a little over my head in this.

NOTE: The projectile does NOT follow the mouse. It should save the coordinates and then head in that direction noting that it can also go past the given coordinates at the same rate.

Entity Creation

int[] mousePos = MouseManager.getCalculatedMouseCoordinates();
                float deltaX = mousePos[0] - GameManager.x;
                float deltaY = mousePos[1] - GameManager.y;
                float m = deltaY/deltaX;
                System.out.println(m);
                GameManager.currentWorld.addEntity(new EntityProjectile(GameManager.x, GameManager.y, 30, m, 50, "fireball"));

Projectile Class

    package UnNamedRpg.Player.Entity;

public class EntityProjectile {

    private double x, y;
    private int entityID = -1;
    private int speed;
    private double headerX, headerY;
    private int renderHeading;
    private double range, currentRange = 0;
    private String texture;
    private double factor = -1;
    public EntityProjectile(double startX, double startY, int speed, double headerX, double headerY, double range, String texture){
        setX(startX);
        setY(startY);
        setSpeed(speed);
        setHeaderX(headerX);
        setHeaderY(headerY);
        setTexture(texture);
        setRange(range);
    }

    public void doTick(){
        double vx = this.x - this.headerX;
        double vy = this.y - this.headerY;
        if(this.factor == -1){
            double length = Math.sqrt((vx*vx) + (vy*vy));
            double factor = this.speed / length;
            this.factor = factor;
        }
        vx *= factor;
        vy *= factor;
        this.x = vx;
        this.y = vy;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getRenderHeading() {
        return renderHeading;
    }

    public void setRenderHeading(int renderHeading) {
        this.renderHeading = renderHeading;
    }

    public int getEntityID() {
        return entityID;
    }

    public void setEntityID(int entityID) {
        this.entityID = entityID;
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public String getTexture() {
        return texture;
    }

    public void setTexture(String texture) {
        this.texture = texture;
    }

    public double getRange() {
        return range;
    }

    public void setRange(double range) {
        this.range = range;
    }

    public double getCurrentRange() {
        return currentRange;
    }

    public void setCurrentRange(double currentRange) {
        this.currentRange = currentRange;
    }

    public double getHeaderX() {
        return headerX;
    }

    public void setHeaderX(double headerX) {
        this.headerX = headerX;
    }

    public double getHeaderY() {
        return headerY;
    }

    public void setHeaderY(double headerY) {
        this.headerY = headerY;
    }

    public double getFactor() {
        return factor;
    }

    public void setFactor(double factor) {
        this.factor = factor;
    }
}

Update Position Method

--Now called in EntityProjectile class every tick instead of it happening in the world tick.

Cyphereion
  • 71
  • 11

2 Answers2

1

Moving towards a given point is relatively simple with some basic vector math. The vector you want to move along is calculated simply by coordinate subtraction:

vx = objectX - mouseX
vy = objectY - mouseY

But you probably want to move your object a little slower than bam there, so you need to scale the vector to a desired length (equals speed per game tick). The current length of the vector is obtained by the pythagorean sqrt(a * a + b * b). To scale the vector to a given length just multiply the components by the required factor:

double targetLength = 5.0; // chosen arbitrarily
double length = Math.sqrt(vx * vx + vy * vy);
double factor = targetLength / length;
vx *= factor;
vy *= factor;

There you have your speed components x,y to be used as delta per game tick. The 5.0 is the "speed" at which the object will move per tick.

EDIT: @Cyphereion About the length of the vector, thats geometrically speaking the base of a triangle, see https://en.wikipedia.org/wiki/Pythagorean_theorem (considered common knowlegde).

Once you have that, you just need to adjust the length of each component by figuring out a scaling factor that makes the base line come out as the desired "speed" length. The original values of the components (vx, vy) represent a vector (see: https://en.wikipedia.org/wiki/Euclidean_vector#Representations) encoding the direction to move to.

Scaling the vector's length adjusts the speed at which your object moves when you apply the vectors components as delta to its position (which is just vector addition). I swapped around the division length/targetLength initailly (now fixed), so the speed variable had a reversed meaning (larger = slower instead of larger = faster).

Durandal
  • 19,919
  • 4
  • 36
  • 70
  • Oh umm that doesn't seem to work exactly as the results keep giving me infinity. I am calculating it here(look at NEW-CALC on question) (Note that the mouse position is saved to the object before-hand.) – Cyphereion Oct 11 '15 at 18:36
  • Could you explain a bit more as to how exactly target length is the speed? It seems to me like I can't change my projectiles x value which I have to change. I feel like you left out a LOT of information as far as this goes. – Cyphereion Oct 11 '15 at 21:07
  • @Cyphereion I don't think I was overly brief, but this naturally depends on ones background and how much math from school has *stuck*. Please see my edit for references. – Durandal Oct 12 '15 at 16:14
  • It seems to only want to change the values the first time that it runs this, every other time it just sits there looking pretty. You can see the results here, I ran this through 50K iterations with only the first 2 or so actually changing. [link](http://pastebin.com/NuYyypjb) – Cyphereion Oct 12 '15 at 22:14
  • EDIT: Also i've noticed when I save the factor (which I assume never changes) I get some VERY wierd results. [link](http://pastebin.com/VMSVdJ55) – Cyphereion Oct 12 '15 at 23:33
  • @Cyphereion I have not the faintest idea what to make of your data. Adding a (constant) speed component vector to a position will obviously alter the position at every game tick. If it *doesn't* you need to check your general logic. Since youre talking about "saving" the factor I can only guess that youre making things more complicated than they need to be. A movable 2D-object needs only 4 variables, pos(x, y) and speed(x, y). You initialized speed *once* to target it and on each game tick simply add the speed pair to the pos pair, nothing more. – Durandal Oct 13 '15 at 11:53
  • Could this be caused by the fact that the projectile will almost always go past the given target coordinates? I really don't see anything wrong with my code, I have updated it above so that you can point out my mistakes if there are any to be made. – Cyphereion Oct 14 '15 at 01:29
0

If you're having trouble with your sprite then use the setDirection() you have there to augment the trajectory. In these examples you have all good code but you're missing restting the direction when your mouse changes direction. That's all I can see. Good luck!