java - 加点机制麻烦?

标签 java android game-physics

我有这个游戏,目标是将球传过迎面而来的带有空隙的矩形。当球的 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 值的右侧,这些点就会开始添加。但是,发生的情况是,一旦矩形通过,这些点就会继续增加数百个。这是我插入的 boolean 方法:

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)并且它有效......它得到了交叉点但是当检查返回真实含义而检查保持真实时它会疯狂地增加分数那些 if 语句是骑自行车发疯,直到它是假的。这是我如何实现您给我的类(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);

我将类 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 |  |
  +--+

与“好”形状相交。该计算可以在 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 对象(或添加重新建立原始状态的重置)。

关于java - 加点机制麻烦?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28790652/

相关文章:

android - QDir mkpath 不会在 android 上创建目录

python - 重绘图像不起作用?

unity-game-engine - 向 2D 主体添加力,同时确保速度始终沿主体向上的方向

java - Volley 中是否有回调来通知已完成的网络调用,例如异步任务中的 onPostExecute?

android - 如何对齐第一个元素填充所有可用空间的 2 个元素?

java - 单击按钮Android后绘制

javascript - 添加相对于对象的速度

java - Java中如何异步调用方法

JavaFX 未启动

java - 异步读取消息时检查 JMS 类型