2015-01-07 162 views
0

我試圖得到兩個球碰撞時的交點,以便我可以在其他方向上反彈它們。我已經嘗試過各種方式來實現它,但沒有成功。可以任何人告訴我,有沒有什麼簡單的方法來檢測碰撞和重新彈跳它。這裏是我的示例代碼,其中的球與設備的屏幕碰撞而反彈: -球對球碰撞檢測

class Ball extends ShapeDrawable { 
     protected static final int BOUNDS_IN = 0; 
     protected static final int BOUNDS_OUT_LEFT = 1; 
     protected static final int BOUNDS_OUT_TOP = 2; 
     protected static final int BOUNDS_OUT_RIGHT = 3; 
     protected static final int BOUNDS_OUT_BOTTOM = 4; 

     public float x; 
     public float y; 
     public int r; 

     public float dx; 
     public float dy; 

     public Ball() { 
      super(new OvalShape()); 

      getPaint().setColor(0xff888888); 
     } 

     public void reBounds() { 
      setBounds((int) x - r, (int) y - r, (int) x + r, (int) y + r); 
     } 

     public void step(long deltaTimeMs) { 
      // Log.i(TAG, "Time:" + deltaTimeMs); 

      x += dx * deltaTimeMs/100; 
      y += dy * deltaTimeMs/100; 

      // Log.i(TAG, "x: "+x); 
     } 

     public int inBounds(int minx, int miny, int maxx, int maxy) { 
      if (dx > 0 && x + r > maxx) { 
       return BOUNDS_OUT_RIGHT; 
      } else if (dx < 0 && x - r < minx) { 
       return BOUNDS_OUT_LEFT; 
      } else if (dy > 0 && y + r > maxy) { 
       return BOUNDS_OUT_BOTTOM; 
      } else if (dy < 0 && y - r < miny) { 
       return BOUNDS_OUT_TOP; 
      } 
      return BOUNDS_IN; 
     } 
    }; 

    public CustomDrawableView(Context context) { 
     super(context); 

     Log.i(TAG, "Constructor Start"); 

     balls = new ArrayList<Ball>(); 

     update(); 

     Log.i(TAG, "Constructor End"); 
    } 

    protected void onFirstDraw(Canvas canvas) { 
     addRandomBalls(5); 
    } 

    protected void addRandomBalls(int number) { 
     Ball mBall; 

     Random r = new Random(); 

     for (int i = 0; i < number; i++) { 
      mBall = new Ball(); 
      mBall.x = r.nextInt(MAX_X); 
      mBall.y = r.nextInt(MAX_Y); 
      mBall.r = 40; 
      mBall.dx = r.nextInt(50) - 25; 
      mBall.dy = r.nextInt(50) - 25; 

      balls.add(mBall); 
     } 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

     MAX_X = MeasureSpec.getSize(widthMeasureSpec); 
     MAX_Y = MeasureSpec.getSize(heightMeasureSpec); 
    } 

    protected void onDraw(Canvas canvas) { 
     // Log.i(TAG, "onDraw Start"); 

     if (EXECUTE_ON_DRAW == false) { 
      EXECUTE_ON_DRAW = true; 

      onFirstDraw(canvas); 
     } 

     for (Ball b : balls) { 
      // Log.i(TAG, "ball draw"); 
      b.reBounds(); 
      b.draw(canvas); 
     } 
    } 

    public void update() { 
     long now = System.currentTimeMillis(); 

     long difference = now - then; 
     int inBound; 
     for (Ball b : balls) { 
      b.step(difference); 
      inBound = b.inBounds(0, 0, MAX_X, MAX_Y); 

      if (inBound == Ball.BOUNDS_OUT_BOTTOM 
        || inBound == Ball.BOUNDS_OUT_TOP) { 
       b.dy *= -1; 
      } else if (inBound == Ball.BOUNDS_OUT_LEFT 
        || inBound == Ball.BOUNDS_OUT_RIGHT) { 
       b.dx *= -1; 
      } 
     } 

     then = now; 

     invalidate(); 

     mRedrawHandler.sleep(60); 
    } 
+0

您需要使用空間索引數據結構來有效地執行此操作。一個比較簡單的就是四叉樹 - 有關實現它的一些信息並將其用於碰撞檢測可以在這裏找到:https://graphics.ethz.ch/~achapiro/gc.html – BadZen

回答

0

那麼不知道,如果我得到你的意思,但兩個圓圈之間的碰撞檢查最簡單,最全成的方法是檢查半徑。你必須在每個球的中心找到x和y座標。 它應該看起來像這樣:centerX = x + widthOfBall/2; centerY = y + heigthOfBall/2;要檢查兩個球之間的碰撞,您需要檢查兩個半徑的和是否高於兩個球中心之間的距離。檢查兩個中心之間的距離谷歌兩點之間的距離。

+0

Vedad - 檢查所有對碰撞成本O (n^2)在屏幕上的球數 - 可能不適合任何中等大n。空間索引是必要的。 – BadZen

+0

'兩半半徑的總和'我認爲你是指兩半球半徑或兩半徑半徑的總和? – Mike

+0

首先對不起我的英語,它不是那麼好:)是的,我的意思是兩個半徑的總和。 –