алгоритм перемещения пула - PullRequest
0 голосов
/ 25 июня 2011

Я пытаюсь переместить мяч для пула в Java2ME.Это легко, когда скорость стабильна.Я изменяю координаты x и y шара в соответствии со скоростью x и y.Все они целые.Нет проблем.Однако обычный мяч в бассейне должен идти сначала быстро, затем замедляться и останавливаться.Поскольку координаты x и y шара являются целыми числами, я не могу уменьшить скорость x и y в процентах.Я имею в виду, если скорость равна 9, и я хочу уменьшить ее на 10%, я не могу сделать это «9 * 0,1», потому что она должна быть целым числом.Я знаю, что координаты не могут быть двойными.Что я могу сделать?код:

public void move() {
    //... Move the ball at the given velocity.
    m_x += m_velocityX; // m_x: x coordinate of the ball
    m_y += m_velocityY; // m_y: y coordinate of the ball


    //... ball hits the borders and change the way
    if (m_x < 0) {                  // If at or beyond left side
        m_x         = 0;            // Place against edge and
        m_velocityX = -m_velocityX; // reverse direction.

    } else if (m_x > m_rightBound) { // If at or beyond right side
        m_x         = m_rightBound;    // Place against right edge.
        m_velocityX = -m_velocityX;  // Reverse direction.
    }

    if (m_y < 0) {                 // if we're at top
        m_y       = 0;
        m_velocityY = -m_velocityY;

    } else if (m_y > m_bottomBound) { // if we're at bottom
        m_y       =  m_bottomBound;
        m_velocityY = -m_velocityY;
    }
}

Ответы [ 3 ]

0 голосов
/ 26 июня 2011

Вы должны хранить скорость мяча как velocity и angle.
Кроме того, каждая упомянутая переменная должна быть float или double.

Тогда все будет проще и намного точнее.

Тогда алгоритм будет:

float x,y,velocity,angle
int ix,iy;
...
{
    if(y<0) angle=-angle;
    ... etc, etc.

    velocity*=0.95;
    x+=velocity*cos(angle);
    y+=velocity*sin(angle);

    // And you get your precious integers ...
    ix=floor(x);
    iy=floor(y);
}
0 голосов
/ 30 августа 2011

если скорость равна 9 и я хочу уменьшить ее на 10%, я не могу сделать это "9 * 0,1", потому что она должна быть целым числом

  1. увеличить скорость и координаты (умножить, например, на 256 или сдвинуть влево, например, на 8)
  2. рассчитать уменьшение для увеличенной скорости "9 * 256/10"
  3. рассчитать новую (увеличенную) позицию и скорость
  4. уменьшить

Примерно так, как показано ниже ...

Ball move(Ball ball, Border border, Tracer tracer) {
    tracer.trace("scale stuff up to handle acceleration = velocity / 8");
    Scale scale = new Scale(256);
    Int2D position = scale.up(ball.position);
    Velocity velocity = new Velocity(scale.up(ball.velocity));

    tracer.trace("calculate acceleration as scaled up velocity / 8";
    Int2D acceleration = new Scale(8).down(velocity);

    tracer.trace("Move the ball at the given velocity");
    position = position.plus(velocity);

    tracer.trace("slow down velocity");
    velocity = velocity.slowDown(acceleration);

    tracer.trace("scale back down to original");
    ball = new Ball(scale.down(position), new Velocity(scale.down(velocity)));

    tracer.trace("adjust if ball hits the borders and change the way");
    return border.reflectIfNeeded(ball);
}

interface Tracer { void trace(String msg); }

class Scale {
    final int scale; // better be power of 2
    Scale(int scale) { this.scale = scale; }
    Int2D up(Int2D src) { return new Int2D(src.x * scale, src.y * scale); }
    Int2D down(Int2D src) { return new Int2D(src.x / scale, src.y / scale); }
} // Scale

class Border {
    final Int2D topLeft, bottomRight;
    Border(Int2D topLeft, Int2D bottomRight) {
        this.topLeft = topLeft;
        this.bottomRight = bottomRight;
    }
    Ball reflectIfNeeded(Ball ball) {
        if (within(ball)) { return ball; }
        throw new UnsupportedOperationException("not yet implemented");
    }
    private boolean within(Ball ball) {
        return within(ball.position.x, topLeft.x, bottomRight.x)
                && within(ball.position.y, topLeft.y, bottomRight.y);
    }
    private boolean within(int value, int min, int max) {
        return value > min && value < max;
    }
} // Border

class Ball {
    final Int2D position;
    final Velocity velocity;
    Ball(Int2D position, Velocity velocity) {
        this.position = position;
        this.velocity = velocity;
    }
} // Ball

class Velocity extends Int2D {
    Velocity(Int2D src) { super(src.x, src.y); }
    Velocity slowDown(Int2D acceleration) {
        return new Velocity(this.minus(acceleration));
    }
    Velocity reflectX() { return new Velocity(new Int2D(-x, y)); }
    Velocity reflectY() { return new Velocity(new Int2D(x, -y)); }
} // Velocity

class Int2D {
    final int x, y;
    Int2D(int x, int y) { this.x = x; this.y = y; }
    Int2D plus(Int2D other) { return new Int2D(x + other.x, y + other.y); }
    Int2D minus(Int2D other) { return new Int2D(x - other.x, y - other.y); }
} // Int2D
0 голосов
/ 25 июня 2011

Если скорость должна быть целой, просто обновите значения до пола вычисления с плавающей запятой. Таким образом, чтобы уменьшить скорость на 10%:

m_velocityX = floor(m_velocityX * 0.9);

Возможно, вы захотите когда-нибудь сделать что-нибудь более необычное, но это кажется простым и выполнимым.

...