Android中判断矩形和圆的碰撞

原创 2013年12月02日 00:15:09

因为写弹球游戏,有涉及到矩形和圆的碰撞,网上搜了一下,有简单有复杂,参考写了一个Demo放到这里。


矩形和圆的碰撞,分两种情况,一种是圆碰到矩形的四边(如上图中的圆心在1,2,3,4四块区域),还一种是圆刚好正中矩形的四个顶角(如上图中圆心在5,6,7,8四地位区域)。


直接上代码:

package com.android.ball;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class TestHit extends View implements Runnable {
	private int ball_x, ball_y, ball_r, left, top, right, bottom;
	private int offsetX = 5; // 圆移动的X步长
	private int offsetY = 5; // 圆移动的Y步长
	private Paint paint_Ball, paint_Rect;

	public TestHit(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		init();
	}

	public TestHit(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init();
	}

	public TestHit(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		init();
	}

	/**
	 * 初始化数据
	 */
	private void init() {
		ball_x = 100; // 圆心的X
		ball_y = 100; // 圆心的Y
		ball_r = 20; // 圆的半径(半径要大于移动的步长)
		left = 180;
		top = 320;
		right = 300;
		bottom = 480;
		paint_Ball = new Paint();
		paint_Ball.setAntiAlias(true);
		paint_Ball.setColor(0xfff444f4);

		paint_Rect = new Paint();
		paint_Rect.setColor(0xff220066);

		new Thread(this).start();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);

		// 画圆
		canvas.drawCircle(ball_x, ball_y, ball_r, paint_Ball);
		// 画矩形
		canvas.drawRect(left, top, right, bottom, paint_Rect);

	}

	@Override
	public void run() {
		// TODO Auto-generated method stub

		try {
			while (true) {
				Thread.sleep(10);
				ball_x += offsetX;
				ball_y += offsetY;

				// 判断圆和屏幕四周的碰撞
				hitAround();
				// 判断圆和矩形的碰撞
				hitRect();

				postInvalidate(); // 刷新
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 判断圆和屏幕四周的碰撞 假设屏幕是 480*800 注意:此测试程序应是全屏,不然800高屏幕底部会越界
	 */
	private void hitAround() {
		if (ball_x - ball_r <= 0 || ball_x + ball_r >= 480) { // 判断和左右两边的碰撞
			offsetX *= -1; // 反弹
//			Log.e(VIEW_LOG_TAG, "圆碰撞到屏幕左右边界");
		}
		if (ball_y - ball_r <= 0 || ball_y + ball_r >= 800) { // 判断和上下两边的碰撞
			offsetY *= -1; // 反弹
//			Log.e(VIEW_LOG_TAG, "圆碰撞到屏幕上下边界");
		}

	}

	/**
	 * 判断圆和矩形的碰撞
	 */
	private void hitRect() {
		// 球在1,3区域的碰撞判断
		if (ball_x >= left && ball_x <= right) {
			if (ball_y + ball_r >= top && ball_y < top) { // 1区域判断
				offsetY *= -1;
				Log.e(VIEW_LOG_TAG, "圆在1区域碰到矩形");
			} else if (ball_y - ball_r <= bottom && ball_y > bottom) { // 3区域判断
				offsetY *= -1;
				Log.e(VIEW_LOG_TAG, "圆在3区域碰到矩形");
			}
		}

		// 球在2,4区域的碰撞判断
		if (ball_y >= top && ball_y <= bottom) {
			if (ball_x - ball_r <= right && ball_x > right) { // 2区域判断
				offsetX *= -1;
				Log.e(VIEW_LOG_TAG, "圆在2区域碰到矩形");
			} else if (ball_x + ball_r >= left && ball_x < left) { // 4区域判断
				offsetX *= -1;
				Log.e(VIEW_LOG_TAG, "圆在4区域碰到矩形");
			}
		}

		// 圆在5区域的碰撞判断
		if (Math.pow(left - ball_x, 2) + Math.pow(top - ball_y, 2) <= Math.pow(
				ball_r, 2) && ball_x < left && ball_y < top) {
			offsetX *= -1;
			offsetY *= -1;
			Log.e(VIEW_LOG_TAG, "圆在5区域碰到矩形");
		}

		// 圆在6区域的碰撞判断
		if (Math.pow(ball_x - right, 2) + Math.pow(top - ball_y, 2) <= Math
				.pow(ball_r, 2) && ball_x > right && ball_y < top) {
			offsetX *= -1;
			offsetY *= -1;
			Log.e(VIEW_LOG_TAG, "圆在6区域碰到矩形");
		}

		// 圆在7区域的碰撞判断
		if (Math.pow(ball_x - right, 2) + Math.pow(ball_y - bottom, 2) <= Math
				.pow(ball_r, 2) && ball_x > right && ball_y > bottom) {
			offsetX *= -1;
			offsetY *= -1;
			Log.e(VIEW_LOG_TAG, "圆在7区域碰到矩形");
		}

		// 圆在8区域的碰撞判断
		if (Math.pow(left - ball_x, 2) + Math.pow(ball_y - bottom, 2) <= Math
				.pow(ball_r, 2) && ball_x < left && ball_y > bottom) {
			offsetX *= -1;
			offsetY *= -1;
			Log.e(VIEW_LOG_TAG, "圆在8区域碰到矩形");
		}
	}

}

当然,上面只是一个View文件,要运行看效果的话,用个MainActivity创建这个View对象就可以了,代码:

package com.android.ball;

import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity {

	private TestHit testHit;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		testHit = new TestHit(this);
		setContentView(testHit);
	}


}

嫌网页看着不爽的,可以下载Demo源码,地址在:http://download.csdn.net/detail/bellovin/6641309


Android碰撞检测——Region碰撞检查

Region碰撞检测    Region类在android开发中经常用到,特别是该类的一个判断点是否在矩形区域内的函数——Region.contains(int x,int y)经常用到。  ...
  • dyllove98
  • dyllove98
  • 2013年04月22日 20:54
  • 2840

碰撞检测算法:点和矩形碰撞、点和圆形碰撞、矩形碰撞、圆形碰撞

http://blog.csdn.net/shineflowers/article/details/41084329 点和矩形碰撞 /** * * @param x1...
  • taotaoah
  • taotaoah
  • 2016年05月06日 21:06
  • 437

圆与旋转矩形的碰撞检测(下篇)

本文翻译自《Circle and Rotated Rectangle Collision Detection》,敬请勘误。 圆与旋转矩形的碰撞检测 本文我将解释如何实现圆和旋转...
  • aa294194253
  • aa294194253
  • 2014年09月11日 16:55
  • 1224

碰撞检测算法:点和矩形碰撞、点和圆形碰撞、矩形碰撞、圆形碰撞

点和矩形碰撞 [java] view plain copy  print? /**       *        * @param x1 点  ...
  • wang15061955806
  • wang15061955806
  • 2016年07月06日 15:51
  • 808

面试题:判断一个圆和一个矩形是否相交

题目:用最简单,最快速的方法计算出下面这个圆形是否和正方形相交。 3D 坐标系原点(0.0,0.0,0.0) 圆形: 半径r = 3.0 圆心o = (*.*, 0.0, *.*) 正方形:...
  • tujinqiuqq85948239
  • tujinqiuqq85948239
  • 2014年06月30日 20:21
  • 2262

【COCOS2DX-游戏开发之三七】圆与旋转矩形的碰撞检测(下篇)

Circle and Rotated Rectangle Collision Detection
  • teng_ontheway
  • teng_ontheway
  • 2014年08月20日 16:10
  • 4071

碰撞检测算法:点和矩形碰撞、点和圆形碰撞、矩形碰撞、圆形碰撞

点和矩形碰撞 [java] view plaincopyprint? /**       *        * @param x1 点    ...
  • shineflowers
  • shineflowers
  • 2014年11月13日 18:44
  • 16809

计算机与数学 —— 检测圆与矩形相交的快速判定算法

这篇博客介绍了如何快速检测圆与矩形是否相交的算法。
  • noahzuo
  • noahzuo
  • 2016年07月26日 17:07
  • 1262

碰撞检测算法(2D矩形)

本文给出了一个简单实用的2D平面上矩形的碰撞检测算法,给出了JavaScript的具体实现代码(两行),并用HTML进行可视化。...
  • gg_18826075157
  • gg_18826075157
  • 2017年06月04日 13:43
  • 689

用qt的图形视图框架实现的圆,三角形,矩形运动及碰撞.

用qt的图形视图框架实现的圆,三角形,矩形运动及碰撞. 效果如图: /*main.cpp*/ #include "project.h" #include int main(int argc...
  • qq_18426941
  • qq_18426941
  • 2015年07月30日 18:43
  • 1152
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android中判断矩形和圆的碰撞
举报原因:
原因补充:

(最多只允许输入30个字)