Android barrier detection of accelerating object - android

my app contains an object moving on a surfaceview. I am able to move it around via accelerometer.
Here's the movement code of the player object:
if(x + mx*speed > 0 && x + mx*speed < GameView.WIDTH) {
x += mx*speed;
}
if(y+ my*speed > 0 && y+ my*speed < GameView.HEIGHT) {
y+=my*speed;
}
x and y are the player's coordinates
mx is the value the player gets from the accelerometer, for example: when tilting to the left, mx is -2, when tilting more, mx is -4, -5, -6 etc. --> my is the same for the y-axis
the speed is a variable to modify and play around when i want to have a faster movement.
as you can see I tried to limit the movement to only move when the player is inside of the view.
Now my problem is: when tilting the device intensively to the right, mx turns to something like 6. speed is set to 5. This means, when the player's position + 6 * 5 is bigger than the game view it should not move any more. But this results in the player stopping pixels in front of the right side of the view... when tilting lightly to the right, the object stops perfectly at the border of the view...
Now how should i change the code to achieve an object that stops it's movement perfectly at borders of the screen?
On this picture you can see the circle not stopping quite at the bottom, as there are some pixels between the circle and the bottom border. when going slightly back with the accelerometer, the circle aligns itself to the bottom of the screen:
But now, i can only reach the screen borders when moving slowly, which means with a low mx or my.
the screenshots you can see the mY values. On the first picture my = ca. 8 and on the second ca. 6.
Any ideas?
Thanks in advance

Try to instead cap the value to the border like so
x = Math.max(Math.min(x + mx*speed, GameView.WIDTH), 0.0f));
y = Math.max(Math.min(y + my*speed, GameView.HEIGHT, 0.0f));

Related

Center camera in GVR MonoscopicView

I'm using GVR Android library version 1.190 and trying to play both 360 and 180 degrees videos in the video360 example project.
In both cases the 2D view (MonoscopicView) starts the playback fine, but the viewer camera position is never centered to the center of the video. It instead starts randomly off-centered by horizontal axis. Same behavior on multiple devices.
Anyone knows how to center the view to the video center when 2D view starts?
Turns out that sensor data from Sensor.TYPE_GAME_ROTATION_VECTOR are having very different values (angles) every time my activity register a listener to it. It only takes a small tilt of the phone to get really different values. Different devices also respond differently but they all have offset readings.
This lead to the initial view angle being positioned (usually) 90 degrees either to the left or right from the center of video.
Thanks to this post, I managed to calculate the initial heading offset and rotate phone position matrix to compensate.
Add a member variable private float initialHeading with initial value 0.
Then, in PhoneOrientationListener's onSensorChanged add the following code after the Android to OpenGL matrix rotation:
if (initialHeading == 0) {
initialHeading = (float) ((angles[0] + 2 * Math.PI) % (2 * Math.PI));
}
float angle = (float) ((Math.PI - initialHeading) * 180 / Math.PI);
Matrix.rotateM(phoneInWorldSpaceMatrix, 0, angle, 0, 1, 0);

provide circular motion for a custom drawing on touch: Android

I have a custom drawn rectangle which i want to move in a circular path based on touch events.
It follows the direction of the touch for clockwise or anticlockwise movement but basically move in circular motion, as if moving on the edge of the circle.
My current thought process is as follows:
Based on the users current and previous x,y i shall find the angle in degrees and then move this rectangle by the same angle by re-drawing in the new position, just making sure that it moves on the edge of a circle.
But this leads to some confusion on the following:
1. how do i decide whether angle movement is clockwise or anti-clockwise.
2. I am not being able to figure out the math for this properly.
Would this be the best approach or is there a better idea for doing this?
Also, if this is the best approach, could someone please tell me the formula for calculating the angle by which i should move it while taking care of the clocking and anticlockwise ?
could someone please help?
please let me know if any more details are required.
Thanks
Steps
Here are a few steps in order to move your rectangle along a circle's rim when the user taps and holds to the side of the circle:
1. Obtain direction desired.
2. Obtain angle from current x and y coordinates.
3. Add direction (+1 if counterclockwise, -1 if clockwise) to angle.
4. Calculate new x and y coordinates.
5. Update/display rectangle.
Details
1. In pseudocode, direction = sign(Rectangle1.x - UsersFingerPosition.x). Here sign is a function returning -1 if the number was negative, 0 if it is 0, and 1 if it is positive. Note that sign(0) will only result when the user is on the exact x and y of your rectangle's location. In that case, the rectangle would not move (which should be good). In Java, the sign function is Math.signum().
2. To obtain the current angle use the following java code:
double angle = Math.toDegrees(Math.atan2(Circle.y-Rectangle1.y, Rectangle1.x-Circle.x));
Note the order of Circle.y-Rectangle.y and Rectangle.x...Circle.x. This is a result of the coordinate (0, 0) being in the top left corner instead of the center of the screen.
3. Simple enough, just add direction to angle. If desired, do something like
angle += direction*2; //So it will move more quickly
4. To get the new x and y coordinates of your rectangle, use the trigonometric functions sine and cosine:
Rectangle1.x = Math.cos(Math.toRadians(angle))*Circle.radius + Circle.x - Rectangle1.width;
Rectangle1.y = Math.sin(Math.toRadians(angle))*Circle.radius + Circle.y - Rectangle1.height;
(where Circle.x and Circle.y are the coordinates of the center of your circle and Circle.radius is naturally it's radius).
5. This one you'll have to take care of (or have already) :)!
Hope this helps you!
Steps
Here are a few steps in order to move your rectangle along a circle's rim:
1. Obtain finger position/Check that it's still dragging the rectangle.
2. Obtain angle from current x and y coordinates.
3. Calculate new x and y coordinates.
4. Update/display rectangle.
Details
1. This one is probably specific to your code, however, make sure that when the user starts dragging the rectangle, you set a variable like rectangleDragging to true. Before you run the next steps (in the code), check that rectangleDragging == true. Set it to false once the user lets go.
2. To obtain the current angle use the following java code:
double angle = Math.toDegrees(Math.atan2(Circle.y-Finger.y, Finger.x-Circle.x));
Note the order of Circle.y-Finger.y and Finger.x...Circle.x. This is a result of the coordinate (0, 0) being in the top left corner instead of the center of the screen.
3. To get the new x and y coordinates of your rectangle, use the trigonometric functions sine and cosine:
Rectangle1.x = Math.cos(Math.toRadians(angle))*Circle.radius + Circle.x - Rectangle1.width;
Rectangle1.y = Math.sin(Math.toRadians(angle))*Circle.radius + Circle.y - Rectangle1.height;
(where Circle.x and Circle.y are the coordinates of the center of your circle and Circle.radius is naturally it's radius). Subtracting the width and height of the rectangle should center it on the circle's border instead of placing the left, upper corner on the circle.
4. This one you'll have to take care of (or have already) :)!
Hope this helps you!

Smoothly move Image with accelerometer in android

I am building an android application similar to x-ray scanner (Play Store Link), which moves images smoothly on screen by moving the device left,right top and bottom.
I am using accelerometer for this, but problem is that image is not moving smoothly.
My code is below
int x1 = (int) sensorEvent.values[0]*(screenW/10);
int y1 = (int) sensorEvent.values[1]*(screenH/14);
and then in on Draw
canvas.drawBitmap(bmp, x, y, mPaint);
This is not how you use them. You should take current value and ADD to current position instead of setting position from value directly. The more you tilt - the bigger values you will get and hence the faster the image will appear to move.
You can then also apply some linear interpolation to the movement so that it appears smoother.
Here is a link to learn more about lerp (linear interpolation) in code: http://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support

Bouncing back on the edges

I am trying to make a small game where you can fling a coin on the screen. while i was searching for that kind of animation i found this page
http://mobile.tutsplus.com/tutorials/android/android-gesture/
I managed to customise the events according to my aim, but i couldn't manage to set boundaries on the screen so that the coin(bitmap) will bounce back when it comes to the edges.
I tried several calculations but in the end the coin moves weirdly based on the contact points on the edges.
Can someone help me about it, according to the working code on the website
Below is a sample code from my pong game. Each object has position (x,y) and its speed. Movement is speed applied to position. One extra info is that the screen coordinate system starts from the left top corner. Y axis go down but increasing. Since screen coordinates start from 0, the boundaries become screen.width -1 and screen.height -1
#Override
public void onDraw(Canvas c){
p.setStyle(Style.FILL_AND_STROKE);
p.setColor(0xff00ff00);
// If ball's current x location plus the ball diameter is greater than screen width - 1, then make speed on x axis negative. Because you hit the right side and will bounce back to left.
if((Px+ballDiameter) > width - 1){
Vx = -Vx;
}
// If ball's current y location plus the ball diameter is greater than screen height -1, then make speed on y axis negative. Because you hit the bottom and you will go back up.
if((Py + ballDiameter) > height - 1){
Vy = -Vy;
}
// If current x location of the ball minus ball diameter is less than 1, then make the speed on x axis nagative. Because you hit to the left side of the screen and the ball would bounce back to the right side
if((Px - ballDiameter) < 1){
Vx = -Vx;
}
// If current y location of the ball minus ball diameter is less than 1, then make the speed on y axis negative. Because the ball hit the top of the screen and it should go down.
if((Py - ballDiameter ) <1){
Dy = 1;
Vy = -Vy;
}
Px += Vx; // increase x position by speed
Py += Vy; // increase y position by speed
c.drawCircle(Px, Py, ballDiameter, p);
invalidate();
}

Gaming, collision on view

I am designing an archer game. When the arrow hits the target it stops moving. What I am trying to accomplish is to define a formula to predict/get location where the target and the arrow meet on the view.
The problem arises when the arrow got a speed varying on initial velocity and the arrow also have angles. Plus, the images on screen are placed by x - bitmapt.getWidth/2 (same for height, h/2..)
If an arrow moves too fast then I need to calculate an error so the arrow does not miss the target even though they are supposed to be on same x and y as we have that, the arrow moves as X + speed pixels. So I came to something like this!
if(arrow[i].getX() + v0x[i] / 2 >= target.getTarget().getX() && arrow[i].getX() <= target.getTarget().getX() + v0x[i] / 2)
I use the velocity of x/2 to specify the error margin.
arrowX + velocity/2 >= collision point >= targetX + velocity/2
However, it does not work.
This is a pure mathematical problem, and there are much literature when it comes to collision detection. I propose that you use a library. For 2D I recommend JBox2D. It is a physics engine (used for example in Angry Birds). You get collision detection and much much more :)

Categories

Resources