Android touch direction northwest, northeast for UP direction - android

Sorry if the title sounds confusing - but this is what I am trying to do:
I have a large circular button on which I detect touch direction. I am able to find the UP/DOWN/LEFT/RIGHT from the dy and dx of the change in touch input coordinates like this:
if(Math.abs(dX) > Math.abs(dY)) {
if(dX>0) direction = 1; //left
else direction = 2; //right
} else {
if(dY>0) direction = 3; //up
else direction = 4; //down
}
But now I would like to handle cases where the button can be slightly rotated and thus the touch direction will also need to adjust for this. For example, if the button is rotated slightly to the left, then UP is now the finger moving northwest instead of just pure north. How do I handle this?

Use Math.atan2(dy, dx) to get the angle anticlockwise from the positive horizontal of the coordinate in radians
double pressed = Math.atan2(dY, dX);
subtract the rotation amount (anticlockwise rotation amount in radians) from this angle, putting the angle into the coordinate system of the button
pressed -= buttonRotation;
or if you have your angle in degrees, convert it to radians
pressed -= Math.toRadians(buttonRotation);
You can then calculate an easier direction number from this angle
int dir = (int)(Math.round(2.0d*pressed/Math.PI) % 4);
This gives right 0, up 1, left 2 and down 3. We need to correct the case where the angle is negative, as the modulo result will also be negative.
if (dir < 0) {
dir += 4;
}
Now supposing that these numbers are bad and you don't want to use them, you can just switch on the result to return whatever you like for each direction. Putting that all together:
/**
* #param dY
* The y difference between the touch position and the button
* #param dX
* The x difference between the touch position and the button
* #param buttonRotationDegrees
* The anticlockwise button rotation offset in degrees
* #return
* The direction number
* 1 = left, 2 = right, 3 = up, 4 = down, 0 = error
*/
public static int getAngle(int dY, int dX, double buttonRotationDegrees)
{
double pressed = Math.atan2(dY, dX);
pressed -= Math.toRadians(buttonRotationDegrees);
// right = 0, up = 1, left = 2, down = 3
int dir = (int)(Math.round(2.0d*pressed/Math.PI) % 4);
// Correct negative angles
if (dir < 0) {
dir += 4;
}
switch (dir) {
case 0:
return 2; // right
case 1:
return 3; // up
case 2:
return 1; // left;
case 3:
return 4; // down
}
return 0; // Something bad happened
}

Related

Move a body emulating the movement of my finger on the screen at a constant speed

I need help with the following problem since I have invested many days without arriving at an acceptable solution.
I'm doing an Android game (using libgdx) where the main character (named Hero) is seen from above (top-down view game) and walks on a field.
The user moves the character by moving his finger along the screen. The finger does't need to be on the character.
The character uses two animations, one animation when he moves forward (that is, when his "y" is greater than zero since the user looks at the game from the "sky") and another animation when he moves backwards (that is, when his "y" is less than zero, remember I'm developing a top-down view game).
Finally, I need the character to always move at a CONSTANT speed.
In short, I would like to handle the character with the finger and move it in the direction that marks my finger, always a CONSTANT speed.
This would be very easy if I could set the position of the character each delta time, but I'm using box2d which only knows about linearVelocity, impulses, forces, etc.
I tried using mouseJoint where hitbody is my main character (Hero) and groundBody is an invisible body.
// Invisible zero size ground body
// to which we can connect the mouse joint
Body groundBody;
BodyDef bodyDef = new BodyDef();
groundBody = world.createBody(bodyDef);
/* player is an instance of my Hero's class, which has a box2d body and
update, draw methods, etc.
*/
hitBody = player.getB2body();
...
InputProcessor:
#Override
public boolean touchDown(int i, int i1, int i2, int i3) {
gameCam.unproject(testPoint.set(i, i1, 0));
MouseJointDef def = new MouseJointDef();
def.bodyA = groundBody;
def.bodyB = hitBody;
def.collideConnected = true;
def.target.set(testPoint.x, testPoint.y);
def.maxForce = 1000.0f * hitBody.getMass();
mouseJoint = (MouseJoint) world.createJoint(def);
hitBody.setAwake(true);
}
#Override
public boolean touchUp(int i, int i1, int i2, int i3) {
player.getB2body().setLinearVelocity(0,0);
// if a mouse joint exists we simply destroy it
if (mouseJoint != null) {
world.destroyJoint(mouseJoint);
mouseJoint = null;
}
return false;
}
#Override
public boolean touchDragged(int i, int i1, int i2) {
// if a mouse joint exists we simply update
// the target of the joint based on the new
// mouse coordinates
if (mouseJoint != null) {
gameCam.unproject(testPoint.set(i, i1, 0));
mouseJoint.setTarget(target.set(testPoint.x, testPoint.y));
evaluateMovementDirection();
}
return false;
}
private void evaluateMovementDirection() {
float vy = player.getB2body().getLinearVelocity().y;
float vx = player.getB2body().getLinearVelocity().x;
// Test to Box2D for velocity on the y-axis.
// If Hero is going positive in y-axis he is moving forward.
// If Hero is going negative in y-axis he is moving backwards.
if (vy > 0.0f) {
player.onMovingUp(); // In draw, I'll use a "moving forward" animation
} else if (vy < 0.0f) {
player.onMovingDown(); // In draw, I'll use a "movieng backwards" animation
} else {
player.onStanding(); // vy == 0 In draw, I'll use a texture showing my Hero standig.
}
}
The problem I get with this, is that if I move my finger very fast, the character moves very fast. I would like the character to always move AT CONSTANT SPEED.
The other approach I tried is to use the pan event:
GestureListener:
#Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
/*
* DeltaX is positive when I move my finger to the left, negative otherwise.
* DeltaY is positive when I move my finger down, negative otherwise.
*/
// In b2body y-axes sign is the opposite.
deltaY = -deltaY;
// DeltaX and deltaY are in pixels, therefore delta is in metres.
Vector2 delta = new Vector2(deltaX / Constants.PPM, deltaY / Constants.PPM);
// Deltas too small are discarded
if (delta.len() > Constants.HERO_SENSIBILITY_METERS) {
/*
* origin.x = player.getB2body().getPosition().x
* origin.y = player.getB2body().getPosition().y
*
* destination.x = origin.x + delta.x
* destination.y = origin.y + delta.y
*
* To go from origin to destination we must subtract their position vectors: destination - origin.
* Thus destination - origin is (delta.x, delta.y).
*/
Vector2 newVelocity = new Vector2(delta.x, delta.y);
// Get the direction of the previous vector (normalization)
newVelocity.nor();
// Apply constant velocity on that direction
newVelocity.x = newVelocity.x * Constants.HERO_LINEAR_VELOCITY;
newVelocity.y = newVelocity.y * Constants.HERO_LINEAR_VELOCITY;
// To avoid shaking, we only consider the newVelocity if its direction is slightly different from the direction of the actual velocity.
// In order to determine the difference in both directions (actual and new) we calculate their angle.
if (Math.abs(player.getB2body().getLinearVelocity().angle() - newVelocity.angle()) > Constants.HERO_ANGLE_SENSIBILITY_DEGREES) {
// Apply the new velocity
player.getB2body().setLinearVelocity(newVelocity);
evaluateMovementDirection();
}
} else {
// Stop
player.getB2body().setLinearVelocity(0, 0);
evaluateMovementDirection();
}
return true;
}
The problem I have with this is that the movement is very unstable and "dirty". The character is shaking.
I tried this approach (thanks #hexafraction).
Using this code, my charecter moves more fluid along the screen.
It's not perfect, but it's something...
#Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
/*
* DeltaX is positive when I move my finger to the left, negative otherwise.
* DeltaY is positive when I move my finger down, negative otherwise.
* Both are in pixels, thus to get meters I must divide by Constants.PPM.
*/
// In b2body y-axes sign is the opposite.
deltaY = -deltaY;
/*
* origin.x = player.getB2body().getPosition().x
* origin.y = player.getB2body().getPosition().y
*
* destination.x = origin.x + deltaX / Constants.PPM
* destination.y = origin.y + deltaY / Constants.PPM
*
* To go from origin to destination we must subtract their position vectors: destination - origin.
* Thus, destination - origin is (deltaX / Constants.PPM, deltaY / Constants.PPM).
*/
candidateVelocity.x = deltaX / Constants.PPM;
candidateVelocity.y = deltaY / Constants.PPM;
// Get the direction of the previous vector (normalization)
candidateVelocity.nor();
// Apply constant velocity on that direction
candidateVelocity.x = candidateVelocity.x * Constants.HERO_LINEAR_VELOCITY;
candidateVelocity.y = candidateVelocity.y * Constants.HERO_LINEAR_VELOCITY;
// Linear interpolation to avoid character shaking
heroVelocity.lerp(candidateVelocity, Constants.HERO_ALPHA_LERP);
// Apply the result
player.getB2body().setLinearVelocity(heroVelocity);
// Depending on the result, we change the animation if needed
evaluateMovementDirection();
}
return true;
}
I need a suggestion on how to resolve this. I mean, move a box2d character with my finger along the screen at CONSTANT SPEED.
Thank you very much.
Calculate the direction in which you want to move:
dragPos.sub(currentPos);
Normalize it and multiply with the constant speed:
dragPos.sub(currentPos).nor().scl(CONSTANT_SPEED);

Animating a list of points to move away from a given touch location

The animation I am working on achieving is shown below in Figure 1.
1)I have a list containing points on a 2D plane(left) that I am working on animating.
2)A touch is made at location x, and an invisible circle is drawn (middle). I want all of the points contained in that circle to move away from the center (x).
3) A final result example (right)
I am planning on applying this in a way that I can supply any list of points, touch location, numFrames, and force applied on each point per frame. An array of length numFrames is returned, each array item being an already animated list.
Since I plan on implementing this on screen touch, it is possible for another touch to happen while the first touch animation is already in progress. How can I handle these collisions?
Figure 1:
here's my 2 cents, you need a list of points, these points should have a position, a velocity and a method to update the position. something like this
public class Point {
public float x, y;
public boolean isMoving;
private float dx,dy;
public Point(float x, float y){
this.x = x;
this.y = y;
}
public boolean move(float maxWidth, float maxHeight){
if(!isMoving) return false;
// update the position
x += dx;
y += dy;
dx /= FRICTION;
dy /= FRICTION;
// bounce...?
if(x < 0 || x > maxWidth){
dx *= -1;
}
if(y < 0 || y > maxHeight){
dy *= -1;
}
if(Math.abs(dx) < MOVEMENT_THRESHOLD && Math.abs(dy) < MOVEMENT_THRESHOLD){
isMoving = false;
}
return isMoving;
}
}
on every touch event you apply a force to every point within the radius and set their velocity
for(Point point : mPoints){
float distance = point.distance(x,y);
if(distance > mTouchRange) continue;
float force = (float) Math.pow(1 - (distance / mTouchRange), 2) * mForceFactor;
float angle = point.angle(x,y);
point.dx -= Math.cos(angle) * force;
point.dy -= Math.sin(angle) * force;
point.isMoving = true;
}
then you need an animation that call move on every frame and eventully stops when there are no moving points
you can find the full example here

Using Android accelerometer y axis falls through terrain - Unity3D

This works much better, thank you. However, it still does not work very well. While I don't go completely through the terrain, the FP controller seems to hover just below the terrain. Adding a +10 helps, but there is another strange issue:
I have the camera set up as a child of the FP controller, at 0,0,0. When the game begins to run, the Y value in the transform of the controller window goes steadily down, in minus numbers, while the camera Y value goes steadily up, in the positive direction. The Y values are mirrored. Any ideas of what is going on?
void Update () {
moveX = Input.acceleration.x * 1;
moveY = Input.acceleration.y * 1;
moveZ = (1+ (Input.acceleration.z));
transform.Translate (0, 0, 0); //transform.translate Moves the transform in the direction and distance of translation
temp = transform.position; //temp = the position of the transform in world space. World Space: the absolute XYZ coordinates of all objects
temp.y = terrainY; //y component of Vector3 (float)
transform.position = temp; //put the position of the transform in world space back into temp
terrainY = Terrain.activeTerrain.SampleHeight(temp); //Sample.height Samples the height at the given position defined in world space
temp2 = transform.position.y; //this shows transform.position.y axis is the same as terrainY, but not the same value as shown in the inspector
if (moveZ >= 0.055 && moveZ >= -0.1) {
zeroZFlag = 1;
if(moveZ >= 0.041){
moveZ = moveZ*10; //multiply by 10 to make it faster when going forward
if (moveY >= 0) {
transform.Translate (moveX,terrainY + 10,moveZ);
//transform.translate needs to be three floats. So the middle one needs to be the y value of the top of the terrain
}
if (moveY < 0){
transform.Translate (moveX,terrainY,-moveZ);
}
}
I have added to my code as suggested but am still having trouble getting the first person controller to stay on the same y-value as the terrain. In the following iteration of code, the First person y value leaves the world entirely and goes up forever.
My code uses
`transform.Translate (moveX,terrainY,moveZ);
to move the FP controller around, where moveX and moveY are acceleration values and terrainY theoretically should be the actual value of the Y-axis as shown in the transform box.
I think that the first issue is that I am mixing acceleration values (X,Z) with a terrain transform for Y, so different meaning to the values.
BTW X and Z axis move very well with the accelerometer with this code, but I will change everything if necessary!
I am not sure what kind of float value operation translate.transform does. The manual states that it returns in the space.world, but does it move by the number of units or position?
Here is my new code, and thank you in advance for help:
public float terrainY;
// y axis falls through terrain
// travels through walls even though collider is set
void LateUpdate (){
//terrainY = Terrain.activeTerrain.SampleHeight (transform.position);
}
void Update () {
moveX = Input.acceleration.x * 1;
moveY = Input.acceleration.y * 1;
moveZ = (1+ (Input.acceleration.z));
transform.Translate (0, 0, 0);
terrainY = Terrain.activeTerrain.SampleHeight (transform.position);
if (moveZ >= 0.055 && moveZ >= -0.1) {
zeroZFlag = 1;
if(moveZ >= 0.041){
moveZ = moveZ*10; //multiply by 10 to make it faster when going forward
if (moveY >= 0) {
transform.Translate (moveX,terrainY,moveZ);
//transform.translate needs to be three floats. so the middle one needs to be the y value of the top of the terrain
}
if (moveY < 0){
transform.Translate (moveX,terrainY,-moveZ);
}
My code causes me to go through and under my terrrain in Unity 3D because the y axis is always zero. In this world, x-axis is left/right and z is depth. Y axis is up/down and shold follow the mountains, hills, valleys in the terrain. However, it just goes through, at 0 height.
Does anyone know what variable/class should be in the y-axis spot instead of the "0" I have there? Thanks in advance!
public class Movement2 : MonoBehaviour {
public float moveX = Input.acceleration.x;
public float moveY = Input.acceleration.y;
public float moveZ = Input.acceleration.z;
public float Speed = 20.0f;
public int zeroZFlag;
void Update () {
moveX = Input.acceleration.x * 1;
moveY = Input.acceleration.y * 1;;
//moveZ = Mathf.Abs(1+ (Input.acceleration.z) * 20);
moveZ = (1+ (Input.acceleration.z));
transform.Translate (0, 0, 0);
if (moveZ >= 0.055 && moveZ >= -0.1) { zeroZFlag = 1;
if (moveY >= 0) {
transform.Translate (moveX,0,moveZ);
}
if (moveY < 0){
transform.Translate (moveX,0,-moveZ);
}
else {
zeroZFlag = 0;
}
}
Try using Terrain.SampleHeight(), it returns the height of the terrain with a given X and Z coordinate. Update its Y position to the height of the terrain every Update().
Reference: http://docs.unity3d.com/ScriptReference/Terrain.SampleHeight.html.
EDIT 1:
The reason your FP controller always goes up forever is because you keep translating it with a Y value.
transform.Translate(moveX, terrainY, moveZ)
// this way you keep adding terrainY value to the Y position
// thus it always goes up and will never end
While you need your FP controller to be constantly the same Y position with the terrain. You should instead modify the position of Y directly.
Vector3 temp = transform.position;
temp.y = terrainY;
transform.position = temp;
EDIT 2:
I try my best to help you see through your code:
void Update () {
moveX = Input.acceleration.x * 1;
moveY = Input.acceleration.y * 1;
moveZ = (1+ (Input.acceleration.z));
transform.Translate (0, 0, 0); // why do you need this? this basically does nothing
// you should get terrain height first to be used as temp.y below
terrainY = Terrain.activeTerrain.SampleHeight(transform.position);
temp = transform.position;
temp.y = terrainY + 10; // you said +10 helped, so I put it here
transform.position = temp;
if (moveZ >= 0.055 && moveZ >= -0.1) {
zeroZFlag = 1;
if(moveZ >= 0.041){
moveZ = moveZ*10;
if (moveY >= 0) {
// here I think you shouldn't move the Y anywhere,
// because you've updated position of Y in every update frame
// so you only need to move X and Z due to device tilt
transform.Translate (moveX,0,moveZ);
}
if (moveY < 0){
transform.Translate (moveX,0,-moveZ);
}
}
This also works:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(CharacterController))]
public class Movement6 : MonoBehaviour {
public float speed = 30.0f;
public float moveX = Input.acceleration.x;
public float moveY = Input.acceleration.y;
public float moveZ = Input.acceleration.z;
void Update() {
moveX = Input.acceleration.x * 1;
moveY = Input.acceleration.y * 1;
moveZ = (1+ (Input.acceleration.z));
CharacterController controller = GetComponent<CharacterController>();
Vector3 forward = transform.TransformDirection(moveX,0,moveZ);
controller.SimpleMove (forward * speed);
}
}

Set an analog clock on time with gestures, touching minute hand clockwise or counter-clockwise

I'm stuck trying to make a class that let users to set an analog clock on time. They have to move minute hand, not hour hand, clockwise or counter-clockwise in order to set the current time. Hour hand moves itself according minute hand progress, but I can't be able to move hour hand properly. It doesn't have a smooth movement every time goes through twelve o'clock and six o'clock, where there are angle critical points.
This is my workout until this moment. At twelve o'clock, angle is equal to 0 degrees, the minimum angle of course, and at six o'clock, angle is 180 degrees, the maximun angle. So, from twelve to six (clockwise), we have positive angles (0,180), and, from six to twelve (clockwise), we have negative angles (-180,0). That is ok, but if I want to calculate what will be the correct position of hour hand according with minute hand progress, I have to translate that angles to 0-360 degrees range.
Here is where I handle gestures:
#Override
public boolean onTouch(View v, MotionEvent event) {
// Clock is the clock sphere and the minutes hand.
final float xc = clock.getTranslationX() + (clock.getWidth() / 2);
final float yc = clock.getTranslationY() + (clock.getHeight() / 2);
final float x = event.getX();
final float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
clock.clearAnimation();
mMinutesCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
break;
case MotionEvent.ACTION_MOVE:
/**
* Translate angles from [-179,179] to [0,360] to be able to move
* hours hand properly.
*/
// Start Angle
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
mMinutesPrevAngle = mMinutesCurrAngle;
// Finish angle
mMinutesCurrAngle = Math.toDegrees(Math.atan2(event.getX() - xc, yc - event.getY()));
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
if ((mMinutesCurrAngle > mMinutesPrevAngle)) {
// Clockwise between 12 and 6
mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
} else if ((mMinutesCurrAngle < mMinutesPrevAngle)) {
// counter-Clockwise between 6 and 12
mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
} else if ((mMinutesCurrAngle > mMinutesPrevAngle) && (mMinutesCurrAngle < 0)) {
// Clockwise between 6 and 12
mHoursCurrAngle = mLastSpinHoursAngle + (- mMinutesCurrAngle / 12);
} else if ((mMinutesCurrAngle < mMinutesPrevAngle) && (mMinutesCurrAngle < 0)) {
// counter-Clockwise between 6 and 12
mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
}
newSpin();
// Transelate angles to the original format to represent them properly.
mMinutesPrevAngle = translate360Angle(mMinutesPrevAngle);
mMinutesCurrAngle = translate360Angle(mMinutesCurrAngle);
animate(clock, mMinutesPrevAngle, mMinutesCurrAngle, 0);
animate(hour, mHoursPrevAngle, mHoursCurrAngle, 0);
mHoursPrevAngle = mHoursCurrAngle;
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
Here is where I translate angles:
/**
* Translate angles from [-179,179] to [0,360] to be able to move
* hours hand properly.
* #param minutesAngle
* #return
*/
private double set360Angle(double angle) {
if (angle < 0) return (360 + angle);
else return angle;
}
/**
* Transelate angles to the original format to represent them properly.
* #param angle
* #return
*/
private double translate360Angle(double angle) {
if (angle > 180) return (-360 + angle);
else return angle;
}
And here is where I know if minute hand starts a new spin:
private void newSpin() {
if (translate360Angle(mMinutesPrevAngle) < 0 && translate360Angle(mMinutesCurrAngle) > 0) {
// New Spin clockwise
// I must remember hour hand angle
mLastSpinHoursAngle = mHoursPrevAngle;
} else if (translate360Angle(mMinutesPrevAngle) > 0 && translate360Angle(mMinutesCurrAngle) < 0) {
// New Spin counter-clockwise
// I must remember hour hand angle
mLastSpinHoursAngle = mHoursPrevAngle;
}
}
Can anybody help me a litle bit? if anyone can help me, I promise to put your name to my first unborn daughter ... just kidding.
I discovered where the problem was...
The problem were the "if conditions" inside newSpin() method. Here, before check conditions, I translated angles to the original format (from 0 degrees to 180 degrees for twelve o'clock to six o'clock, clockwise, and from -180 degrees to 0 degrees, for six o'clock to twelve o'clock, clockwise too). So, instead check if user starts a new spin with minute hand, It was adding/subtracting a new spin everytime user goes through six o'clock instead twelve o'clock.
So, I did fix it modifying those conditions, and checking both minute hand angles, previous and current, on 360 degrees format. Now, if previous angle is bigger than 355 degrees and current angle is smaller than 5 degrees, I add a new spin to mSpinNumber. Likewise, if previous angle is smaller than 5 degrees and current angle is bigger than 355 degrees, I subtract a spin to mSpinNumber. I also did change method's name from newSpin() to calculateHourHandAngle().
private void calculateHourHandAngle() {
if ((mMinutesPrevAngle > 355) && (mMinutesCurrAngle < 5)) {
// New Spin clockwise
mSpinNumber++;
} else if ((mMinutesPrevAngle < 5) && (mMinutesCurrAngle > 355)) {
// New Spin counter-clockwise
mSpinNumber--;
}
mHoursCurrAngle = (mSpinNumber * (360/12)) + (mMinutesCurrAngle / 12);
}
I also get rid of unnecessary code in onTouch() method:
#Override
public boolean onTouch(View v, MotionEvent event) {
// Clock is the clock sphere and the minutes hand.
final float xc = clock.getTranslationX() + (clock.getWidth() / 2);
final float yc = clock.getTranslationY() + (clock.getHeight() / 2);
final float x = event.getX();
final float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
clock.clearAnimation();
hour.clearAnimation();
mMinutesCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
break;
case MotionEvent.ACTION_MOVE:
/**
* Translate angles from [-179,179] to [0,360] to be able to move
* hours hand properly.
*/
// Start Angle
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
mMinutesPrevAngle = mMinutesCurrAngle;
// Finish angle
mMinutesCurrAngle = Math.toDegrees(Math.atan2(event.getX() - xc, yc - event.getY()));
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
calculateHourHandAngle();
animate(clock, translate360Angle(mMinutesPrevAngle), translate360Angle(mMinutesCurrAngle), 0);
animate(hour, mHoursPrevAngle, mHoursCurrAngle, 0);
mHoursPrevAngle = mHoursCurrAngle;
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
Now I be able to know what hour did set the user, because I know the initial position of hands clock, the number of spins and, the minute hand angle.

Android Animation Question

I am trying to write the logic for an animation sequence and can't seem to get the thing right. What I want to happen is: if the user clicks on the screen, the method takes in the touchEvent coordinates, and then changes the movement variables of a sprite so that the sprite travels to where the user touched the screen. I have my "launch" event setup like this.
public void launch(float eventX, float eventY) {
//get the touch event coords and then move the banana to them.
fire = true;
//the x and y variables for the sprite
getX();
getY();
//the target x and y variables
targetX = eventX;
targetY = eventY;
//the total distance the two variable have to "travel"
distanceX = x - targetX;
distanceY = y - targetY;
//variables to update the movement
moveX = distanceX;
moveY = distanceY;
}
Then, I thought I was supposed to put the movement variables in the update method like this:
public void update(long gameTime) {
if(gameTime > frameTicker + framePeriod) {
frameTicker = gameTime;
currentFrame++;
if(currentFrame >= frameNbr){
currentFrame = 0;
}
}
this.sourceRect.left = currentFrame * spriteWidth;
this.sourceRect.right = this.sourceRect.left + spriteWidth;
if(fire == true){
x = (int) moveX;
y = (int) moveY;
}
If the user clicks as it is, the animation shows up like it's supposed to, but then instantaneously goes to the top left corner of the screen or what I have come to understand is (0,0) on a coordinate system. I can't figure out how to slow it down so that it moves at a reasonable space and goes where it is supposed to.
You could put the whole animation in your launch() function if you want.
For instance, at the end of the function something like:
float incrementX = distanceX / 100;
float incrementY = distanceY / 100;
float spriteX = getX();
float spriteY = getY();
bool xDone = false;
bool yDone = false;
while(!(xDone && yDone)) {
if (distanceX <= spriteX) {
spriteX += incrementX; // update the sprite's x coordinate as well
}
if (distanceY <= spriteY) {
spriteY += incrementY; // update the sprite's y coordinate as well
}
try{ Thread.sleep(10) } catch(Exception e) {}
}
That code relies on the sprite starting at a lower x and y than the event; if that's not the case it needs to be modified.

Categories

Resources