手游《奔跑吧?骚年!》技术分享(四):矩形碰撞检测

手游《奔跑吧?骚年!》技术分享(四):矩形碰撞检测

今天来分享一下游戏中的碰撞处理,基本上横版2D游戏内的物体,都可以用矩形来表示(有时也需要用三角形来检测)。通常就判断一下是否碰撞是不够的,还需要检测一下碰撞在那一面。就比如在我的游戏中,人物碰到石块的顶上和碰到左侧需要的处理就不一样。碰到顶上,需要将人物的垂直速度变为0。后者就需要将人物的水平速度变为0。

所以需要一个表示碰撞位置的参数:

package com.baohanbin.run_boy_run.game_util;

/**
 * 碰撞检查时所用的数据信使。 包括是否碰撞,和撞击类型(上,下,左,右,。。。)
 * 
 * @author 包汉彬同学
 * 
 */
public class CollisionData {
	public static final int COLLISION_TOP = 1;
	public static final int COLLISION_LEFT = 2;
	public static final int COLLISION_RIGHT = 3;
	public static final int COLLISION_BOTTOM = 4;
	public static final int COLLISION_TOP_LEFT = 5;
	public static final int COLLISION_TOP_RIGHT = 6;
	public static final int COLLISION_BOTTOM_LEFT = 7;
	public static final int COLLISION_BOTTOM_RIGHT = 8;
	public static final int COLLISION_CENTRE = 9;

	public static enum CollisionType {
		COLLISION_TOP_FALSE(COLLISION_TOP, false), COLLISION_LEFT_FALSE(
				COLLISION_LEFT, false), COLLISION_RIGHT_FALSE(COLLISION_RIGHT,
				false), COLLISION_BOTTOM_FALSE(COLLISION_BOTTOM, false), COLLISION_TOP_LEFT_FALSE(
				COLLISION_TOP_LEFT, false), COLLISION_TOP_RIGHT_FALSE(
				COLLISION_TOP_RIGHT, false), COLLISION_BOTTOM_LEFT_FALSE(
				COLLISION_BOTTOM_LEFT, false), COLLISION_BOTTOM_RIGHT_FALSE(
				COLLISION_BOTTOM_RIGHT, false), COLLISION_CENTRE_FALSE(
				COLLISION_CENTRE, false), COLLISION_TOP_TRUE(COLLISION_TOP,
				true), COLLISION_LEFT_TRUE(COLLISION_LEFT, true), COLLISION_RIGHT_TRUE(
				COLLISION_RIGHT, true), COLLISION_BOTTOM_TRUE(COLLISION_BOTTOM,
				true), COLLISION_TOP_LEFT_TRUE(COLLISION_TOP_LEFT, true), COLLISION_TOP_RIGHT_TRUE(
				COLLISION_TOP_RIGHT, true), COLLISION_BOTTOM_LEFT_TRUE(
				COLLISION_BOTTOM_LEFT, true), COLLISION_BOTTOM_RIGHT_TRUE(
				COLLISION_BOTTOM_RIGHT, true), COLLISION_CENTRE_TRUE(
				COLLISION_CENTRE, true);
//		碰撞类型
		public int collType = 0;
//		是否碰撞
		public boolean collFlag = false;

		CollisionType(int collType, boolean flag) {
			this.collType = collType;
			this.collFlag = flag;
		}
	}

}

接下来还需要表示游戏内物体的类:

package com.baohanbin.run_boy_run.game_run;


import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;

/**
 * 该类是整个游戏最前景的父类 所有的存在于游戏的前景元素必须直接或间接继承于它
 * 
 */
public class Front {
	// x :在坐标中横轴的位置 y : 在坐标中纵轴的位置
	public float x, y;
	// 每一个元素的唯一类型标签
	public int type;
	// 物体的尺寸
	public int width, height;
	private Paint paint = new Paint();
	/**
	 * 
	 * @param x2
	 *            在坐标中横轴的位置
	 * @param y2
	 *            在坐标中纵轴的位置
	 * @param w
	 *            物体的宽度
	 * @param h
	 *            物体的高度
	 */
	public Front(float x2, float y2, int w, int h, int t) {
		this.x = x2;
		this.y = y2;
		this.width = w;
		this.height = h;
		this.type = t;
	}

	/**
	 * 绘制物体所有元素必须
	 * 
	 * @param c
	 *            画布
	 * @param x
	 *            在屏幕横轴的位置
	 * @param y
	 *            在屏幕纵轴的位置
	 * @param bitmap
	 *            物体的图片数组
	 */
	public void draw(Canvas c, float screenX, float screenY, Bitmap... bitmap) {
		try{
			c.drawBitmap(bitmap[0], screenX, screenY, paint);

		}catch(Exception e){
			Log.d("GameLog", "draw is  Failure");
			e.printStackTrace();
		}
		
	}

	public String toStirng() {
		return "Front Data --- x:" + x + " y:" + y + " width:" + width
				+ " height:" + height + " type:" + type;
	}

}

现在主角登场:

/**
 * Description :计算各种类型的撞击
 * 
 * @author 包汉彬同学
 * @version 1.0
 */
public class Collision {
	/**
	 * 储存三角形,三边坐标的数组,用于碰撞计算,非同步
	 */
	public static float[][] TriangLineArray = new float[3][4];
	/**
	 * 储存矩形,四边的坐标,用于碰撞计算,非同步
	 */
	public static float[][] RectLineArray = new float[4][4];

	/**
	 * Description : 计算矩形的物体是否相撞 计算出两个矩形的中心坐标 然后比较坐标的距离,是否分别小于两矩形宽和高的一半之和
	 * 然后推断出撞击的类型
	 * 
	 * @param passivity
	 *            被撞击物体
	 * @param initiative
	 *            撞击物体
	 * @return 返回撞击数据信使
	 */
	public static CollisionType Rectangle(Front passivity, Front initiative) {
		CollisionType cd = CollisionType.COLLISION_TOP_FALSE;
		// 为了避免不必要的计算
		if ((passivity.x + passivity.width) > initiative.x
				&& passivity.x <= (initiative.x + 800)) {
			float x1 = passivity.x + passivity.width / 2;
			float y1 = passivity.y - passivity.height / 2;
			float x2 = initiative.x + initiative.width / 2;
			float y2 = initiative.y - initiative.height / 2;
			// 判断是否相撞击
			boolean b = (Math.abs(x2 - x1) <= (passivity.width / 2 + initiative.width / 2) && Math
					.abs(y2 - y1) <= (passivity.height / 2 + initiative.height / 2));
			if (b) {
				if ((x2 <= passivity.x) && (y2 >= passivity.y)) {
					cd = CollisionType.COLLISION_TOP_LEFT_TRUE;
				} else if ((x2 <= passivity.x)
						&& (y2 <= passivity.y - passivity.height)) {
					cd = CollisionType.COLLISION_BOTTOM_LEFT_TRUE;
				} else if ((x2 >= passivity.x + passivity.width)
						&& (y2 >= passivity.y)) {
					cd = CollisionType.COLLISION_TOP_RIGHT_TRUE;
				} else if ((x2 >= passivity.x + passivity.width)
						&& (y2 <= passivity.y - passivity.height)) {
					cd = CollisionType.COLLISION_BOTTOM_RIGHT_TRUE;
				} else if (y2 > passivity.y) {
					cd = CollisionType.COLLISION_TOP_TRUE;
				} else if (y2 < passivity.y - passivity.height) {
					cd = CollisionType.COLLISION_BOTTOM_TRUE;
				} else if (x2 < passivity.x) {
					cd = CollisionType.COLLISION_LEFT_TRUE;
				} else if (x2 > passivity.x + passivity.width) {
					cd = CollisionType.COLLISION_RIGHT_TRUE;
				} else {
					cd = CollisionType.COLLISION_CENTRE_TRUE;
				}
			}
		}
		return cd;
	}
}


该类还包括其实该类还包括三角型碰撞,但是它比较复杂,就把它放到下一次的博客中。。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值