androidcoordinatesscreen-sizescreen-density

Use x/y coordinates to set bounds of a moving particle


I have two bitmaps that I draw onto the center of a canvas: One is only a background, it's a spirit level in top view which doesnt move. The second one is a bitmap looking like a "air bubble". When the user tilts the phone, the sensors read the tilt and the air bubble moves according to the sensor values along the x-axis. However, I need to make sure that the air bubble doesnt move too far, e.g out of the background-bitmap. So I tried to which x coordinate the bubble can travel to, before I have to set xPos = xPos -1 using trial and error This works fine on my device.

To clarify: On my phone, the air bubble could move to the coordinate x = 50 from the middle of the screen. This would be the point, where the bitmap is at the very left of the background spirit level. On a larger phone, the position x = 50 is too far left, and therefore looking like the air bubble travelled out of the water level.

Now I've tried following: I calculated the area in % in which the air bubble can move. Let's say that is 70% of the entire width of the bitmap. So I tried to calculate the two x boundary values:

leftBoundary = XmiddlePoint - (backgroundBitmap.getWidth() * 0.35); rightBoundary = XmiddlePoint + (backgroundBitmap.getWidth() * 0.35);

...which doesnt work when testing with different screen sizes :(

Is it possible to compensate for different screen sizes and densities using absolute coordinates or do I have to rethink my idea?

If you need any information that I forgot about, please let me know. If this question has already been answered, I would appreciate a link :) Thanks in advance!

Edit: I load my bitmaps like this:

private Bitmap backgroundBitmap;
private static final int BITMAP_WIDTH = 1898;
private static final int BITMAP_HEIGHT = 438;

public class SimulationView extends View implements SensorEventListener{
public SimulationView(Context context){
Bitmap map = BitmapFactory.decodeResource(getResources, R.mipmap.backgroundImage);
backgroundBitmap = Bitmap.createScaledBitmap(map, BITMAP_WIDTH, BITMAP_HEIGHT, true; 
}

and draw it like this:

protected void onDraw(Canvas canvas){
canvas.drawBitmap(backgroundBitmap, XmiddlePoint - BITMAP_WIDTH / 2, YmiddlePont - BITMAP_HEIGHT / 2, null);
}

backgroundBitmap.getWidth() and getHeight() prints out the correct sizes. Calculating like mentioned above would return following boundaries:

DisplayMetrics displayMetrics = new DisplayMetrics();
    ((Activity)  getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    int width = displayMetrics.widthPixels;
    //which prints out width = 2392
    xMiddlePoint = width / 2;
    // = 1196
    leftBoundary = xMiddlePoint - (BITMAP.getWidth()* 0.35);
    // = 531,7

However, when I use trial and error, the right x coordinate seems to be at around 700.


Solution

  • I've come across a great explanation on how to fix my issue here. As user AgentKnopf explained, you have to scale coordinates or bitmaps like this:

    X = (targetScreenWidth / defaultScreenWidth) * defaultXCoordinate

    Y = (targetScreenHeight / defaultScreenHeight) * defaultYCoordinate

    which, in my case, translates to:

    int defaultScreenWidth = 1920;
    int defaultXCoordinate = 333;
    DisplayMetrics displayMetrics = new DisplayMetrics();
    ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    displayWidth = displayMetrics.widthPixels;
    leftBoundary = (displayWidth / defaultScreenWidth) * defaultXCoordinates