您的位置:首页 > 其它

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

2014-08-12 00:19 429 查看
手游《奔跑吧?骚年!》技术分享(四):矩形碰撞检测
今天来分享一下游戏中的碰撞处理,基本上横版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;
}
}


该类还包括其实该类还包括三角型碰撞,但是它比较复杂,就把它放到下一次的博客中。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: