У меня есть собственное представление "Stick", которое расширяет RelativeLayout.
У меня есть другой пользовательский вид "Ball", который также расширяет RelativeLayout. И их родители разные. В любое время на экране есть несколько (или один) автоматически движущихся шаров и палочек. Я хочу получать информацию, когда мяч сталкивается с палкой. Значит, я хочу что-то сделать, когда происходит столкновение. В настоящее время я запускаю бесконечный цикл, чтобы проверить, пересекается ли текущий ограничивающий прямоугольник шара с текущим ограничивающим прямоугольником палочек. Но это слишком дорого, и если на экране несколько палочек и шаров, этот метод не работает или почти не работает. Есть ли лучший способ сделать это или есть слушатель столкновения зрения в Android?
Ниже приведен класс ручки
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.widget.RelativeLayout;
import java.util.ArrayList;
public class Stick extends RelativeLayout {
int height;
String dest;
Context context;
RelativeLayout.LayoutParams layoutParams;
private static int stickDecelerate = 2000;
private static ArrayList<Stick> stickList = new ArrayList<Stick>();
public static ArrayList<Stick> getStickList() {
return stickList;
}
public static int getStickDecelerate() {
return stickDecelerate;
}
public static void setStickDecelerate(int stickDecelerate) {
Stick.stickDecelerate = stickDecelerate;
}
public Stick(Context context){
super(context);
}
public Stick(Context context, int height, String dest, int leftMargin, int topMargin) {
super(context);
this.context = context;
this.height = height;
this.dest = dest;
if(dest.equals("left") || dest.equals("right")){
layoutParams = new RelativeLayout.LayoutParams(height*5, height);
layoutParams.setMargins(leftMargin-(height*5)/2, topMargin-height/2, 0, 0);
}
else{
layoutParams = new RelativeLayout.LayoutParams(height, height*5);
layoutParams.setMargins(leftMargin-height/2, topMargin-(height*5)/2, 0, 0);
}
this.setLayoutParams(layoutParams);
}
public void release(){
Stick stick = new Stick(context);
stick.setBackgroundColor(Color.YELLOW);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(this.getWidth(), this.getHeight());
stick.setLayoutParams(layoutParams);
this.addView(stick);
ObjectAnimator animation;
if(dest.equals("right")) animation = ObjectAnimator.ofFloat(stick, "translationX", GameScreen.getMin());
else if(dest.equals("left")) animation = ObjectAnimator.ofFloat(stick, "translationX", -GameScreen.getMin());
else if(dest.equals("up")) animation = ObjectAnimator.ofFloat(stick, "translationY", -GameScreen.getMin());
else animation = ObjectAnimator.ofFloat(stick, "translationY", GameScreen.getMin());
animation.setDuration(stickDecelerate);
animation.start();
stickList.add(stick);
animation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
stickList.remove(stick);
stick.setVisibility(View.GONE);
}
});
}
public void preview(){
}
}
ниже класса Мяч
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.view.View;
import android.widget.RelativeLayout;
import java.util.Random;
public class Ball extends View{
int circleBounds;
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canvas.drawCircle(circleBounds/4, circleBounds/4, circleBounds/4, paint);
}
public Ball(Context context) {
super(context);
}
public Ball(Context context, int circleBounds) {
super(context);
this.circleBounds = circleBounds;
RelativeLayout.LayoutParams ballParams = new RelativeLayout.LayoutParams(circleBounds/2, circleBounds/2);
this.setLayoutParams(ballParams);
startMoving();
}
private void startMoving(){
Random randomAngle = new Random();
int random = randomAngle.nextInt(360);
int x = (int) ((int) GameScreen.getMin()*Math.cos(random));
int y = (int) ((int) GameScreen.getMin()*Math.sin(random));
ObjectAnimator animX = ObjectAnimator.ofFloat(this, "x", x);
ObjectAnimator animY = ObjectAnimator.ofFloat(this, "y", y);
long animDuration = (long) (Stick.getStickDecelerate()*2.2);
animX.setDuration(animDuration);
animY.setDuration(animDuration);
AnimatorSet animation = new AnimatorSet();
animation.playTogether(animX, animY);
animation.start();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if(Important.checkCollision(Ball.this)){
animation.cancel();
Ball.this.setVisibility(View.GONE);
return;
}
handler.postDelayed(this, 0);
}
}, 0);
animation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
Ball.this.setVisibility(View.GONE);
}
});
}
}
и ниже - метод проверки столкновения
public static boolean checkCollision(View ball){
ArrayList<Stick> stickList = Stick.getStickList();
int[] rec1Pos = new int[2];
ball.getLocationOnScreen(rec1Pos);
int v1_w = ball.getWidth();
int v1_h = ball.getHeight();
Rect ballBound = new Rect(rec1Pos[0], rec1Pos[1], rec1Pos[0] + v1_w, rec1Pos[1] + v1_h);
for(Stick stick:stickList){
int[] rec2Pos = new int[2];
stick.getLocationOnScreen(rec2Pos);
int v2_w = stick.getWidth();
int v2_h = stick.getHeight();
Rect stickBound = new Rect(rec2Pos[0], rec2Pos[1], rec2Pos[0] + v2_w, rec2Pos[1] + v2_h);
return ballBound.intersect(stickBound);
}
return false;
}