Introducing Box2D filtering
2009-10-18 00:00:00 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁惧墽鎳撻—鍐偓锝庝簻椤掋垺銇勯幇顖毿撻柟渚垮妼椤粓宕卞Δ鈧獮濠勭磽閸屾艾鈧懓顫濋妸鈺佺疅缂佸顑欓崥瀣煕椤愵偅绶氱紓鍐╂礋濮婂宕掑▎鎴М濠电姭鍋撻梺顒€绉甸幆鐐哄箹濞n剙濡肩紒鎰殜閺屸€愁吋鎼粹€茬敖婵炴垶鎸哥粔鐢稿Φ閸曨垰鍐€妞ゆ劦婢€濞岊亪姊虹紒妯诲蔼闁稿海鏁诲濠氭晲婢跺﹤宓嗛梺缁樺姈缁佹挳宕戦幘璇叉嵍妞ゆ挻绋戞禍鐐叏濡厧浜鹃悗姘炬嫹

In Box2D, normally every object collides with other objects in the stage.
But sometimes we may need a way to make an object collide with only certain objects, ignoring the rest. I am not talking about sensors, but real objects that won’t collide with certain other objects.
This feature can be done with filtering.
Collision filtering is a system for preventing collision between shapes. For example, say you make a character that rides a bicycle. You want the bicycle to collide with the terrain and the character to collide with the terrain, but you don’t want the character to collide with the bicycle (because they must overlap). Box2D supports such collision filtering using categories and groups.
Box2D supports 16 collision categories. For each shape you can specify which category it belongs to. You also specify what other categories this shape can collide with. For example, you could specify in a multiplayer game that all players don’t collide with each other and monsters don’t collide with each other, but players and monsters should collide. This is done with masking bits.
The following script is the same we saw a Understanding how Box2D manages boundaries but I am using a random filtering to make the ball ignore the ramp, the wall, or none of them.
package {
import flash.display.Sprite;
import flash.events.Event;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
public class bound extends Sprite {
var body:b2Body;
public var m_world:b2World;
public var m_iterations:int=10;
public var m_timeStep:Number=1.0/30.0;
var m_boundaryListener=new b2BoundaryListener();
var bodyDef:b2BodyDef;
var boxDef:b2PolygonDef;
var circleDef:b2CircleDef;
public function bound() {
addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-100.0, -100.0);
worldAABB.upperBound.Set(100.0, 100.0);
var gravity:b2Vec2=new b2Vec2(0.0,10.0);
var doSleep:Boolean=true;
m_world=new b2World(worldAABB,gravity,doSleep);
m_world.SetBoundaryListener(m_boundaryListener);
// debug draw start
var m_sprite:Sprite;
m_sprite = new Sprite();
addChild(m_sprite);
var dbgDraw:b2DebugDraw = new b2DebugDraw();
var dbgSprite:Sprite = new Sprite();
m_sprite.addChild(dbgSprite);
dbgDraw.m_sprite=m_sprite;
dbgDraw.m_drawScale=30;
dbgDraw.m_alpha=1;
dbgDraw.m_fillAlpha=0.5;
dbgDraw.m_lineThickness=1;
dbgDraw.m_drawFlags=b2DebugDraw.e_shapeBit;
m_world.SetDebugDraw(dbgDraw);
// ground
bodyDef = new b2BodyDef();
bodyDef.position.Set(4, 12);
boxDef = new b2PolygonDef();
boxDef.filter.categoryBits=2;
boxDef.SetAsOrientedBox(10, 1,new b2Vec2(5, 1.5), Math.PI/32);
boxDef.friction=0.3;
boxDef.density=0;
body=m_world.CreateBody(bodyDef);
body.CreateShape(boxDef);
body.SetMassFromShapes();
// another object
bodyDef = new b2BodyDef();
bodyDef.position.Set(8, 12);
boxDef = new b2PolygonDef();
boxDef.filter.categoryBits=4;
boxDef.SetAsBox(1, 3);
boxDef.friction=0.3;
boxDef.density=0;
body=m_world.CreateBody(bodyDef);
body.CreateShape(boxDef);
body.SetMassFromShapes();
// circle
create_circle();
}
public function create_circle() {
bodyDef = new b2BodyDef();
bodyDef.position.x=6;
bodyDef.position.y=2;
circleDef = new b2CircleDef();
circleDef.filter.maskBits=Math.ceil(Math.random()*3)*2;
circleDef.radius=2;
circleDef.density=1.0;
circleDef.friction=0.5;
circleDef.restitution=0.2;
body=m_world.CreateBody(bodyDef);
body.CreateShape(circleDef);
body.SetMassFromShapes();
}
public function Update(e:Event):void {
m_world.Step(m_timeStep, m_iterations);
if (m_boundaryListener.get_contact()) {
m_boundaryListener.no_contact();
m_world.DestroyBody(body);
bodyDef = new b2BodyDef();
create_circle();
}
}
}
}
Tags:Introducing BoxD filtering
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接