圆形碰撞 原理: 利用两个圆心之间的距离进行判定.当两个圆心的距离小于半径之和则碰撞.
像素碰撞 原理:不适用 遍历所有像素 检测 太多了
多矩形碰撞 原理:设置多个矩形碰撞检测区域 检测碰撞矩形数组 与另一碰撞矩形数组之间的位置关系.
矩形碰撞 代码:
public class MySurfaceView extends SurfaceView implements Callback, Runnable {private SurfaceHolder sfh;private Paint paint;private Thread th;private boolean flag;private Canvas canvas;private int screenW, screenH;//定义两个矩形的宽高坐标private int x1 = 10, y1 = 110, w1 = 40, h1 = 40;private int x2 = 100, y2 = 110, w2 = 40, h2 = 40;//便于观察是否发生了碰撞设置一个标识位private boolean isCollsion;/** * SurfaceView初始化函数 */public MySurfaceView(Context context) {super(context);sfh = this.getHolder();sfh.addCallback(this);paint = new Paint();paint.setColor(Color.WHITE);paint.setAntiAlias(true);setFocusable(true);}/** * SurfaceView视图创建,响应此函数 */@Overridepublic void surfaceCreated(SurfaceHolder holder) {screenW = this.getWidth();screenH = this.getHeight();flag = true;//实例线程th = new Thread(this);//启动线程th.start();}/** * 游戏绘图 */public void myDraw() {try {canvas = sfh.lockCanvas();if (canvas != null) {canvas.drawColor(Color.BLACK);if (isCollsion) {paint.setColor(Color.RED);paint.setTextSize(20);canvas.drawText("Collision!", 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);}} catch (Exception e) {// TODO: handle exception} finally {if (canvas != null)sfh.unlockCanvasAndPost(canvas);}}/** * 触屏事件监听 */@Overridepublic boolean onTouchEvent(MotionEvent event) {//让矩形1随着触屏位置移动x1 = (int) event.getX() - w1 / 2;y1 = (int) event.getY() - h1 / 2;if (isCollsionWithRect(x1, y1, w1, h1, x2, y2, w2, h2)) {isCollsion = true;} else {isCollsion = false;}return true;}/** * 按键事件监听 */@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {return super.onKeyDown(keyCode, event);}/** * 游戏逻辑 */private void logic() {}public boolean isCollsionWithRect(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;}@Overridepublic void run() {while (flag) {long start = System.currentTimeMillis();myDraw();logic();long end = System.currentTimeMillis();try {if (end - start < 50) {Thread.sleep(50 - (end - start));}} catch (InterruptedException e) {e.printStackTrace();}}}/** * SurfaceView视图状态发生改变,响应此函数 */@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}/** * SurfaceView视图消亡时,响应此函数 */@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {flag = false;}}圆形碰撞 代码:
public class MySurfaceView extends SurfaceView implements Callback, Runnable {private SurfaceHolder sfh;private Paint paint;private Thread th;private boolean flag;private Canvas canvas;private int screenW, screenH;//定义两个圆形的半径与坐标private int r1 = 20, r2 = 20;private int x1 = 50, y1 = 100, x2 = 150, y2 = 100;//定义一个碰撞标识位private boolean isCollision;/** * SurfaceView初始化函数 */public MySurfaceView(Context context) {super(context);sfh = this.getHolder();sfh.addCallback(this);paint = new Paint();paint.setColor(Color.WHITE);paint.setAntiAlias(true);setFocusable(true);}/** * SurfaceView视图创建,响应此函数 */@Overridepublic void surfaceCreated(SurfaceHolder holder) {screenW = this.getWidth();screenH = this.getHeight();flag = true;//实例线程th = new Thread(this);//启动线程th.start();}/** * 游戏绘图 */public void myDraw() {try {canvas = sfh.lockCanvas();if (canvas != null) {canvas.drawColor(Color.BLACK);if (isCollision) {paint.setColor(Color.RED);paint.setTextSize(20);canvas.drawText("Collision!", 0, 30, paint);} else {paint.setColor(Color.WHITE);}canvas.drawCircle(x1, y1, r1, paint);canvas.drawCircle(x2, y2, r2, paint);}} catch (Exception e) {// TODO: handle exception} finally {if (canvas != null)sfh.unlockCanvasAndPost(canvas);}}/** * 触屏事件监听 */@Overridepublic boolean onTouchEvent(MotionEvent event) {x1 = (int) event.getX();y1 = (int) event.getY();if (isCollisionWithCircle(x1, y1, x2, y2, r1, r2)) {isCollision = true;} else {isCollision = false;}return true;}/** * 圆形碰撞 * @param x1圆形1的圆心X坐标 * @param y1圆形2的圆心X坐标 * @param x2圆形1的圆心Y坐标 * @param y2圆形2的圆心Y坐标 * @param r1圆形1的半径 * @param r2圆形2的半径 * @return */private boolean isCollisionWithCircle(int x1, int y1, int x2, int y2, int r1, int r2) {//Math.sqrt:开平方//Math.pow(double x, double y): X的Y次方if (Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) <= r1 + r2) {//如果两圆的圆心距小于或等于两圆半径则认为发生碰撞return true;}return false;}/** * 按键事件监听 */@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {return super.onKeyDown(keyCode, event);}/** * 游戏逻辑 */private void logic() {}@Overridepublic void run() {while (flag) {long start = System.currentTimeMillis();myDraw();logic();long end = System.currentTimeMillis();try {if (end - start < 50) {Thread.sleep(50 - (end - start));}} catch (InterruptedException e) {e.printStackTrace();}}}/** * SurfaceView视图状态发生改变,响应此函数 */@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}/** * SurfaceView视图消亡时,响应此函数 */@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {flag = false;}}多矩形碰撞 代码
public class MySurfaceView extends SurfaceView implements Callback, Runnable {private SurfaceHolder sfh;private Paint paint;private Thread th;private boolean flag;private Canvas canvas;private int screenW, screenH;//定义两个矩形图形的宽高坐标private int rectX1 = 10, rectY1 = 10, rectW1 = 40, rectH1 = 40;private int rectX2 = 100, rectY2 = 110, rectW2 = 40, rectH2 = 40;//便于观察是否发生了碰撞设置一个标识位private boolean isCollsion;//定义第一个矩形的矩形碰撞数组private Rect clipRect1 = new Rect(0, 0, 15, 15);private Rect clipRect2 = new Rect(rectW1 - 15, rectH1 - 15, rectW1, rectH1);private Rect[] arrayRect1 = new Rect[] { clipRect1, clipRect2 };//定义第二个矩形的矩形碰撞数组private Rect clipRect3 = new Rect(0, 0, 15, 15);private Rect clipRect4 = new Rect(rectW2 - 15, rectH2 - 15, rectW2, rectH2);private Rect[] arrayRect2 = new Rect[] { clipRect3, clipRect4 };/** * SurfaceView初始化函数 */public MySurfaceView(Context context) {super(context);sfh = this.getHolder();sfh.addCallback(this);paint = new Paint();paint.setColor(Color.WHITE);paint.setAntiAlias(true);setFocusable(true);}/** * SurfaceView视图创建,响应此函数 */@Overridepublic void surfaceCreated(SurfaceHolder holder) {screenW = this.getWidth();screenH = this.getHeight();flag = true;//实例线程th = new Thread(this);//启动线程th.start();}/** * 游戏绘图 */public void myDraw() {try {canvas = sfh.lockCanvas();if (canvas != null) {canvas.drawColor(Color.BLACK);paint.setColor(Color.WHITE);paint.setStyle(Style.FILL);if (isCollsion) {paint.setTextSize(20);canvas.drawText("Collision!", 0, 30, paint);}//绘制两个矩形canvas.drawRect(rectX1, rectY1, rectX1 + rectW1, rectY1 + rectH1, paint);canvas.drawRect(rectX2, rectY2, rectX2 + rectW2, rectY2 + rectH2, paint);//---绘制碰撞区域使用非填充,并设置画笔颜色白色paint.setStyle(Style.STROKE);paint.setColor(Color.RED);//绘制第一个矩形的所有矩形碰撞区域for (int i = 0; i < arrayRect1.length; i++) {canvas.drawRect(arrayRect1[i].left + this.rectX1, arrayRect1[i].top + this.rectY1, arrayRect1[i].right + this.rectX1, arrayRect1[i].bottom+ this.rectY1, paint);}//绘制第二个矩形的所有矩形碰撞区域for (int i = 0; i < arrayRect2.length; i++) {canvas.drawRect(arrayRect2[i].left + this.rectX2, arrayRect2[i].top + this.rectY2, arrayRect2[i].right + this.rectX2, arrayRect2[i].bottom+ rectY2, paint);}}} catch (Exception e) {// TODO: handle exception} finally {if (canvas != null)sfh.unlockCanvasAndPost(canvas);}}/** * 触屏事件监听 */@Overridepublic boolean onTouchEvent(MotionEvent event) {//让矩形1随着触屏位置移动rectX1 = (int) event.getX() - rectW1 / 2;rectY1 = (int) event.getY() - rectH1 / 2;if (isCollsionWithRect(arrayRect1, arrayRect2)) {isCollsion = true;} else {isCollsion = false;}return true;}/** * 按键事件监听 */@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {return super.onKeyDown(keyCode, event);}/** * 游戏逻辑 */private void logic() {}//Rect 类中的四个属性 top bottom left right//分别表示这个矩形的 上下左 右public boolean isCollsionWithRect(Rect[] rectArray, Rect[] rect2Array) {Rect rect = null;Rect rect2 = null;for (int i = 0; i < rectArray.length; i++) {//依次取出第一个矩形数组的每个矩形实例rect = rectArray[i];//获取到第一个矩形数组中每个矩形元素的属性值int x1 = rect.left + this.rectX1;int y1 = rect.top + this.rectY1;int w1 = rect.right - rect.left;int h1 = rect.bottom - rect.top;for (int j = 0; j < rect2Array.length; j++) {//依次取出第二个矩形数组的每个矩形实例rect2 = rect2Array[j];//获取到第二个矩形数组中每个矩形元素的属性值int x2 = rect2.left + this.rectX2;int y2 = rect2.top + this.rectY2;int w2 = rect2.right - rect2.left;int h2 = rect2.bottom - rect2.top;//进行循环遍历两个矩形碰撞数组所有元素之间的位置关系if (x1 >= x2 && x1 >= x2 + w2) {} else if (x1 <= x2 && x1 + w1 <= x2) {} else if (y1 >= y2 && y1 >= y2 + h2) {} else if (y1 <= y2 && y1 + h1 <= y2) {} else {//只要有一个碰撞矩形数组与另一碰撞矩形数组发生碰撞则认为碰撞return true;}}}return false;}@Overridepublic void run() {while (flag) {long start = System.currentTimeMillis();myDraw();logic();long end = System.currentTimeMillis();try {if (end - start < 50) {Thread.sleep(50 - (end - start));}} catch (InterruptedException e) {e.printStackTrace();}}}/** * SurfaceView视图状态发生改变,响应此函数 */@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}/** * SurfaceView视图消亡时,响应此函数 */@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {flag = false;}}以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。