Reputation: 1431
I am working on a very simple Physics game for Android where an object bounces up and down with some gravity (0 friction, ball should always reach same height). I want it to reach the same height on all devices (density independence). My game is coded with the following for the physics, which works perfectly fine on a 540 * 960 device.
Note: My game has a max FPS of 30
physics code
//Instance variables
private final float acceleration = .1f;
private static float timePoint;
private float velocityY = 0;
//game loop code
timePoint += 1;//updates every tick
velocityY = velocityY - acceleration * timePoint;
position.y = (int) (position.y - velocityY);
if(position.y + bitMapHeight <= 0){
velocityY = 30;
timePoint = 0;
}
When the ball hits the ground (y = 0) I simply apply a velocity of 30, which makes the ball reach a desired height on the 540 * 960 device. Of course multiple devices lead to major headaches, and this formula will not suite all of them. I think the best approach would be to somehow calculate the velocity based on screen height, but I'm not really sure what the best approach is for something like this. Below are some screenshots showing whats happening.
If anyone can point me in the right direction I would be very grateful! Please let me know if any more details are required.
Upvotes: 3
Views: 783
Reputation: 1431
I apologize to those who posted on this for my delayed response. I found a solution that worked for me. Below is the approach I took.
Find the target height that the object should reach after it hits the ground (bottom of screen).
//We want the object to bounce halfway on screen
targetBounceHeight = metrics.heightPixels / 2;
Use physics calculation to find required velocity to reach point Y.
double velocityI = Math.sqrt(2 * targetBounceHeight * acceleration);
I simply find the initial velocity required, then plug it into the original code snippet dynamically instead of the value 30 (see top post). This solution has worked on all tested devices perfectly. Hope this helps someone!
Upvotes: 0
Reputation: 48
Why don't you try this on the onCreate:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
With that you can get the values of the screen and, instead of using ´velocityY = 30;´ you can set it to ´velocityY= height/10´ for example
Upvotes: 1
Reputation: 294
I had to solve a similar problem in a 2D game I was working on a while ago.
I developed the initial physics and rendering functionality on my own Android device until it behaved nicely on that particular device. I then obtained 'baseline' values for the relevant variables (eg. pixels:meter as mentioned by bjb568), to achieve the correct velocities on my baseline device.
Then, to make the game behave in the same way on different devices/screens, I simply used the baseline values scaled by the ratio of the actual screen resolution and the baseline screen resolution.
My game used a SurfaceView, so the 'actual screen resolution' was basically determined by the width and height of the surface.
I hope that helps.
Upvotes: 1
Reputation: 2329
Why you set velocityY = 30; after point reaches the bottom? I think that you should use perfectly elastic collision. So, you just need to set velocityY = -velocityY;
Upvotes: 0