Java 加点机构故障?

Java 加点机构故障?,java,android,game-physics,Java,Android,Game Physics,我有一个游戏,目标是把一个球穿过有缝隙的迎面而来的长方形。当球的x位置落在球经过的矩形右侧的某个范围内(加号或减号)时,记录点数增益。由于我设置的计时器每10毫秒循环一次,因此出现了一个问题,因为有时它工作正常;每个传递的矩形都会增加一个点,但其他时候它甚至不会注册一个矩形传递,或者它会两次注册落在边距中的球的x值,给用户一个矩形传递两个点。以下是此机制的部分代码: /*********Keeps track of score and update TextView with score****

我有一个游戏,目标是把一个球穿过有缝隙的迎面而来的长方形。当球的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() + "");
                    }
                });

            }
我将类跟踪器调整为:

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  ;
}
}
公共类跟踪器{
private int lastX=Integer.MAX_值;
私有int gateX;
公共无效setGateX(int gateX){
this.gateX=gateX;
}
公共布尔检查(BallView ball){
if(lastX==Integer.MAX_值){
lastX=Math.round(ball.getX());
}
int currX=Math.round(ball.getX());
返回currX==gateX | | lastX-gateX<0&&currX-gateX>0
||lastX-gateX>0&&currX-gateX<0;
}
}

我需要一个答案,这样我就可以使用等距格式。长方形是否有一个必须被球碰到的出口,这样球才能通过

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

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

o |  |
  +--+       t1
--------------
球路径是连接o的多段线。(这里只是一条直线。)

与“好”形状相交。当球通过形状时,可以在t2处进行此计算。在t0和t1,只需保存球的位置,并快速检查球是否仍低于形状的上限

所以“好”的形状是连接两个gap的“角极”的形状,用GGGG标记

  +--+
  |  | o
  GGGG
o |  |
  +--+
稍后根据
多段线相交
,使用
球视图
可以执行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;
    }
公共类跟踪器{
private int lastX=Integer.MAX_值;
私有int gateX;
公共追踪器(int gateX){
this.gateX=gateX;
}
公共布尔检查(BallView ball){
if(lastX==Integer.MAX_值){
lastX=ball.getX();
返回;
}
int currX=ball.getX();
返回电流x==gateX||
lastX-gateX>0&&currX-gateX<0||
lastX-gateX<0&&currX-gateX>0;
}

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

我不知道矩形和球是如何移动的。但是一个精确的、与循环无关的方法是计算点的路径与矩形的交点。这样,算法使用整个“历史”,而不仅仅是一个“快照”。-所需的算法甚至可能在java.awt中(不确定android有什么).@laune所以你建议我将该代码移出计时器,并使用另一种算法?我该怎么做呢?因为我不知道你怎么能不使用计时器,因为我的游戏移动得非常快,为了获得传球的实例,我需要使用快速采样计时器。我必须不断用分数更新文本视图,以便必须拍摄“快照”以保持分数新鲜。不,代码应该保留在计时器中,但我建议使用不同的算法。从概念上讲,球描述了一条曲线(多段线),每当该多段线与某个区域(矩形?)相交时,就会发生“命中”。因此,在t0处,球在外,在矩形下方,在tn处,球在矩形上方。然后,多段线是在t0-t1-…tn处的球,如果它与矩形相交,则有一个“命中”。您仍然需要对球的轨迹进行高速采样,但您可能会错过实际位于矩形中的球。@laune但使用这种方法,您仍然可能会错过您所说的击球,我不希望这样,因为我的用户可能会认为我的应用程序质量不高,因为它甚至无法准确记分。我已经在高速下尝试了您所说的内容采样率很高,有时仍然会漏掉球击。我应该接受这个错误作为不可修复的东西,还是继续寻找答案?我的意思是,我能做的最好的事情是改变mPointMargin变量,将点区域扩展为矩形,球移动得更快,不会漏掉一分。我宁愿球员得到两分,而不是一分都没有。。不,它不会错过球击数-我从来没有说过。你肯定会计算球击数。游戏的运作方式是球穿过矩形的缝隙,从右边靠近(向左移动)。t0从左边穿过,t1在矩形缝隙中,t2在另一边(右边穿过矩形)?虚线是缺口的入口,实线是矩形的边界吗?在这种情况下,t1图是一个球员死亡,因为它接触到了矩形。啊,我们越来越近了。所以你想让我看看球的路径的一条策略线是否与良好的形状重叠(即缺口)?如果我的计时器每10毫秒采样一次,那么我不是会得到多个正确的语句吗?或者你的意思是计算与矩形右侧重叠的多边形线的数量吗?我建议在球位于矩形左侧时立即进行计算。你必须收集一些球的位置t0、t1、…tn-它们定义了多段线。Now:如果与GGGGG相交,则得一分。如果与矩形中两个非GGGGG区域相交,则该球员的球无效。
  +--+
  |  | o

o |  |
  +--+
  +--+
  |  | o
  GGGG
o |  |
  +--+
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;
    }