Getting under the hood with PhysInjector and Box2D: AIR to App Store, Day 8

A friend and fellow indie game developer of mine, Silas Rowe of Miniboss.com,  mentioned something interesting to me yesterday after I’d asked him if he was reading my blog.

“It’s alright, but I still feel like I’m in the dark about the actual game itself. I haven’t really learnt anything about the game since you announced it on day one.”

chris_programmer

“Whaaaaaaaaat?!!!”

The thing is, I have to admit he’s right. There’s not a whole lot of focus in my writing right now. The blog was initially planned to be a straight-up developer diary, but with each day has morphed into my general thoughts on the industry and various aspects within. Once the game is finished, I’m going to keep blogging about the game dev business some more – I have around ten years experience making Flash games after all and have seen many trends come and go, so there’s a lot to say.

I didn’t want the blog to just be a 14 day advertisement for the upcoming game Fishmonger, nor did I want it too be too technical and specific as to alienate those curious about the business – however, it’s a fine balance between trying to cast too wide a net and catering for too niche an audience. I must say though, a hundred reads a day of the blog is actually more than I expected, and for that, I’m grateful.

So the question I’d like to pose is, what would you prefer to hear about? More technical stuff? More general thoughts and opinions about the business? More hillarious cat gifs ?

For those not so technically minded, you can safely stop reading here and enjoy the rest of your Friday. Have a beer for me, you’ve earnt it! For the rest of you, it’s time to get our hands dirty with some code.

Today, I’m going to indulge Silas and get under the hood of the game, discussing a few game mechanics. Here’s a couple of details about the game:

  • It’s made using Adobe AIR and Flash. I can basically port it to iOS, Android, a browser, or even Steam, with ease. Try that in HTML5 in 2 weeks, I dare you.
  • The game engine itself coded in Actionscript 3 using the excellent FlashDevelop IDE.
  • I’m using Gamua’s awesome Starling Framework for the game. It allows for 60 frames per second, lightning fast gameplay across the web and mobile. There are benchmark tests that actually show that in some circumstances, Starling  is actually faster than Unity for making 2D games. I’ve got lots of experience in Starling, and only limited in Unity so I can’t confirm this myself. Each to their own, I think Starling rocks.
  • Graphic assets are made in Illustrator/Photoshop then imported using spritesheets made in TexturePacker , as well as some dynamically converted MovieClips in Flash Pro CC.
  • The game engine uses an AS3 port of Box2D (the physics engine behind Angry Birds, no less ) and Reynaldo Columna’s excellent PhysInjector plugin.

The game itself is a physics puzzler in which the protagonist, a rusty fishing boat with a salty sea captain, must drop blocks of ice and balance them in a limited time. The blocks themselves have their own weights and physical properties, rectangles, triangles and ‘tetris style’ L Shapes, etc. Initially, this was the ONLY game mode but I found it a) too difficult to stack too many blocks without them collapsing and b) a little too repetitive. I stepped away from the game for a few hours to plan a few ways to come up with some variety.

block_04block_14block_10

I have a class in the game for each IceBlock creates a Starling Sprite called blockMC and assigns it some box2D physics properties: How heavy is it? How bouncy? The code below defines this.

blockProperties = new PhysicsProperties();
blockProperties.isDynamic = true;
blockProperties.isSensor = false;
blockProperties.name=”iceBlock”
blockProperties.contactGroup = “iceBlocks”
blockProperties.restitution = 0.01
blockProperties.friction = 1
blockProperties.density = 2

And we apply this code to a special object called a PhysicsObject with the following code:

var blockPhys:PhysicsObject

var blockType:int=1   //regular square block

if (check_array(polygonsArray, blockType )) { //PHYSEDITOR CUSTOM SHAPES

blockProperties.physicsEditorClass = PhysicsData
blockProperties.physicsEditorName = “block_0″+ blockType
blockPhys =gameGlobals.box2DWorld.physics.injectPhysics(blockMC, PhysInjector.PHYSEDIT, blockProperties);
}
else blockPhys = gameGlobals.box2DWorld.physics.injectPhysics(blockMC, PhysInjector.SQUARE, blockProperties)}

By setting blockProperties.friction=0  , we can make slippery blocks very easily. Alternatively, you can set blockProperties.restitution=0.66 to make bouncier blocks. It’s quite easy to mix and match blocks this way. I differentiated these blocks just by setting a tint colour on each block with blockMC.color = 0xCCFF00 ( green )

The PhysicsInjector.PHYSEDIT property refers to custom shapes created using this handy little tool, PhysicsEditor from CodeAndWeb. It’s really easy to drag transparent PNG files into the program and spit out code ( not just for Actionscript, it works great for Unity, Cocoa etc )

physiceEditor

 

Here’s a sample of the code that would be spat out for a custom shape. It doesn’t make too much sense at first glance, but they’re just co-ordinates for creating vectors Box2D can translate into complex shapes.

[ new b2Vec2(23/ptm_ratio, 28.5/ptm_ratio) , new b2Vec2(26/ptm_ratio, 0.5/ptm_ratio) , new b2Vec2(27/ptm_ratio, 0.5/ptm_ratio) , new b2Vec2(45.5/ptm_ratio, 17/ptm_ratio) , new b2Vec2(42.5/ptm_ratio, 29/ptm_ratio) , new b2Vec2(28/ptm_ratio, 35.5/ptm_ratio) ] 

These blocks come into the game when the user taps a screen, and they drop down until they hit either the boat or fall into the sea. PhysInjector has an awesome class called ContactManager, which allows me to set up listeners for when various objects come into contact with each other. Simply add this code when you add an iceblock to the stage and you can instantly determine collisions between contactGroups.

ContactManager.onContactEnd(“iceBlocks”, “iceBlocks”, handleContactBegin,true)
ContactManager.onContactBegin(“boat”, “iceBlocks”, handleContactBegin,true)

When they actually collide, you can determine what to do next, whether to play a sound, make the block explode, and so on.

private function handleContactBegin(objectA:PhysicsObject, objectB:PhysicsObject, contact:b2Contact):void
{
    if (objectA.physicsProperties.contactGroup==”iceBlocks” && objectB.physicsProperties.contactGroup==”iceBlocks”){
      if (objectA.data.firstContact != true ) {
         gameGlobals.gameSounds.playSound(“ice”)
       objectA.data.firstContact = true
      showContactText(objectA)
    }
    if (objectB.data.firstContact != true ) {
       objectB.data.firstContact = true
      showContactText(objectB)
    }

    if (objectA.data.volatile==true && objectB.data.volatile==true) {
      ///red blocks touching, boom
     createExplosion(objectA)
     createExplosion(objectB)
    }

}

Notice the objectA.data property? This is just a generic object set when I created the initial blockMC Starling Sprite. You can assign custom properties. volatile, for example, makes two blocks explode on contact.

public function createExplosion(obj:PhysicsObject):void
{ //create an explosion
explosions.create(obj.x, obj.y,500,25)  //create an explosion 500 pixels in diameter with an impulse force of 25
shakeScreen(10, 10, 10, this)
gameGlobals.gameSounds.playSound(“sparks”,0.5)
gameGlobals.gameSounds.playSound(“explosion”,0.2)
}

In the image below, the red block is volatile. If I drop another one on it, it’ll explode and fly out of the boat, ending the level.

fishmonger_5

 

You will notice the two buttons down the bottom of the screen. These create other Box2D objects on the screen which can stop the boat rocking ( an anchor ) or a girder which can guide your blocks for a while before it falls. It’s easy to make items that are suspended in the air: just set their isDynamic property to false, like so (bumperProps being a PhysInjector PhysicsObject.)

bumperProps.isDynamic =false

I’ve come up with a stack of different game modes just using the various blocks, girders and bumpers. Today I’m building a quick visual level editor so I can churn out 50 or so levels for the game. I was doing it originally via code but I’ve found if you spend time on a level editor, you can test out levels much more easily. I’m a visual creature at heart, after all! Here’s what the editor will roughly churn out. I can set how many blocks for victory, the time of day, even the victory conditions for the level.


var lo:Object=new Object()
lo.timeLeft =30

lo.iceBlocksNeeded = 10
lo.victoryConditions=[VictoryConditions.STACK_BLOCKS,VictoryConditions.BLUE_BLOCKS]
lo.bumpersArray = [ { x:100, y:250 }, { x:500, y:250 }, { x:300, y:400 } ]
allLevelBlocks.push(9,14)   //the blocks that can be used in the level
lo.hourFrame = 1
lo.weatherFrame = 7

Anyway, that is it for today. I hope this has been a little enlightening for you on the process behind building a physics based puzzle game in Box2D and PhysInjector. If you’ve got any questions or comments, please hit me up and I’d be happy to help. Remember as always, you can follow me at https://twitter.com/oliver_joyce

Cheers, Oliver Joyce

 

 1781 people have viewed this page.