池球移动算法

时间:2011-06-25 16:34:57

标签: java-me midp

我正在尝试在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 :(得分:0)

如果速度必须是整数,只需将值更新为浮点计算的最低值。所以要将速度降低10%:

m_velocityX = floor(m_velocityX * 0.9);

你可能希望有一天能做些更好的事情,但这看起来很简单而且可行。

答案 1 :(得分:0)

您应该将球速保存为velocityangle 此外,提及的每个变量都应为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);
}

答案 2 :(得分:0)

  

如果速度是9而我想减少10%我不能“9 * 0.1”,因为它必须是一个整数

  1. 放大速度和坐标(乘以例如256或向左移动例如8)
  2. 计算放大速度“9 * 256/10”
  3. 的减少量
  4. 计算新的(放大的)位置和速度
  5. 缩小
  6. 关于如下......

    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