Tag Archives: Box2D

QuickBox2D FRIM

Actionscript:
  1. import com.actionsnippet.qbox.*;
  2. import Box2D.Common.Math.*;
  3.  
  4. // try altering your frame rate
  5. [SWF(backgroundColor=0x000000, width=700, height=600, frameRate=30)]
  6. // try setting frim to false
  7. var sim:QuickBox2D = new QuickBox2D(this, {iterations:20, timeStep:1 / 60, frim:true});
  8.  
  9. sim.setDefault({fillColor:0x003366, lineAlpha:0});
  10. sim.createStageWalls();
  11.  
  12. sim.addBox({x:10, y:18, height:3, density:0});
  13.  
  14. sim.setDefault({fillColor:0x004466, lineColor:0x2B80F5});
  15.  
  16. var cVel:b2Vec2 = new b2Vec2();
  17.  
  18. for (var i:int = 0; i<32; i++){
  19.     var c:QuickObject = sim.addCircle({x:13 + i % 8, y:10 + int(i / 8), friction:0.01, radius:0.2 + Math.random()*0.3, angularDamping:1});
  20.     cVel.x = Math.random() * 4 - 2;
  21.     cVel.y = Math.random() * 4 - 2;
  22.     c.body.SetLinearVelocity(cVel);
  23. }
  24.  
  25. var box:QuickObject = sim.addBox({x:3, y:16, width:2, height: 2});
  26. var boxVel:b2Vec2 = new b2Vec2(15, -25);
  27.  
  28. sim.start();
  29.  
  30. // shoot the box from left to right
  31. setTimeout(positionBox, 200);
  32. function positionBox():void{
  33.     // reset box position
  34.     box.x = 3, box.y = 16;
  35.     setTimeout(shootBox, 500);
  36. }
  37. function shootBox():void{
  38.     box.body.SetLinearVelocity(boxVel);
  39.     box.body.SetAngularVelocity(10);
  40.     // shoot the box again
  41.     setTimeout(positionBox, 4000);
  42. }

You'll need to download the latest version of QuickBox2D in order to run this snippet (alpha 107 as of this post). I recommend checking out the demo below first though...

The most notable feature of this release is FRIM (frame rate independent motion). FRIM is used to attempt to keep the speed of the Box2D simulation constant no matter what frame rate the swf is running at. This is good because frame rates will vary from browser to browser and from computer to computer.

Mr.Doob suggested that I implement this feature in QuickBox2D. If you haven't seen his site I highly recommend checking it out - really great stuff there.

I created a demo to illustrate the FRIM feature... this demo is basically the same as the above snippet with a few extra buttons added to control frame rate and toggle FRIM.


Take a look at the demo here...

While this new feature seems to be working, I believe there still may be room for improvement. Please let me know if the demo doesn't work correctly on your machine. As of now, I've only tested it on my 2.5 Ghz Intel Core 2 Duo.

Also, any suggestions to improve the clarity of this demo are appreciated... I found it kind of hard to think of a good demo to show FRIM in action. The original demo really didn't make much sense... so I gave Rich Shupe a call and he helped me come up with the idea for the current demo.

UPDATE:
I just updated the demo so that the simulation restarts when you change the frame rate (as per Mr.doob's suggestion below)

Posted in Box2D, QuickBox2D, motion | Also tagged , , , | 10 Comments

QuickBox2D w/ Key Controls

Actionscript:
  1. import com.actionsnippet.qbox.*;
  2. import Box2D.Common.Math.*
  3.  
  4. [SWF(backgroundColor=0xEFEFEF, width=700, height=600, frameRate=60)]
  5.  
  6. var sim:QuickBox2D = new QuickBox2D(this);
  7.  
  8. sim.setDefault({lineColor:0xCC0000, fillColor:0xCC0000});
  9.  
  10. // create compound shape (two circles and a box for the character)
  11. var charParts:Array = [];
  12. // x and y position are now relative to center of compound shape
  13. charParts[0] = sim.addBox({x:0, y:0, width:1, height:2});
  14. charParts[1] = sim.addCircle({x:0, y:-1, radius:0.5});
  15. charParts[2] = sim.addCircle({x:0, y:1, radius:0.5});
  16. var char:QuickObject = sim.addGroup({objects:charParts, x:2, y:2.5, allowSleep:false, angularDamping:0.8, linearDamping:1.5});
  17.  
  18. // vector for linear velocity of character
  19. var charVel:b2Vec2 = new b2Vec2();
  20.  
  21. // angular velocity of character
  22. var charVelAng:Number = 1;
  23. char.body.SetAngularVelocity(charVelAng);
  24.  
  25. // world/platforms
  26. sim.setDefault({lineColor:0x666666, fillColor:0x666666, height:0.5, density:0});
  27. sim.createStageWalls();
  28. sim.addBox({x:3, y:5, width:5});
  29. sim.addBox({x:11, y:5, width:5});
  30. sim.addBox({x:8, y:9, width:8});
  31. sim.addBox({x:4, y:13, width:8});
  32. sim.addCircle({x:16, y:8, radius:2});
  33. sim.addCircle({x:12, y:15, radius:2});
  34.  
  35. // falling circles
  36. sim.setDefault({lineColor:0x2870B5, fillColor:0x2870B5});
  37. for (var i:int = 0; i<15; i++){
  38.     sim.addCircle({x:5 + i, y:2, radius:0.25 ,density:1});
  39. }
  40.  
  41. sim.start();
  42.  
  43. // key controls
  44. addEventListener(Event.ENTER_FRAME, onLoop);
  45. function onLoop(evt:Event):void {
  46.     charVel = char.body.GetLinearVelocity();
  47.     charVelAng =  char.body.GetAngularVelocity();
  48.    
  49.     if (key[Keyboard.RIGHT]){
  50.         charVel.x += 1
  51.         char.body.SetLinearVelocity(charVel);
  52.        
  53.         charVelAng += 1;
  54.         char.body.SetAngularVelocity(charVelAng);
  55.     }
  56.     if (key[Keyboard.LEFT]){
  57.         charVel.x -=1;
  58.         char.body.SetLinearVelocity(charVel);
  59.        
  60.         charVelAng -= 1;
  61.         char.body.SetAngularVelocity(charVelAng);
  62.     }
  63.     if (key[Keyboard.UP]){
  64.          charVel.y = -10;
  65.          char.body.SetLinearVelocity(charVel);
  66.            
  67.          charVelAng *= 0.8;
  68.          char.body.SetAngularVelocity(charVelAng);
  69.     }
  70. }
  71. // basic key setup
  72. var key:Object = new Object();
  73. stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPressed);
  74. stage.addEventListener(KeyboardEvent.KEY_UP, onKeyReleased);
  75. function onKeyPressed(evt:KeyboardEvent):void {
  76.     key[evt.keyCode] = true;
  77.     key.keyCode = evt.keyCode;
  78. }
  79. function onKeyReleased(evt:KeyboardEvent):void { key[evt.keyCode] = false}

This snippet shows one way to go about doing key controls using QuickBox2D

Take a look at the swf here...

This works with the current version of QuickBox2D.... tomorrow I'll be uploading the new version of QuickBox2D which supports FRIM (frame rate independent motion) and contains a few additional minor tweaks and fixes.

Posted in Box2D, QuickBox2D, keys, motion | Also tagged , , | 1 Comment

QuickBox2D Tetris Pieces

Actionscript:
  1. import com.actionsnippet.qbox.*;
  2.  
  3. [SWF(backgroundColor=0x000000, width=700, height=600, frameRate=60)]
  4.  
  5. var sim:QuickBox2D = new QuickBox2D(this);
  6.  
  7. sim.setDefault({fillColor:0x003366, lineColor:0x2B80D5, isBullet:true});
  8. sim.createStageWalls();
  9.  
  10. var shapes:Array = [];
  11. shapes[0] = [[1,1,1,1]];
  12. shapes[1] = [[1, 0, 0], [1, 1, 1]];
  13. shapes[2] = [[0, 0, 1], [1, 1, 1]];
  14. shapes[3] = [[1, 1], [1, 1]];
  15. shapes[4] = [[0, 1, 1], [1, 1, 0]];
  16. shapes[5] = [[0, 1, 0], [1, 1, 1]];
  17. shapes[6] = [[1, 1, 0], [0, 1, 1]];
  18. var cols:Array = [0xFF0000,  0xFFFF00, 0xFF00FF, 0x0000FF, 0x00FF00,0x00FFFF, 0x00FF00,0xFAA703];
  19. var angs:Array =  [0, Math.PI / 2, Math.PI, Math.PI + Math.PI / 2];
  20. var bev:BevelFilter = new BevelFilter();
  21. with (bev) blurX = 10, blurY = 10, strength = 0.5;
  22.  
  23. var inc:int = 9;
  24. for (var i:int = 0; i<shapes.length; i++){
  25.     sim.setDefault({fillColor:cols[inc % cols.length]});
  26.     inc++
  27.     makePiece(shapes[i], 3 + i * 3, 3);
  28.     sim.setDefault({fillColor:cols[inc % cols.length]});
  29.     inc++
  30.     makePiece(shapes[i], 3 + i * 3, 8);
  31. }
  32.  
  33. function makePiece(pattern:Array, xp:Number, yp:Number, scale:Number = 0.7):QuickObject{
  34.     var parts:Array = [];
  35.     for (var i:int = 0; i<pattern.length; i++){
  36.         for (var j:int = 0; j<pattern[i].length; j++){
  37.             if (pattern[i][j] == 1){
  38.                 parts.push(sim.addBox({x:j * scale, y:i * scale, width:scale, height:scale, restitution:0, friction:1, isBullet:true}));
  39.             }
  40.         }
  41.     }
  42.     var ang:Number = angs[int(Math.random()*angs.length)];
  43.     var piece:QuickObject =  sim.addGroup({objects:parts, x:xp, y:yp, angle:ang});
  44.    
  45.     piece.userData.filters = [bev];
  46.     return piece;
  47. }
  48.  
  49. sim.start();
  50. sim.mouseDrag();

This snippet uses the QuickBox2D library to create some Tetris pieces.


Have a look at the swf here...

Posted in Box2D, QuickBox2D, misc | Also tagged , , | 3 Comments

QuickBox2D Groups

Actionscript:
  1. import com.actionsnippet.qbox.*;
  2.  
  3. [SWF (backgroundColor=0xAA0000, width=700, height=600, frameRate=60)]
  4.  
  5. var sim:QuickBox2D = new QuickBox2D(this);
  6.  
  7. sim.createStageWalls();
  8.  
  9. /**
  10. create a dancing pill
  11. */
  12. // all x and y coords are relative to the center of the group
  13. var partA:QuickObject = sim.addCircle({x:-1, y:0, radius:0.5, restitution:.9});
  14. var partB:QuickObject = sim.addCircle({x:1, y:0, radius:0.5, restitution:.9});
  15. var partC:QuickObject = sim.addBox({x:0, y:0, width:2, height:1});
  16. // all the parts are passed into the objects array
  17. // addGroup() groups the parts together into one rigid body
  18. var pill:QuickObject = sim.addGroup({objects:[partA, partB, partC], x:3, y:3, angle:0.3});
  19.  
  20. /**
  21. create another group
  22. */
  23. partA = sim.addCircle({x:0, y:0, radius:1});
  24. partB = sim.addBox({x:0, y:1, width:1, height:1, fillColor:0x666666});
  25. partC = sim.addBox({x:0, y:-1, width:1, height:1, fillColor:0x666666});
  26. sim.addGroup({objects:[partA, partB, partC], x:8, y:3, angle:0.3});
  27.  
  28. /**
  29. create two circles linked together by a stretchy joint
  30. */
  31. partA = sim.addCircle({x:15, y:3, fillColor:0x000000, anglularDamping:1});
  32. partB = sim.addCircle({x:17, y:3, fillColor:0xFFFFFF, anglularDamping:1});
  33. // if x1, y1, x2 and y2 properties are not set, the joint is automatically placed
  34. // at the b2Body's center
  35. sim.addJoint({a:partA.body, b:partB.body, frequencyHz:1});
  36.  
  37. sim.start();
  38. sim.mouseDrag();

You'll need QuickBox2D Alpha 106 to run this... This snippet demo's the addGroup() method, which allows for easy grouping of shapes. I updated the docs today to feature a simple explanation of how this works.


Have a look at the swf here...

Posted in Box2D, QuickBox2D, motion | Also tagged , | 3 Comments