我有一个自定义视图“ 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;
}
答案 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
}
}