-2

So my problem is that I am trying to position a sprite in the middle of the screen. How to do that is very simple but the calculations made during runtime are wrong. I have come to the conclusion that it is about floating points being messy in Java.

So, this is the code I have right now, which works:

float posX = ((1280f / 2f) - 128f);
float posY = ((720f / 2f) - 112.5f);
splash.setScale(1.5f);
splash.setPosition((posX), (posY));

But if I replace the divisions above with these variables:

private float screenCenterW = (1280.0f / 2f);
private float screenCenterH = (720.0f / 2f);
private float splashCenterW = (225.0f / 2f);
private float splashCenterH = (256.0f / 2f);

Things does not seem to work anymore. It seems to me that the first part of the posX and posY calculations result in a 0.0 and my sprite ends up in the upper left corner, half-visible.

Why is it that if I replace the different calculations with these variables, it stops working?

EDIT:

So to clarify:

This is how I want the code to look like:

private float screenCenterW = (1280.0f / 2f);
private float screenCenterH = (720.0f / 2f);
private float splashCenterW = (225.0f / 2f);
private float splashCenterH = (256.0f / 2f);
float posX = (screenCenterW - splashCenterW);
float posY = (screenCenterH - splashCenterH);
splash.setScale(1.5f);
splash.setPosition((posX), (posY));

This, however, makes something go wrong. Even though, to me, they look exactly the same as the other calculation. Am I making a rookie mistake somewhere? I have been constructing this calculation from the bottom to the top with just numbers, and it works, but as soon as I substitute one of the calculations with a variable (saving it in a variable) it stops working, and the sprite goes off the screen, as if the screenCenterW and screenCenterH is calculated to 0.0 through the division of 2f. Example of screenWidthH: (1280f / 2f) = 0 | 0 - 112.5f = -112.5f

Why I have issues debuging this is because I don't know how to show these calculations on the screen in the AndEngine for Android that I am using. I sincerely apologise for not being detailed and I realise now that the question didn't say much at the start, but I hope this clarifies what I'm asking about. And if somebody out there that use AndEngine could help me that would be amazing.

Simon
  • 470
  • 1
  • 7
  • 22
  • 1
    Have you tried debugging? – Luis Sep Aug 15 '13 at 16:40
  • 2
    What do you mean by _"calculations are wrong"_ and _"does not seem to work"_? Slightly off? Way off? Have you printed the numerical values to see what's happening? You need to a lot more research and show the results before anybody here can help you. – Jim Garrison Aug 15 '13 at 16:41
  • Also note the calculations you do are different. In one case you subtract, presumably half the width and height of the sprite, from the quotient, in the other you do not. You have not shown how you actually _use_ the results to position the sprite. – Jim Garrison Aug 15 '13 at 16:43
  • The code with your variables is not doing the same calculations. `((1280f / 2f) - 128f) != (screenCenterW - splashCenterW)` . The later is `(1280.0f / 2f) - (225.0f / 2f)` – Jonathan Drapeau Aug 15 '13 at 17:22
  • @JonathanDrapeau Yes, I can see that I switched those, but the result shouldn't be what it is even though that is true what you said. Because my result does not differ with just 20-something 'pixels', it actually 'resets' the position to 0, and then does the minus. Instead of taking into account the width andheight of the screen. That is why I'm having issues. That the numbers are switched would only mean that they were slightly mispositioned, but they are infact off the screen right now. – Simon Aug 15 '13 at 17:31
  • The problem is not in the code you're showing as the results of the calculations, even if done with variables, is working fine. I've tested with and without variables and the results are all fine. – Jonathan Drapeau Aug 15 '13 at 17:37
  • @JonathanDrapeau Did you test it in AndEngine for Android? – Simon Aug 15 '13 at 17:39

2 Answers2

1

You show too little code to tell you where you went wrong, but I suspect you either alter the variable at some place without noting, or you have a class initialization order issue (you are using the variables before they are actually calculated).

To rule out accidental alteration, declare the variables as final:

 private final float screenCenterW = (1280.0f / 2f);

If there's any place where you assign them, the compiler will complaing about it.

Initialization order is harder to track down, you can use a conditional check just before using the variable:

 if (screenCenterW == 0) {
     throw new RuntimeException("Something is horribly wrong!");
 }

You should see the exception in your IDE's console window if it triggers.

Durandal
  • 19,919
  • 4
  • 36
  • 70
  • Hehe, so what you are saying about the initialization is that the calculation doesn't finish before it should be used. I thought that was a problem that only occurred at the lowest level? Like instruction wise, and that it was being solved at that level as well (hardware) And I tried the final solution and it did the trick! Thank you so much! I did not get any errors about changing the values and so this seems like a bug to me. Or is it supposed to be that unreliable? Because all I added was the final to those variables and poof! Thanks yet again! – Simon Aug 15 '13 at 19:13
  • Unless your code uses multiple threads, the initialization order is deterministic - the order in which all the class initializers run is strictly defined be the Java Language Specification (http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2). Its quite possible to call a method of an object before all its initializer code has run (e.g. template method called from the constructor of a superclass). In that case your code still sees the default value for class members. – Durandal Aug 16 '13 at 12:00
  • Since the use of the thread is in a GUI, it is very likely that the variables are being initialized in the main thread, and used in the event dispatch thread. If so, the permanent solution is to only operate on them in the EDT, if necessary using invokeLater. – Patricia Shanahan Aug 16 '13 at 20:29
0

Nothing is wrong with the calculations. The way you're doing it is right, and you can test it:

public static void main(String[] args) {
        float screenCenterW = (1280.0f / 2f);
        float screenCenterH = (720.0f / 2f);
        float splashCenterW = (225.0f / 2f);
        float splashCenterH = (256.0f / 2f);

        System.out.println(screenCenterW);
        System.out.println(screenCenterH);
        System.out.println(splashCenterW);
        System.out.println(splashCenterH);
    }

Output:

640.0
360.0
112.5
128.0

Show the rest of the code.

Luis Sep
  • 2,384
  • 5
  • 27
  • 33