Stupe
Stupe

Reputation: 83

Android Math does not work

private void gotoPos()
{
    spaceX = x2 - x;
    spaceY = y2 - y;
    if (Math.abs(spaceX) >= Math.abs(spaceY)) {
        xSpeed = Math.round(spaceX * (3/Math.abs(spaceX)));
        ySpeed = Math.round(spaceY * (3/Math.abs(spaceX)));
    }

With this code I want to move an object to the position x2 and y2. x and y is the current position of the object. spaceX is the space that is between the object and the x position it should go to. The same for spaceY.

But I don't want the object to move more than 3 Pixels per draw.

Example: object position: x = 35, y = 22

Point it should go to: x2 = 79, y2 = 46

space between them: spaceX = 79-35 = 44, spaceY = 46-22 = 24

spaceX is bigger then spaceY so:

xSpeed = 44 * (3/44) = 3, ySpeed = 24 * (3/44) = 1.63 = 2

But it does not work like this. When I start the app the object does not go to x2 and y2. If I change xSpeed = spaceX; ySpeed = spaceY;

The object moves to the position but I do not want it to go there instantly

Complete Code:

public class Sprite
{
private boolean walking = true;
private int actionWalk = 0;
private Random rnd;
private int checkIfAction;
private int nextAction = 0;
static final private int BMP_COLUMNS = 4;
static final private int BMP_ROWS = 4;
private int[] DIRECTION_TO_SPRITE_SHEET = { 1, 0, 3, 2 };
public int x=-1;
private int y=-1;
public int xSpeed;
private int ySpeed;
private int width;
private int height;
private int bottomSpace;
private Bitmap bmp;
private GameView theGameView;
private int currentFrame=0;
private int x2, y2;
private boolean isTouched;
private int spaceX, spaceY;

D

public Sprite(GameView theGameView, Bitmap bmp)
{
    this.theGameView = theGameView;
    this.bmp = bmp;
    this.width = bmp.getWidth() / BMP_COLUMNS;
    this.height = bmp.getHeight() / BMP_ROWS;
    rnd = new Random();
    xSpeed = 0;
    ySpeed = 0;
}

public void shareTouch(float xTouch, float yTouch)
{
    x2 = (int) xTouch;
    y2 = (int) yTouch;
    isTouched = true;
}
    private void gotoPos()
{
    spaceX = x2 - x;
    spaceY = y2 - y;
    if (Math.abs(spaceX) >= Math.abs(spaceY)) {
        xSpeed = Math.round(spaceX * (3/Math.abs(spaceX)));
        ySpeed = Math.round(spaceY * (3/Math.abs(spaceX)));
    }
    else {
        xSpeed = spaceX;
        ySpeed = spaceY;
    }
}

D

private void bounceOff()
{
    bottomSpace = theGameView.getHeight() - y;
    if (x > theGameView.getWidth() - (width * theGameView.getDensity()) - xSpeed - bottomSpace / 2 || x + xSpeed < bottomSpace / 2)
    {
        xSpeed = -xSpeed;
    }
    x = x + xSpeed;
    if (y > theGameView.getHeight() - (height * theGameView.getDensity()) - ySpeed || y + ySpeed < theGameView.getHeight() / 2)
    {
        ySpeed = -ySpeed;
    }
    y = y + ySpeed;
    currentFrame = ++currentFrame % BMP_COLUMNS;
}

d

public void onDraw(Canvas canvas)
{
    if (x == -1)
    {
        x = (theGameView.getWidth() / 2);
        y = (theGameView.getHeight() / 2 + theGameView.getHeight() / 4);
    }
    if (isTouched == true)
    {
        gotoPos();
    }
    /*      if (nextAction == 100)
     {
     action();
     nextAction = 0;
     }
     nextAction += 1;*/
    bounceOff();
    int sourceX, sourceY;
    if (walking == true)
    {
        sourceX = currentFrame * width; 
    }
    else
    {
        sourceX = 0;
    }
    sourceY = getAnimationRow() * height;
    Rect source = new Rect(sourceX, sourceY, sourceX + width, sourceY + height);
    Rect destine = new Rect(x, y, (int) (x + (width * theGameView.getDensity())), (int) (y + (height * theGameView.getDensity())));
    canvas.drawBitmap(bmp, source, destine, null);
}

d

private int getAnimationRow()
{
    double directionDouble = (Math.atan2(xSpeed, ySpeed) / (Math.PI / 2) + 2);
    int spriteDir = (int) Math.round(directionDouble) % BMP_ROWS;
    return DIRECTION_TO_SPRITE_SHEET[spriteDir];
}

}

Upvotes: 0

Views: 189

Answers (3)

Jongware
Jongware

Reputation: 22478

There is a logical fallacy in your code: what if Math.abs(spaceX) < Math.abs(spaceY))? Then your object would not move at all.

What you calculate, 'x-distance / y-distance', is usually considered angle, not speed. Speed is 'distance / time'. You can calculate the distance, and you should decide on a reasonable speed for your object. Since you know your fps -- 20 --, you can then calculate how many pixels your object needs to move in each frame.

Upvotes: 0

Saj
Saj

Reputation: 18712

Given points a Vector2d(x, y) and b Vector2d(x2, y2)-

Create a vector V from a to b by subtracting b from a as you did. Normalize vector V into a unit vector and multiply it with the distance you want. Then add the resulting vector to point a.

On update:

a.add(b.subtract(a).norm().multiply(d));

Depending on your vector implementation, modify properly the above pseudo code.

Upvotes: 0

Uwe Plonus
Uwe Plonus

Reputation: 9974

Simple problem: you use integer arithmetic and don't understand this:

spaceX * (3/Math.abs(spaceX))

The result will be 0 in nearly all cases as 3/x with x > 3 is 0 all the time.

To make your program working use either floating point arithmetic or rewrite your formulas to work as expected.

To use floating point arithetic you have to change to

spaceX * (3.0/Math.abs(spaceX))

assuming that you variable spaceX is also floating point.

Also you can use

(spaceX * 3) / Math.abs(spaceX)

if you want to stay with integers (what I suppose).

Upvotes: 1

Related Questions