点添加机制有问题吗?

时间:2015-03-01 06:00:37

标签: java android game-physics

我有这个游戏,其目标是通过迎面而来的矩形传球。当球的x位置落在球经过的矩形右边的一定边距(正负)内时,记录点增益。由于定时器I每隔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:好的,所以我尝试了这个课程并且它的工作原理...就是它得到了交叉但是当检查返回真实含义时添加得分会变得很疯狂而检查保持为真如果语句是骑自行车疯狂直到它是假的。以下是我实施你给我的课程的方法。

     /*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);

我将类跟踪器调整为:

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

1 个答案:

答案 0 :(得分:3)

我需要一个答案,所以我可以使用monospaced格式化。矩形是否有一个必须由球满足的出口 - 所以它通过?

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

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

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

球路径是连接o的折线。 (这只是一条直线。)

  +--+
  |  | o

o |  |
  +--+

与“好”形状相交。当球已经通过形状时,该计算可以在t2完成。在t0和t1,只有球位置必须保存,并快速检查球是否仍然低于形状的上限。

所以“好”的形状是连接两个间隙的“角柱”的形状,由GGGG标记。

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

稍后根据polylineIntersectsBallView可让您执行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;
    }

需要为前面的每个矩形/间隙创建一个Tracker类的对象。然后必须为每个新的BallView调用方法检查。一旦它返回true,得分+1并丢弃Tracker对象(或添加重新建立原始状态的重置)。