手游《奔跑吧?骚年!》技术分享(四):矩形碰撞检测
2014-08-12 00:19
429 查看
手游《奔跑吧?骚年!》技术分享(四):矩形碰撞检测
今天来分享一下游戏中的碰撞处理,基本上横版2D游戏内的物体,都可以用矩形来表示(有时也需要用三角形来检测)。通常就判断一下是否碰撞是不够的,还需要检测一下碰撞在那一面。就比如在我的游戏中,人物碰到石块的顶上和碰到左侧需要的处理就不一样。碰到顶上,需要将人物的垂直速度变为0。后者就需要将人物的水平速度变为0。
所以需要一个表示碰撞位置的参数:
接下来还需要表示游戏内物体的类:
现在主角登场:
该类还包括其实该类还包括三角型碰撞,但是它比较复杂,就把它放到下一次的博客中。。
今天来分享一下游戏中的碰撞处理,基本上横版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; }
}
该类还包括其实该类还包括三角型碰撞,但是它比较复杂,就把它放到下一次的博客中。。
相关文章推荐
- 手游《奔跑吧?骚年!》技术分享(五):三角形碰撞检测
- 手游《奔跑吧?骚年!》技术分享(二):图片适配
- 手游《奔跑吧?骚年!》技术分享(一):开篇
- 手游《奔跑吧?骚年!》技术分享(三):文件处理
- Physics - 高级碰撞检测技术
- 分享一个超高效的不规则物体碰撞检测的类~~
- 矩形碰撞检测
- 圆与矩形简单碰撞检测
- 矩形检测碰撞算法
- 碰撞检测技术简介
- 高级碰撞检测技术
- Flash游戏学习笔记:矩形检测碰撞
- 碰撞检测技术
- 技术转载:游戏里实现碰撞检测方法
- 技术转载:游戏里实现碰撞检测方法
- 高级碰撞检测技术
- 高级碰撞检测技术
- Flash游戏学习笔记:矩形检测碰撞
- 高级碰撞检测技术
- 2D游戏碰撞检测--矩形与圆形