碰撞检测常用的分三类:圆形检测、矩形检测、像素检测。像素检测是最为精确的一种,但是它对性能消耗也是最大的一种,因为一般游戏中很少用到。
矩形检查
思路:可以检查两个矩形的相对位置,如果RectA在RectB的上下左右,且两个矩形没有挨着,则可以判定他们没有碰撞,反之就发生碰撞了。
/** * * @param x1 矩形1的X坐标 * @param y1 矩形1的Y坐标 * @param w1 矩形1的宽 * @param h1 矩形1的高 * @param x2 矩形2的X坐标 * @param y2 矩形2的Y坐标 * @param w2 矩形2的宽 * @param h2 矩形的高 * @return */ public boolean CheckRectCollsion(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) { if (x1 >= x2 && x1 >= x2 + w2) { return false; } else if (x1 <= x2 && x1 + w1 <= x2) { return false; } else if (y1 >= y2 && y1 >= y2 + h2) { return false; } else if (y1 <= y2 && y1 + h1 <= y2) { return false; } return true; }
实现一个完整的例子
public class MySurfaceView extends SurfaceView implements Callback,Runnable { private SurfaceHolder surfaceHolder; private Paint paint; private Thread thread; private boolean flag; int sleeptime=100; //定义两个矩形的宽高坐标 private int x1 = 10, y1 = 110, w1 = 40, h1 = 40; private int x2 = 100, y2 = 110, w2 = 40, h2 = 40; //便于观察是否发生了碰撞设置一个标识位 private boolean isCollsion; public MySurfaceView(Context context) { super(context); surfaceHolder = this.getHolder(); surfaceHolder.addCallback(this); paint = new Paint(); paint.setColor(Color.WHITE); paint.setAntiAlias(true); setFocusable(true); //设置焦点 } @Override public void run() { Canvas canvas=null; while (flag) { try { canvas=surfaceHolder.lockCanvas(); synchronized (canvas) { myDraw(canvas); } } catch (Exception e) { Log.e("collsion", e.getMessage()); }finally{ if(canvas!=null){ surfaceHolder.unlockCanvasAndPost(canvas); } } try { Thread.sleep(sleeptime); } catch (Exception e) { Log.e("collsion", e.getMessage()); } } } /** * 触屏事件监听 */ @Override public boolean onTouchEvent(MotionEvent event) { //让矩形1随着触屏位置移动 x1 = (int) event.getX() - w1 / 2; y1 = (int) event.getY() - h1 / 2; if (CheckRectCollsion(x1, y1, w1, h1, x2, y2, w2, h2)) { isCollsion = true; } else { isCollsion = false; } return true; } public void myDraw(Canvas canvas) { canvas.drawColor(Color.BLACK); if (isCollsion) { paint.setColor(Color.RED); paint.setTextSize(20); canvas.drawText("碰撞了!", 0, 30, paint); } else { paint.setColor(Color.WHITE); } //绘制两个矩形 canvas.drawRect(x1, y1, x1 + w1, y1 + h1, paint); canvas.drawRect(x2, y2, x2 + w2, y2 + h2, paint); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder arg0) { flag = true; //实例线程 thread = new Thread(this); if(!thread.isAlive()){ //启动线程 thread.start(); } } @Override public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub } /** * * @param x1 矩形1的X坐标 * @param y1 矩形1的Y坐标 * @param w1 矩形1的宽 * @param h1 矩形1的高 * @param x2 矩形2的X坐标 * @param y2 矩形2的Y坐标 * @param w2 矩形2的宽 * @param h2 矩形的高 * @return */ public boolean CheckRectCollsion(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) { if (x1 >= x2 && x1 >= x2 + w2) { return false; } else if (x1 <= x2 && x1 + w1 <= x2) { return false; } else if (y1 >= y2 && y1 >= y2 + h2) { return false; } else if (y1 <= y2 && y1 + h1 <= y2) { return false; } return true; }