A co-ordinate problem.

OK so this may be a long a complicated problem, I have made a Boomerang class (yes it’s that guy) that determines the boomerangs start point by getting the X,Y position of the player and then modifying these co-ords so the boomerang will appear from the centre of the player.

First problem: It doesn’t, it appears significantly higher and to the left of the player.

The class then creates the path of the boomerang and stores it in a point array and every time the sprite is updated moves it to the next point in the array.

Second problem: Although it does move in a straight, diagonal line, it moves vertically down from the start point, even though the path is calculated by adding X,Y positions to the last “node” of the path.

I will post the class and see if you can make head or tails of where the problem is coming from, part of me thinks that it may be using points to store the X,Y co-ords, as these use Java’s co-ordinate system and points aren’t used throughout the rest of the code. I wanted someone else’s opinion before I rewrite the class or the rest of the engine to use or not to use points.

Here’s the class:

public class Boomerang extends Sprite
{
    private static double DURATION = 0.5;  // secs
    // total time to cycle through all the images
    private int period;    // in ms; the game's animation period
    private BricksManager brickMan;
   
    private int speed; //used to calculate how many nodes to create along the
                       //boomerangs path.
    protected int locx, locy;
    private Boolean isVisible;
    private JumperSprite rat;
    private Point startPoint = new Point();
    private Point nextPoint = new Point();
    private int nodeLength;
    private int nodes = 0;
    private Point[] boomPath;
    
public Boomerang (int x, int y, BricksManager bm, ImagesLoader imsLd, int p, String name, JumperSprite js)
{
super(x, y, 30, 32, imsLd, "Boomerang");
 
locx = x;
locy = y;
super.setImage(name);
speed = 3;
period = p;
isVisible = false;
rat = js;
boomPath = new Point[20];
    }

public void fire(){
    int x;
    int y;
    int ratx = rat.getXPosn();
    int raty = rat.getYPosn();
    System.out.println("ratx:" + ratx);
    System.out.println("raty:" + raty);
    
    Point endp = new Point();
    int midx = rat.getWidth()/2; //get the mid point of rat' sprite
    //System.out.println("midx:" + midx);
    int midy = rat.getHeight()/2;
    //System.out.println("midy:" + midy);
    startPoint.setLocation((ratx + midx), (raty - midy));
    //set the start of boomPath to the mid 
    //positions.
    //System.out.print("startPoint original" +startPoint);
    boomPath[0] = startPoint;
    
    PointerInfo MousePosn = MouseInfo.getPointerInfo();
    
    endp = MousePosn.getLocation();
    
    nodeLength = (int) (startPoint.distance(endp)/(20-speed));
    //System.out.println();
    //System.out.println("nodeLength:" + nodeLength);
    //cut the distance into equal segments to increment boomPath
    
    for(int i = 0; i<(20- speed); i++){   //add points to boomPoint using nodeLength increments
        //System.out.println();
        //System.out.println("boomPath[0].x:" + boomPath[0].x);
        //System.out.println();
        //System.out.println(i + 1);
        
        nextPoint.setLocation((boomPath[i].x - nodeLength), (boomPath[i].y - nodeLength));
        
        boomPath[i+1] = nextPoint;
        
        
        //System.out.println();
        //System.out.println("boompath[" + i + "]:" + boomPath[i]);     
        
    } //end of for loop
    
    isVisible = true; 
    
            
  }//end of fire()

public boolean isVisible(){
    return this.isVisible;
}

public void update() {
   if(isVisible){
       if(nodes < boomPath.length){
       locx = boomPath[nodes].x;
       
       //System.out.println("boomPath[" + nodes + "]" + "locx:" + locx);
       locy = boomPath[nodes].y;
       //System.out.println("boomPath[" + nodes + "]" + "locx:" + locy);
       nodes ++;
        }
       }
    }//end of update()
   


}//end of Boomerang

Cheers for any help you can give me :slight_smile:

Have you tried drawing all of your points to see where they actually are?

There should be nothing wrong with using Point, but I’m not sure from your description what your actual bug is. An image might help?

Every path node gets the same point object.

how so?

Because of this:
boomPath[i+1] = nextPoint;

Every node is nextPoint.

Yes but before

boomPath[i+1] = nextPoint;

nextPoint is calculated for every iteration:

nextPoint.setLocation((boomPath[i].x - nodeLength), (boomPath[i].y - nodeLength));

Ok so Orangy Tang here’s a rough approximation of what currently happens when you throw the boomerang:

The green line is the path that the boomerang takes, the red cross is the mouse pointer position at time of throwing the boomerang.

I have tried subtracting the nodeLength from the X and Y co-ord (line 67) as I having read up on Java’s co-ord system, it seems to use a system by which 0,0 is the top left of the screen. Confusingly whether I add or subtract nodeLength the boomerang still takes a downwards diagonal path.

65K is right, you’ve got an array where all the indexes refer to the same Point object. You want something like:


boomPath[i+1] = new Point((boomPath[i].x - nodeLength), (boomPath[i].y - nodeLength));

Of course then it probably still won’t work as your usage of nodeLength is pretty weird. What do you think you’re doing there?

nodeLength is essentially the distance between each node, may be confusingly named, but I know what I mean and ultimately that’s all that matters as this is a one man project :stuck_out_tongue:

what I think I’m doing is:

The next node is at the X position of the current node - the nodeLength and at the Y postion…etc.

But the nodeLength is only the length between nodes along the line. The actual x distance between two nodes is different from the actual y distance between two nodes, but you’re trying to use one value to step both.

By now hopefully you’ll see that you need separate xNodeLength and yNodeLength.

If I want to calculate a path with a 1:1 ratio i.e:

(I realise that triangle does not have a 1:1 ratio)

surely the X and Y would need to be the same.

Also, why does my boomerang travel on a path diagonally downwards whether I add or subtract nodeLength, surely, even if my game logic, so to speak, is flawed, changing whether the value is added or subtracted should change the vertical direction of the path?

you know when you’re really tired and you say things that are silly because you are really tired and say silly things that are silly.

Yes, I have done that, of course I need a different Y value worked out from the angle of the mouse pointer relative to the X perpendicular (also still tired so that may sound like crap, but again I know what I mean :P)

I’m glad you’ve brought that to my attention, but the main problem still remains, what the hell is going on!?

So, do create new point objects now like Orangy Tang suggested ?

Ok, so I’ve added the code you suggested, I’ll code in the calculation of the Y path when I’ve fixed the problem that my boomerang travels diagonally downwards, any suggestions especially as changing the operator like so:

From:

boomPath[i+1] = new Point((boomPath[i].x - nodeLength), (boomPath[i].y - nodeLength));

To:

boomPath[i+1] = new Point((boomPath[i].x + nodeLength), (boomPath[i].y + nodeLength));

makes no difference whatsoever!?

To explain why you can’t recycle the same Point object:

All objects in Java are actually pointers to objects, everywhere. That means that setting nextPoint for 50 different objects, even if it has different values on each setting, will always end up changing it for all 50 objects. If you know how pointers work, all Objects in Java are pointers to a spot in memory where the data is. So all 50 objects have different pointers, but all the pointers are pointing to the same data.

Creating new Points every time means you have distinct data for each (as desired), so you’re all good.

Primitive values (int, float, boolean, etc.), however, are pass by value. That means every time you change the value of one or put one as a parameter it is copied and is its own distinct value. So if instead of using a Point you were using two floats (x and y), then you would actually have no issues.

Make sense?

Yer, I totally get that, I am a noob at Java, but I have read a couple of books and while that was a while ago I have retained some of the knowledge, I just can’t get my head around the behaviour of the boomerang and how using floats as opposed to Points will change that?

I think I don’t understand what you are actually trying to do…
Shall the boomerang, well, fly like a boomerang, or in a diagonal line ?

well for now just a diagonal line, at the moment a lot of the code is place holder while I get everything together, the issue is the code isn’t working properly.

The boomerang is supposed to calculate its path from the centre of the player (I think I know why it doesn’t do that) towards the position of the mouse pointer when boomerang.fire() is called.

If you check the diagram (if you can call it that :P) above it shows that when mouse pointer is up and to the right of the player not only does the boomerang start above and to the left of the player (wrong) it then travels diagonally downwards(wrong), whereas it is supposed to travel diagonally upwards to the right i.e. towards the position of the mouse pointer.

Are you drawing things in OpenGL with LWJGL?

Maybe your xy(0|0) Coord is at the top-left, and so LWJGL’s Mouse.getY() is flipped.

Then you would need to get the Mouse position with Display.getHeight()-Mouse.getY().

Hope, that helps :slight_smile:

So, from a starting and a target point you want to calculate a set of intermediate curve points.
As input and output are clearly defined, I recommend to first develop a separate method just for this. No sprites, no mouse, no image required, thus no further interactions and no further possible error causes.

List calculateFlightCurve(Point start, Point target)