Erase Box: the tutorial
Some days ago I blogged about Erase Box, a Box2D game made with my tutorials, now it’s time to publish Rodrigo‘s tutorial.
« On a game I was making, I needed a way to detect if a body was leaving the screen.
That can be done by checking the x and y positions of it, but I also wanted to explore Box2D features.
That was actually good, because I found another way to do that, and it can be of great help on other projects.
Sensors are bodies that won’t directly interact with others.
They won’t make a moving box stop when they hit, i.e.
That being said, they are still useful.
Box2D will keep track of it’s “contacts” just as if it were a normal body, so they can be used as exactly what their name means, a sensor.
Also, Box2D allows you to “attach” some information to a body, so that it can be distinguished from others.
Let’s see an example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | package { import flash.display.Sprite; import flash.events.Event; import flash.utils.Timer; import flash.events.TimerEvent; import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; import Box2D.Dynamics.Contacts.*; public class demo extends Sprite { public var the_world:b2World; var time_count:Timer=new Timer(1000); var i:int = 0; public function demo() { var environment:b2AABB = new b2AABB(); environment.lowerBound.Set(-5.0, -5.0); environment.upperBound.Set(30.0, 30.0); var gravity:b2Vec2=new b2Vec2(0.0,10.0); the_world=new b2World(environment,gravity,true); var debug_draw:b2DebugDraw = new b2DebugDraw(); var debug_sprite:Sprite = new Sprite(); addChild(debug_sprite); debug_draw.m_sprite=debug_sprite; debug_draw.m_drawScale=30; debug_draw.m_fillAlpha=0.5; debug_draw.m_lineThickness=1; debug_draw.m_drawFlags=b2DebugDraw.e_shapeBit; the_world.SetDebugDraw(debug_draw); var final_body:b2Body; var final_body2:b2Body; var the_body:b2BodyDef; var the_box:b2PolygonDef; the_body = new b2BodyDef(); the_body.position.Set(8.5, 13); the_box = new b2PolygonDef(); the_box.SetAsBox(8.5, 0.5); the_box.friction=0.3; the_box.density=0; the_box.isSensor = true; the_body.userData = "eraseSensor"; final_body=the_world.CreateBody(the_body); final_body.CreateShape(the_box); the_body.position.Set(8.5, 8); the_body.userData = "detSensor"; final_body2=the_world.CreateBody(the_body); final_body2.CreateShape(the_box); addEventListener(Event.ENTER_FRAME, on_enter_frame); time_count.addEventListener(TimerEvent.TIMER, on_time); time_count.start(); } public function on_time(e:Event) { var final_body:b2Body; var the_body:b2BodyDef; var the_box:b2PolygonDef; the_body = new b2BodyDef(); the_body.position.Set(Math.random()*10+2, 0); the_box = new b2PolygonDef(); the_box.SetAsBox(Math.random()+0.1,Math.random()+0.1); the_box.friction=0.3; the_box.density=1; the_body.userData = i; final_body=the_world.CreateBody(the_body); final_body.CreateShape(the_box); final_body.SetMassFromShapes(); i++; } public function on_enter_frame(e:Event) { the_world.Step(1/30, 10); // Setting up a sensor-contact listener if (the_world.m_contactList) { var contact:b2Contact = the_world.m_contactList; if ( contact.GetShape1().GetBody().GetUserData() == "detSensor" ) { trace(contact.GetShape2().GetBody().GetUserData()); } if ( contact.GetShape1().GetBody().GetUserData() == "eraseSensor" ) { var body2 = contact.GetShape2().GetBody(); the_world.DestroyBody(body2); } } //if ( contact.GetShape2().GetBody().GetUserData() == "eraseSensor" ) //{ //var body3 = contact.GetShape1().GetBody(); //the_world.DestroyBody(body3); //} } } } |
This is a modified version of Emanuele’s script: Box2D: tutorial for the absolute beginners
So I will only comment the changes:
Line 14: Creating a variable to keep track of the number of boxes created.
Line 40: Defining the_box as a sensor.
Lines 41 and 45: Setting up the userData for both sensors, so Box2D will be able to distinguish between them and other bodies.
Line 63: Setting the randomly generated box userData to the variable “i” (that keeps track of the number of boxes created).
Line 67: Increasing “i”
Lines 73 to 86: Setting up the contact listener:
73: Checking if m_contactList is not null.
75: Defining variable contact.
77 and 82: m_conctactList will also check for contact between boxes. This will make sure that it will only execute the lines below on the bodies that we want.
78: Tracing the box userdata (“i” at the time it was created)
83 and 84: Defining body2 as the second object in contact and then destroying it. It is also possible to add “&& contact.GetShape2().GetBody().GetUserData() == 5” to the if function, so it will only execute on the fifth body, i.e.
It is also possible to create non-0-density boxes as sensors, and attach them to bodies, but this is for another tutorial :) »
This is the result:
They can be easily customized to meet the unique requirements of your project.

























This post has 6 comments
ThomasTan
Cool! I never thought of that! I thought i would just check if the corner furthest away from the side would touch the side… Great one!
ThomasTan
seems like Emanuele NEVER CHECKS HIS MAIL…
X-Tender
Is it maybe possible to add an listener for the sensors instead checking it with the onenter frame and IF stuff? :)
ThomasTan
No way… He really does not check his mail…
fans
hi,could you show me a example about
man Walking animation?thank you
Understanding how Box2D manages boundaries : Emanuele Feronato
[...] in this case this means the object is outside the screen. Yuou can read more about this method at Erase Box: the tutorial post. Very cool solution, but not what I am going to [...]