Я пытаюсь получить точку пересечения, когда два шара сталкиваются, чтобы я мог отбросить их в другом направлении. я пробовал различный способ реализовать его, но не получил успеха. Может кто-нибудь скажет мне, что есть простой способ обнаружить столкновение и повторить его. Вот мой пример кода, где шары сталкиваются с экраном устройства и отскакивает назад: -Обнаружение столкновения шара с мячом
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);
}
Для эффективной работы вам необходимо использовать пространственную индексную структуру данных. Относительно простой - квадтрит. Некоторую информацию о реализации и использовании его для обнаружения столкновений можно найти здесь: https://graphics.ethz.ch/~achapiro/gc.html – BadZen