Category Archives: Box2D

QuickBox2D Contacts Part 2

Actionscript:
  1. import com.actionsnippet.qbox.*;
  2.  
  3. [SWF(width = 800, height = 600, backgroundColor = 0x000000, frameRate=60)]
  4.  
  5. var sim:QuickBox2D = new QuickBox2D(this);
  6.  
  7. sim.createStageWalls();
  8.  
  9. var boxA:QuickObject = sim.addBox({x:3, y:3, width:2, height:2});
  10. var boxB:QuickObject = sim.addBox({x:3, y:6, width:2, height:2});
  11.  
  12. // add a few extra circles to show that there are other contacts
  13. // occuring
  14. for (var i:int = 0; i<10; i++){
  15.     sim.addCircle({x:5 + i, y:4, radius:0.1 + Math.random()});
  16. }
  17.  
  18. sim.start();
  19. sim.mouseDrag();
  20.  
  21. // when boxA touches boxB change their alpha values to 50%
  22. var contacts:QuickContacts = sim.addContactListener();
  23. contacts.addEventListener(QuickContacts.ADD, onAdd);
  24. contacts.addEventListener(QuickContacts.PERSIST, onPersist);
  25. contacts.addEventListener(QuickContacts.REMOVE, onRemove);
  26. function onAdd(evt:Event):void{
  27.     if(contacts.isCurrentContact(boxA, boxB)){
  28.         boxA.userData.alpha = 0.5;
  29.         boxB.userData.alpha = 0.5;
  30.     }
  31. }
  32. function onPersist(evt:Event):void{
  33.     if(contacts.isCurrentContact(boxA, boxB)){
  34.         boxA.userData.alpha = 0.5;
  35.         boxB.userData.alpha = 0.5;
  36.     }
  37. }
  38. function onRemove(evt:Event):void{
  39.     if(contacts.isCurrentContact(boxA, boxB)){
  40.         boxA.userData.alpha = 1;
  41.         boxB.userData.alpha = 1;
  42.     }
  43. }

Note: This snippet requires QuickBox2D 1.0 or greater

This is another example showing how to make use of QuickBox2D contacts. In this example three contact events are used ADD, PERSIST and REMOVE. When the two boxes are touching their alpha values are set to 50% - otherwise their alpha values are at 100%.


Have a look at the swf...

A Little Detail About the Events

The ADD event is dispatched when a new b2ContactPoint is generated. The PERSIST event is dispatched as long as the b2ContactPoint exists for more than one timeStep - and from what I can tell, is dispatched until the rigid bodies it is associated with go to sleep. The REMOVE event is called when the b2ContactPoint is removed, meaning the rigid bodies that caused the creating of the b2ContactPoint are no longer touching.

You need to be careful with the code that you place inside the listener functions for these events. The reason being that these events are called many many times for every contact point in the simulation.

Also posted in QuickBox2D | Tagged , , , , | 2 Comments

QuickBox2D Contacts Part 1

Actionscript:
  1. import com.actionsnippet.qbox.*;
  2. import Box2D.Common.Math.*;
  3.  
  4. [SWF(width = 800, height = 600, backgroundColor = 0x000000, frameRate=60)]
  5.  
  6. var sim:QuickBox2D = new QuickBox2D(this, {debug:false, frim:true});
  7.  
  8. sim.createStageWalls();
  9.  
  10. var boxA:QuickObject = sim.addBox({x:3, y:3, width:2, height:2, fillColor:0xFF0000});
  11. var boxB:QuickObject = sim.addBox({x:3, y:6, width:2, height:2, fillColor:0xFF0000});
  12.  
  13. sim.start();
  14. sim.mouseDrag();
  15.  
  16. // when boxA touches boxB a circle QuickObject is created
  17. var contacts:QuickContacts = sim.addContactListener();
  18. // listen for contact points being added
  19. contacts.addEventListener(QuickContacts.ADD, onAdd);
  20. function onAdd(evt:Event):void{
  21.     // see if this contact event is associated with boxA and boxB
  22.     if(contacts.isCurrentContact(boxA, boxB)){
  23.         // get the location of the collision in world space
  24.         var loc:b2Vec2 = contacts.currentPoint.position;
  25.         // you cannot create new QuickObjects inside this listener function
  26.         // so we just give a 5 ms delay
  27.         setTimeout(sim.addCircle, 5, {x:loc.x, y:loc.y});
  28.     }
  29. }

Note: This snippet requires QuickBox2D 1.0 or greater

I've created a few simple examples to show how to use QuickBox2D contact listeners. This is the first one. When two boxes collide circles are added to the simulation at the point of collision.


Have a look at the swf...

Also posted in QuickBox2D | Tagged , , , , | 10 Comments

QuickBox2D 1.0

QuickBox2D 1.0 is ready. It contains a bunch of small bug fixes and a few new features that I'll be demoing in the next few posts. The main new features relate to collision detection and simple event sequencing.

Go download it from here...

I also spent some time updating the docs.... everything is documented... I may add additional documentation text over the next few days...

A detailed tutorial for QuickBox2D is also in the works...

[EDIT]

Also, if you find any bugs send me an e-mail (see about page for e-mail)... if there are any bugs left I'd like to fix the asap.... You can also feel free to e-mail any API suggestions...

Also posted in QuickBox2D | Tagged , , , , | 2 Comments

QuickBox2D addTimeStepSequence() Preview

Actionscript:
  1. import com.actionsnippet.qbox.*;
  2.  
  3. [SWF(width = 800, height = 600, backgroundColor = 0xFFFFFF, frameRate=60)]
  4.  
  5. // hide everything for 300 ms
  6. visible = false;
  7. setTimeout(function():void{ visible = true}, 300);
  8.  
  9. var canvas:MovieClip = MovieClip(addChild(new MovieClip()));
  10.  
  11. var sim:QuickBox2D = new QuickBox2D(canvas, {debug:true});
  12.  
  13. sim.setDefault({fillColor:0x666666, lineAlpha:0})
  14. sim.createStageWalls();
  15.  
  16. var boxA:QuickObject = makeLever(6 , 17.5, 9, "right", 0.7);
  17. var circleA:QuickObject = sim.addCircle({x:2, y:3, radius:0.5, mass:4});
  18. sim.addBox({x:15, y:12, width:2, height:0.5, density:0})
  19. var circleB:QuickObject = sim.addCircle({x:16, y:11, radius:0.5, mass:4, friction:0.2, fillColor:0});
  20. sim.addBox({x:20.5, y:12, width:2, height:0.3, angle:-0.6, restitution:4.6, density:0})
  21. var boxB:QuickObject = makeLever(20 , 17.5, 8, "right", 1);
  22. sim.addBox({x:9, y:9, width:2, height:0.5, density:0});
  23. var circleC:QuickObject = sim.addCircle({x:9, y:9, radius:0.5, mass:4, friction:0.2, fillColor:0});
  24. sim.addBox({x:7, y:12, width:2, height:0.5, angle:-0.3, density:0, restitution:2});
  25. sim.addBox({x:3, y:7, width:2, height:0.5, angle:Math.PI/2 - 0.22, density:0, restitution:3});
  26. sim.addBox({x:13, y:15, width:2, height:0.5, density:0, angle:0.3, restitution:1});
  27. sim.addBox({x:25.5, y:7, width:2, height:0.3, angle:-0.2, restitution:0.5, density:0})
  28. sim.addBox({x:26, y:10, width:1, height:1, density:0,restitution:0.3});
  29. sim.addBox({x:25, y:19, width:2, height:0.5, density:0, restitution:3.5, angle:-0.99});
  30. sim.addBox({x:1, y:17, width:0.3, height:2, density:0, angle:-0.15, restitution:0.999});
  31. sim.addBox({x:0.7, y:11, width:0.3, height:2, density:0, angle:-0.19, restitution:20})
  32. sim.addBox({x:0.4, y:11.5, width:1, height:0.3, density:0})
  33.  
  34. function makeLever(xp:Number, yp:Number, boxWidth:Number, dir:String, off:Number=0, hasBox:Boolean=true):QuickObject{
  35.     var angle:Number, xpos:Number, weight:QuickObject
  36.     if (dir == "right"){
  37.         angle = 0.43;
  38.         xpos = xp + boxWidth / 2 - off;
  39.     }else{
  40.         angle = -0.43;
  41.         xpos = xp - boxWidth / 2 + off;
  42.     }
  43.     if (hasBox){
  44.       weight = sim.addBox({x:xpos , y:yp, width:0.5, height:0.5, angle:angle, fillColor:0});
  45.     }
  46.     var plank:QuickObject = sim.addBox({x:xp, y:yp, width:boxWidth, height:0.5, angle:angle});
  47.     var fulcrum:QuickObject = sim.addPoly({x:xp, y:yp, verts:[[0,0, 1,2, -1,2]], density:0})
  48.     sim.addJoint({type:"revolute", a:plank.body, b:fulcrum.body, collideConnected:false});
  49.     return weight;
  50. }
  51.  
  52. sim.start();
  53.  
  54. // new feature, calls a function after a specific number of box2D timeSteps
  55. sim.addTimeStepSequence({time:70, callback:cam, args:[boxA]},
  56.                         {time:150, callback:cam, args:[circleB]},
  57.                         {time:200, callback:cam, args:[boxB, 1.3]},
  58.                         {time:580, callback:cam, args:[circleC]},
  59.                         {time:700, callback:cam, args:[circleC, 1.1]},
  60.                         {time:810, callback:cam, args:[boxB, 1.4]},
  61.                         {time:870, callback:cam, args:[boxB, 3]},
  62.                         {time:890, callback:cam, args:[boxB, 1.1]},
  63.                         {time:1200,callback:cam, args:[boxB, 1]});
  64.  
  65. // set values for matrix pan and zoom
  66. function cam(quickObj:QuickObject, scale:Number=-1):void{
  67.     currQuick = quickObj;
  68.     if (scale != -1){
  69.         scaleDest = scale;
  70.     }
  71. }                                
  72.                
  73. // matrix pan and zoom
  74. var scale:Number = 1;
  75. var scaleDest:Number = 1.2;
  76. var down:Boolean = false;
  77. var dx:Number = 0, dy:Number = 0, time:Number = 0;
  78. var currQuick:QuickObject = circleA;
  79. addEventListener(Event.ENTER_FRAME, onLoop);
  80. function onLoop(evt:Event):void {
  81.    scale += (scaleDest - scale) / 8;
  82.    dx += (currQuick.x*30 - dx) / 8;
  83.    dy += (currQuick.y*30 - dy) / 8;
  84.    // matrix zoom/pan
  85.     var m:Matrix = canvas.transform.matrix;
  86.    m.identity();
  87.    m.translate(-dx,-dy);
  88.    m.scale(scale, scale);
  89.    m.translate(dx,dy);
  90.    canvas.transform.matrix = m;
  91. }

This is a preview of an upcoming feature for the QuickBox2D 1.0 release. It shows how addTimeStepSequence() is going to work. QuickBox2D 1.0 will have an internal timer counting the number of world steps that Box2D has taken. This is really useful for sequencing in conjunction with QuickBox2D's default FRIM (framerate independent motion).

This snippet uses addTimeStepSequence() to move a 2D camera around the simulation (from yesterdays post) - the camera pans and zooms... If you'd like to use addTimeStepSequence() simply replace your QuickBox2D.as file with this updated one:

I plan to release QuickBox2D 1.0 on monday - so I didn't think it made sense to do alpha 110 just for this one change...


Have a look at the swf....

Also posted in QuickBox2D, motion | Tagged , , , | 1 Comment