台球移动算法

发布于 2024-11-17 04:26:55 字数 1125 浏览 5 评论 0原文

我正在尝试在 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;
    }
}

I am trying to move a pool ball in Java2ME. It is easy when the velocity is stable. I change the x and y coordinate of the ball according to x and y velocity. They are all integers. No problem. However a normal pool ball has to go first fast then slowdown and stop. Because the x and y coordinates of the ball are integers, I can't decrease the x and y velocity by percentage. I mean if the velocity is 9 and I want to decrease it by 10% I cant do it "9 * 0.1" because it has to be an integer. I know the coordinates can't be double. What can I do?
the code:

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;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

童话里做英雄 2024-11-24 04:26:55

如果速度必须是积分,只需将值更新为浮点计算的下限即可。因此,要将速度降低 10%:

m_velocityX = floor(m_velocityX * 0.9);

有一天您可能想做一些更奇特的事情,但这看起来很简单且可行。

If the velocity must be integral, just update the values to the floor of the floating-point calculation. So to reduce velocity by 10%:

m_velocityX = floor(m_velocityX * 0.9);

You might want to do something fancier someday, but this seems simple and workable.

溺孤伤于心 2024-11-24 04:26:55

您应该将球速度存储为速度角度
此外,提到的每个变量都应该是 floatdouble

那么一切都会变得更容易,也更准确。

该算法将是:

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);
}

You should store the ball speed as velocity and angle.
Also, every variable mentioned should be float or double.

Then everything will be easier, and much more accurate.

The algorithm will then be:

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);
}
鼻尖触碰 2024-11-24 04:26:55

如果速度是 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

if the velocity is 9 and I want to decrease it by 10% I cant do it "9 * 0.1" because it has to be an integer

  1. scale up the velocity and coordinates (multiply eg by 256 or shift left by eg 8)
  2. calculate decrease for scaled up velocity "9 * 256 / 10"
  3. calculate new (scaled up) position and velocity
  4. scale down

About like below...

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文