加点机制麻烦?

Point adding mechanism troubles?

我有这个游戏,目标是将球传过迎面而来的有空隙的矩形。当球的 x 位置落在距球所经过的矩形右侧一定范围内(正或负)时,将记录得分增益。由于我设置的定时器每 10 毫秒循环一次,因此出现了一个问题,因为有时它工作正常;每个通过的矩形都会添加一个点,但有时它甚至没有注册矩形传球,或者它会注册球的 x 值两次落入边缘,从而为用户提供一个矩形传球的两个点。这是此机制的部分代码:

/*********Keeps track of score and update TextView with score************/
            if (rectWhite1.getTheRight() > Math.round(mBallPos.x) - 5 && rectWhite1.getTheRight() < Math.round(mBallPos.x) + 5) {

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mScoreboard.addPoint();
                        scoreTextView.setText(mScoreboard.getScore() + "");
                    }
                });

            }

            if (rectWhite2.getTheRight() > Math.round(mBallPos.x) - mPointMargin && rectWhite2.getTheRight() < Math.round(mBallPos.x) + mPointMargin) {

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mScoreboard.addPoint();
                        scoreTextView.setText(mScoreboard.getScore() + "");
                    }
                });


            }

            if (rectWhite3.getTheRight() > Math.round(mBallPos.x) - mPointMargin && rectWhite3.getTheRight() < Math.round(mBallPos.x) + mPointMargin) {

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mScoreboard.addPoint();
                        scoreTextView.setText(mScoreboard.getScore() + "");
                    }
                });

            }

mPointMargin 是作为成员变量设置的以像素为单位的数量,它会随着游戏速度的加快而动态变化,以便游戏准确地注册通过。即使我解决了这个错误,它仍然会出错,并且偶尔会漏掉一个分数或一次传球得到双倍分数。无论如何,是否有一种更准确的方式来做到这一点,即添加一次分数并终止该 if 语句,直到再次需要它,或者是否有另一种方法来解决这个问题?

编辑: 我破解了这个机制的代码,结果很糟糕。我希望一旦球位于矩形右侧 x 值的右侧,这些点就会开始添加。但是,发生的情况是,一旦矩形通过,这些点就会继续增加数百个。这是我插入的布尔方法:

public boolean polylineIntersects(BallView ball, int right) {
    boolean intersects = false;
    int ballPos1 = 0;
    int ballPos2 = 0;

    if (ball.getX() < right) {
        ballPos1 = Math.round(ball.getX());
    }
    else if (ball.getX() > right) {
        ballPos2 = Math.round(ball.getX());
    }

    if (ballPos2 > ballPos1) {
        intersects = true;
    }
    else {
        intersects = false;
    }


    return intersects;
}

无论如何,如果我不使用实际绘制折线,这是否可行,因为我找不到检测与指定区域相交 Polyline (Android Developers) 的方法。

编辑 2: 好的,所以我尝试了 class 并且它起作用了......它得到了交叉点但是当检查 returns true 意思是 check 保持 true 那些 if 语句循环疯狂直到它为 false。下面是我如何实现你给我的 class。

     /*Declared Tracker objects in OnCreate*/

//What is below is in OnResume

mTmr3 = new Timer();
    mTsk3 = new TimerTask() {
        @Override
        public void run() {


            mTracker.setGateX(rectWhite1.getTheRight());
            mTracker2.setGateX(rectWhite2.getTheRight());
            mTracker3.setGateX(rectWhite3.getTheRight());

            //*********Keeps track of score and update TextView with score*************
            if (mTracker.check(mBallView)) {
                mediaPlayer1.start();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mScoreboard.addPoint();
                        scoreTextView.setText(mScoreboard.getScore() + "");

                    }
                });

            }

            if (mTracker2.check(mBallView)) {
                mediaPlayer1.start();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mScoreboard.addPoint();
                        scoreTextView.setText(mScoreboard.getScore() + "");

                    }
                });

            }

            if (mTracker3.check(mBallView)) {
                mediaPlayer1.start();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mScoreboard.addPoint();
                        scoreTextView.setText(mScoreboard.getScore() + "");

                    }
                });

            }
        }
    };
    mTmr3.schedule(mTsk3, 10, 10);

我将 class Tracker 调整为:

public class Tracker {
private int lastX = Integer.MAX_VALUE;
private int gateX;


public void setGateX(int gateX) {
    this.gateX = gateX;
}

public boolean check(BallView ball) {
    if (lastX == Integer.MAX_VALUE) {
        lastX = Math.round(ball.getX());
    }
    int currX = Math.round(ball.getX());
    return currX == gateX || lastX - gateX < 0 && currX - gateX > 0
            || lastX - gateX > 0 && currX - gateX < 0  ;
}
}

我需要一个答案,以便我可以使用等宽格式进行格式化。矩形是否有球必须遇到的出口 - 所以它通过?

--------------
  +--+
  |  | o

  |  |
  +--+    t0
--------------
  +--+
  |  |  

o |  |
  +--+       t1
--------------

球道是连接o的多段线。 (这里只是一条直线。)

  +--+
  |  | o

o |  |
  +--+

与 "good" 形状相交。该计算可以在 t2 完成,此时球已通过该形状。在t0和t1,只需要保存球的位置,并快速检查球是否仍在形状的上限以下。

因此 "good" 形状是连接两个间隙 "corner poles" 的形状,用 GGGG 标记。

  +--+
  |  | o
  GGGG
o |  |
  +--+

稍后 根据polylineIntersects,一个BallView让你做getX。

public class Tracker {
    private int lastX = Integer.MAX_VALUE;
    private int gateX;
    public Tracker( int gateX ){
        this.gateX = gateX;
    }
    public boolean check( BallView ball ){
        if( lastX == Integer.MAX_VALUE ){
            lastX = ball.getX();
            return;
        }
        int currX = ball.getX();
        return currX == gateX ||
               lastX - gateX > 0 && currX - gateX < 0 ||
               lastX - gateX < 0 && currX - gateX > 0;
    }

需要为前面的每个rectangle/gap 创建一个class Tracker 的对象。然后必须为每个新的 BallView 调用方法检查。一旦 returns 为真,得分 +1 并丢弃 Tracker 对象(或添加重新建立原始状态的重置)。