Physics 101 – UIKit app with Box2D for Gravity

Personally I was most at the edge of my seat at the “Voices that Matters Conference” in Seattle when Rod Strougo showed us how to make a physics-enabled game with Cocos2D and Box2D in under an hour. It really was as sexy as he sounds. Eros did what every good TV-cook would do, he had most things already prepared. On the flight home I wanted to see if I could just take the physics part (without Cocos2D) and make a UIKit app with it. The goal of this experiment was to have a UIView with multiple square subviews of different sizes that would start falling as soon as the app starts. The first tricky part is how to add the latest version of the Box2D physics engine to your iPhone project. Then we need to mediate between the different units and coordinate systems of UIKit and Box2D. Finally when we got it all running, we also want to add  the current gravity vector to affect the boxes. So, to get started we need to get the latest version of Box2D. It’s also included in Cocos2D, but for this tutorial we don’t care about getting the entire Cocos2D project. Box2D has a site on Google Code which tells us how to check out a read-only-copy of Box2D. Adding Box2D So we start a terminal, cd into a suitable directory and use this svn command to check out: svn checkout http://box2d.googlecode.com/svn/trunk/ box2d-read-only In the Box2D/Box2D subfolder of the folder this command creates you find all the C++ files that make up the engine. Next we’ll create a new View-based iPhone app, I’m calling mine UIKitPhysics. Now choose Add – Existing Files. Navigate to the innermost Box2D folder of the project, it’s 2 levels deep, and add it to your project. If you want to be able to update it from the repository in the future, you need to not copy it to your project. If you don’t care about updating then you can copy the files. I choose to copy it because it makes setting of the header search path easier later on. So now we have a Box2D group in our project. This is one way of adding it, the other would be to build a static library in Box2D and add this, but the above mentioned method looks easy enough for our first physics-enabled app. There are still a couple more tweaks necessary to get it all working properly. Box2D is written entirely in C++, but we are used to be working in Objective-C. Xcode usually uses the file extension to discern which compiler to use. Now if we are going to uses some function calls into Box2D those will be in C++ syntax. So we have two options to get the compiler to accept these as valid syntax. Either you modify the file extension to .mm or you force the compiler directly to interpret the affected files as C++. I think the latter is cleaner. This tweak is necessary for all .m files which use C++ syntax and/or include the Box2D header. Since the default project probably has an include of the our view controller’s header in the app delegate, you need to make the same adjustment for the app delegate’s .m file. Get Info on the those files and change the file type to “sourcecode.cpp.objcpp”. This does not hurt, your normal Objective-C code can still be compiled normally. Box2D uses angle brackets for all imports. So as the last step we need to add the location where the Box2D directory resides to the header search path. This can be done in the Project Settings or Target Settings. Since we want it to be in effect for all targets it’s preferable to set it in the Project Settings. Go to Project – Edit Project Settings, look for “Header Search Paths” and add this setting. I’m using the environment variable ${PROJECT_DIR} so that it always works regardless where our project currently resides. Should you have Box2D outside of the project then you need to add the full path at this stage. Now with this setting any #import with angle brackets will also work if the Box2D folder is inside your project root directory. UIKit, meet Mr. Box2D Now we are ready to add physical behaviors to our UIKit app. But first a couple of tidbits to understand the differences between those two. Any two-dimensional object in Box2D has it’s own representation which is completely independent from how it is drawn. Nor does Box2D draw anything nor does it move anything. Therefore we have to create a physical representation for each view that we want to attach physics to. We have to set a timer to poll where the physical object have moved and rotated to at set intervals and update … Continue reading Physics 101 – UIKit app with Box2D for Gravity