检查父母不同的两个不同的自定义视图之间的冲突

时间:2018-08-30 16:10:40

标签: java android android-layout android-studio android-studio-3.0

我有一个自定义视图“ Stick”,它扩展了RelativeLayout。 我有另一个自定义视图“球”,它也扩展了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(){

    }

}

下面是Ball类

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;
}

1 个答案:

答案 0 :(得分:0)

好吧,请尝试使用这种布尔方法,如果球碰撞,则返回true。

public boolean checkCollision(View ball)
{
    boolean result = false;

    for(Stick stick : Stick.getStickList())
    {
         if(collision(ball, stick))
         {
             result = true;
             break;
         }
         else result = false;
     }

    return result;
}

/*Gets View HitRect*/
public boolean collision(View a, View b)
{
   Rect aRect = new Rect();
   a.getHitRect(aRect);
   Rect bRect = new Rect();
   b.getHitRect(bRect);
   return aRect.intersect(bRect);
}

以及游戏的Render()方法:

Thread t = new Thread() {
 @Override
 public void run() {
 try {
    while (!isInterrupted()) {
         Thread.sleep(100);
         runOnUiThread(new Runnable() {
         @Override
         public void run(){Render();}});}
         }catch (InterruptedException e) {}}};

 t.start();
}

public void Render()
{
    if(checkCollision(ball))
    {
      //Do something
    }
}