1

I've been scratching my head on this for a short while now, and I'm really quite confused. Recently, I've been making a game, and I'm now trying to redo the way I had initially created the Camera class. It's now part of a Thread, and follows around a specific Location.

Here is the code:

public void run(){  
    while (game.isRunning()){
        if (!lockLocation) continue;

        while (center == null){
            EntityHandler handler = game.getEntityHandler();
            if (handler == null) continue;

            center = (Entity) game.getEntityHandler().getFirst(ObjectType.PLAYER);
        }

        xOffset = center.getLocation().getRawX() - (Game.WIDTH / 2) + (center.getWidth() / 2);
        yOffset = center.getLocation().getRawY() - (Game.HEIGHT / 2) + (center.getHeight() / 2);
    }

    try { thread.join(); } 
    catch (InterruptedException e) { e.printStackTrace(); }
}

So this bit of code here works... under certain conditions. Take note of the following lines:

xOffset = center.getLocation().getRawX() - (Game.WIDTH / 2) + (center.getWidth() / 2);
yOffset = center.getLocation().getRawY() - (Game.HEIGHT / 2) + (center.getHeight() / 2);

When I keep the lines as is, only the yOffset works. When I comment out the yOffset line, the xOffset will stop working (thus, both lines do not work).

When I comment out the xOffset line, much like the commented yOffset, the yOffset will no longer work, rendering the entire code useless.

Here's the weirdest part; they will both work when I put a System.out.println() method. (If one of them is commented and a System.out.println() is placed, the one that is uncommented will work).

I have no clue why the while loop is just ignoring certain lines unless its under certain conditions. There's absolutely no reason I can think of for it to do so. Any ideas?

  • sounds like `getLocation()` only works once. You need to define "stops working". – John3136 May 12 '16 at 23:12
  • 2
    This is almost definitely a [Data Race](https://docs.oracle.com/cd/E19205-01/820-0619/geojs/index.html) – Natecat May 12 '16 at 23:13
  • Arguably one of the most important parts of debugging is asking the right question. https://www.google.com/#q=scientific+method . *"I have no clue why the while loop is just ignoring certain lines unless its under certain conditions"* I guarantee you that your code isnt "ignoring certain lines". Not saying your question is bad just make sure you create a valid hypotheses. – ug_ May 12 '16 at 23:14
  • You need to give some more info. What threads are accessing/modifying `center`? A good start would be to use a `synchronized` block to tackle race conditions(as mentioned by @Natecat). – Debosmit Ray May 12 '16 at 23:16
  • That Data Race seems as though it's been the most accurate representation of my issue. How would I go about fixing a Data Race? (I'll attempt the use of a synchronized block) – Parker Hawke May 12 '16 at 23:18
  • Using a debugger would be a great idea. Put breakpoints at the start of the `run()` method. Traditional debugging might not be good enough. You need to break the VM instead of the thread [[read more here](http://stackoverflow.com/a/9903421/1692706)] – Debosmit Ray May 12 '16 at 23:20
  • Adding a synchronized block around the xOffset and yOffset changes seems to have fixed everything :) Thank you – Parker Hawke May 12 '16 at 23:28

2 Answers2

3

Is it possible that another thread is updating xOffset, yOffset, or center? If two thread are both trying to update these variable you may see the behaviour described. You can try adding locking statements or a synchronized block around these two lines. The lock will need to be shared with the other thread updating these variables and that thread will also need locking statments.

David Waters
  • 11,979
  • 7
  • 41
  • 76
  • Unfortunately, no. There is no other location in the game in which the xOffset and yOffset variables are being modified other than in this Camera class. (I did a project search for the usage of those methods and variables just to make sure) – Parker Hawke May 12 '16 at 23:16
2

Solved! :D The answer was as followed:

synchronized (game.getMainThread()){
    xOffset = center.getLocation().getRawX() - (Game.WIDTH / 2) + (center.getWidth() / 2);
    yOffset = center.getLocation().getRawY() - (Game.HEIGHT / 2) + (center.getHeight() / 2);
}
  • 2
    So, when you say "Unfortunately, no." in your comment on @DavidWaters' answer, I think you meant "Actually, yes" :) – Andy Turner May 12 '16 at 23:53
  • Lol apparently I do modify it _somewhere_. I don't see exactly where I do modify it, but apparently I do :P The entire purpose of this thread was so I didn't have to update it anywhere else – Parker Hawke May 13 '16 at 00:55