您的位置:首页 > 移动开发 > Android开发

Android游戏开发---碰撞检测

2013-03-29 20:42 627 查看
虽然碰撞检测不一定要自己去写,一些游戏引擎直接就提供了相关的方法。但是掌握了碰撞检测的基本方法,还是想当有用的。

2D游戏中碰撞一般是矩形的碰撞,但是一般会有一些误差,因为边缘可能是透明的。

以下介绍3种碰撞检测的方法
1. 圆的碰撞检测
碰撞条件:两个圆心的距离 < 两圆半径和 则碰撞

2. 矩形的碰撞检测方法1
碰撞条件:
x抽距离差 < 两矩形宽度之和 / 2
y抽距离差 < 两矩形高度之和 / 2

3. 矩形的碰撞检测方法2

碰撞条件:

s表示起点,e表示终点。需要知道矩形的两点。



一般在实际中第二种与第三种任选一种即可

第一种 “ 圆的碰撞检测 ” 代码
public class CircleCrash extends SurfaceView implements SurfaceHolder.Callback,
		Runnable
{
	private SurfaceHolder holder;
	private Canvas canvas;
	private boolean isRunning = true;
	private Paint paint;
	private float cx, cy;//动圆的圆心坐标

	public CircleCrash(Context context)
	{
		super(context);
		this.setFocusable(true);
		holder = this.getHolder();//这个this指的是这个Surface
		holder.addCallback(this); //这个this表示实现了Callback接口
		paint = new Paint();
	}

	@Override
	public void run()
	{
		while (isRunning)
		{
			drawView();
			try
			{
				Thread.sleep(100);
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}

	private void drawView()
	{
		try
		{
			if (holder != null)
			{
				//draw
				canvas = holder.lockCanvas();
				canvas.drawColor(Color.BLACK);
				paint.setColor(Color.BLUE);
				canvas.setDrawFilter(new PaintFlagsDrawFilter(0,
						Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
				// 圆的碰撞 (一个动的圆去碰撞一个禁止的圆, 碰撞后动圆禁止)
				canvas.drawCircle(150, 150, 33, paint); //禁止的圆

				//碰撞检测 . (没有碰撞时cx,cy自增, 即圆移动)
				if (Math.sqrt((150 - cx) * (150 - cx) + (150 - cy) * (150 - cy)) > (33 + 22))
				{
					cx+=3;
					cy+=3;
					System.out.println(cx + "  " + cy);
				}
				canvas.drawCircle(cx, cy, 22, paint);	//动的圆(都在对角线上运动)
			}

		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			if (canvas != null)
				holder.unlockCanvasAndPost(canvas);
		}

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder)
	{
		new Thread(this).start();
		isRunning = true;
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height)
	{

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder)
	{
		isRunning = false;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		if (keyCode == KeyEvent.KEYCODE_BACK)
			isRunning = false;
		return super.onKeyDown(keyCode, event);
	}

}
效果:



第二种 “ 矩形的碰撞检测1 ” 代码:(核心部分)

private void drawView()
	{
		try
		{
			if (holder != null)
			{
				//draw
				canvas = holder.lockCanvas();
				canvas.drawColor(Color.BLACK);
				paint.setColor(Color.BLUE);
				canvas.setDrawFilter(new PaintFlagsDrawFilter(0,
						Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
				//矩形的碰撞 (碰撞后动的矩形禁止)
				canvas.drawRect(150, 151, 220, 221, paint);
				//当没有碰撞时才自增移动
				if (!((150 - cx) < (70 + 60) / 2 && (151 - cy) < (70 + 60) / 2))
				{
					cx += 4;
					cy += 4;
				}
				canvas.drawRect(cx, cy, cx + 60, cy + 60, paint);//动的矩形(都在对角线上运动)

			}

		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			if (canvas != null)
				holder.unlockCanvasAndPost(canvas);
		}

	}
效果:



第三种 “ 矩形的碰撞检测 2” 代码

private void drawView()
	{
		try
		{
			if (holder != null)
			{
				//draw
				canvas = holder.lockCanvas();
				canvas.drawColor(Color.BLACK);
				paint.setColor(Color.BLUE);
				canvas.setDrawFilter(new PaintFlagsDrawFilter(0,
						Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
				//矩形的碰撞 (碰撞后动的矩形禁止)
				//s(150,151),  e(220,221)
				canvas.drawRect(150, 151, 220, 221, paint);
				//当没有碰撞时才自增移动(取反)
				if (220 <= cx || 221 <= cy || 150 >= (cx + 60)
						|| 151 >= (cy + 60))
				{
					cx += 5;
					cy += 5;
				}
				canvas.drawRect(cx, cy, cx + 60, cy + 60, paint);//动的矩形(都在对角线上运动)

			}

		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			if (canvas != null)
				holder.unlockCanvasAndPost(canvas);
		}

	}


原创文章,转载请注明出处:http://blog.csdn.net/xn4545945
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: