Android中判断矩形和圆的碰撞

因为写弹球游戏,有涉及到矩形和圆的碰撞,网上搜了一下,有简单有复杂,参考写了一个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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值