Book Image

Box2D for Flash Games

Book Image

Box2D for Flash Games

Overview of this book

Physics games are getting more and more popular, and Box2D is the best choice if you are looking for a free, stable and robust library to handle physics. With Box2D you can create every kind of 2D physics game, only coding is not the fun part, but the game itself. "Box2D for Flash Games" will guide you through the process of making a Flash physics game starting from the bare bones and taking you by hand through complex features such as forces, joints and motors. As you are learning, your game will have more and more features, like the physics games you are used to playing. The book analyzes two of the most played physics games, and breaks them down to allow readers to build them from scratch in a step-by-step approach. By the end of the book, you will learn how to create basic primitive bodies as well as complex, compound bodies. Motors will give life to cars, catapults and siege machines firing bullets, while a complete collision management will make your game look even more realistic. If you want to make full Flash games with physics, then Box2D for Flash Games will guide you through the entire process of making a Flash physics game.
Table of Contents (15 chapters)
Box2D for Flash Games
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Running the simulation


You need to run the simulation at every frame, so first of all you need a listener to be triggered at every frame.

  1. Let's make some simple changes to our class:

    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 Main extends Sprite {
        public function Main() {
          var gravity:b2Vec2=new b2Vec2(0,9.81);
          var sleep:Boolean=true;
          var world:b2World = new b2World(gravity,sleep);
          addEventListener(Event.ENTER_FRAME,updateWorld);
        }
        private function updateWorld(e:Event):void {
          trace("my awesome simulation runs here");
        }
      }
    }

    Nothing new, we just added an ENTER_FRAME event, but we needed it in order to run the simulation inside the updateWorld function. If you have doubts regarding event handling with AS3, refer to the official Adobe docs or get Flash Game Development by Example, Packt Publishing, which will guide you to a step-by-step creation of pure AS3 games.

    Box2D simulation works by simulating the world at discrete steps of time. This means the world gets updated at every time step. It's up to us to decide which time step we are going to use for our simulation. Normally, physics in games have a time step of 1/60 seconds. Anyway, as I am running the Flash movie at 30 fps, I am going to set a time step of 1/30 seconds.

  2. The first line into the updateWorld function will be:

    var timeStep:Number=1/30

    Just defining a time step, is not enough. At every step, every physic entity is updated according to the forces acting on it (unless it's sleeping). The algorithm which handles this task is called constraint solver. It basically loops through each constraint and solves it, one at a time. If you want to learn more about constraints, search for "constraint algorithm" on Google or Wikipedia.

    Where's the catch? While a single constraint is solved perfectly, it can mess with other constraints that have already been solved.

    Think about two balls moving: in the real world, each ball position is updated at the same time. In a computer simulation, we need to loop through the balls and update their position one at a time. Think about a for loop that updates a ball at every iteration. Everything works as long as the balls do not interact with each other, but what happens if the second ball hits the first, whose position has already been updated? They would overlap, which is not possible in a rigid body simulation.

    To solve this problem with a reasonable approximation, we need to loop over all the constraints more than once. Now the question is: how many times?

    There are two constraint solvers: velocity constraint solver and position constraint solver . The velocity solver is used to move physic entities in the world according to their impulses. The position solver adjusts physic entities' positions to avoid overlap.

    So it's obvious that the more iterations there are, the more accurate the simulation, and the lower will be the performance. I managed to handle more than 100 physic entities using 10 velocity and position iterations, although the author of Box2D recommends 8 for velocity and 3 for position.

  3. It's up to you to play with these values. Meanwhile, I'll be using 10 iterations for both constraint solvers.

    So here we go with two new variables:

    var velIterations:int=10;
    var posIterations:int=10;
  4. Finally we are ready to call the Step method on the world variable to update the simulation.

    To use world inside the updateWorld function, we need to declare world as a class-level variable, shown as follows:

    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 Main extends Sprite {
        private var world:b2World;
        public function Main() {
          var gravity:b2Vec2=new b2Vec2(0,9.81);
          var sleep:Boolean=true;
          world=new b2World(gravity,sleep);
          addEventListener(Event.ENTER_FRAME,updateWorld);
        }
        private function updateWorld(e:Event):void {
          var timeStep:Number=1/30;
          var velIterations:int=10;
          var posIterations:int=10;
          world.Step(timeStep,velIterations,posIterations);
        }
      }
    }

    Now we have our world configured and running. Unfortunately, it's a very boring world, with nothing in it. So in the next chapter, we are going to populate the world with all kinds of physic entities.

  5. Just one last thing, after each step you need to clear forces, to let the simulation start again at the next step.

  6. You can do it by adding the following line right after the Step method:

    world.ClearForces();Your final code is shown as follows:
    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 Main extends Sprite {
        private var world:b2World;
        public function Main() {
          var gravity:b2Vec2=new b2Vec2(0,9.81);
          var sleep:Boolean=true;
          world=new b2World(gravity,sleep);
          addEventListener(Event.ENTER_FRAME,updateWorld);
        }
        private function updateWorld(e:Event):void {
          var timeStep:Number=1/30;
          var velIterations:int=10;
          var posIterations:int=10;
          world.Step(timeStep,velIterations,posIterations);
          world.ClearForces();
        }
      }
    }

    Tip

    Downloading the example code

    You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

    And now you are really ready to place some action in your Box2D World.