2015-01-07 3 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; центр Y = y + heigthOfBall/2; Чтобы проверить столкновения между двумя шарами, вам нужно только проверить, находится ли сумма двух радиусов выше расстояния между двумя центрами шаров. Чтобы проверить расстояние между двумя центрами, расстояние между двумя точками.

+0

Vedad - проверка всех пар на затраты на столкновение O (n^2) в количестве шаров на экране - вероятно, не подходит для любого умеренно большого n. Требуется пространственный индекс. – BadZen

+0

'сумма двух половин радиуса', я думаю, вы имеете в виду сумму« двух половинного диаметра »или« двукратного радиуса », если оба шара получили одинаковый радиус? – Mike

+0

Ну сначала извините за мой английский, это не так хорошо :) Да, я имел в виду сумму двух радиусов. –

Смежные вопросы