Integrating Box2D in an Android project

Hello

I searched for a solution for this all over the forums, but I found no solution so far.

What I am trying to do: create a project for iPhone and Android with Box2D support.

What I’ve done so far: create the project in Xcode, create Android project, merge them together. The directory structure is like this:

Game
  - android
  - ios
  - Classes
  - libs (contains cocos2dx, Box2D, etc)

What stops me: the Android code does not build when the compiler tries to build the libgame because:

SharedLibrary  : libbox2d.so
Install        : libbox2d.so => libs/armeabi/libbox2d.so
Compile++ thumb  : game <= AppDelegate.cpp
In file included from /Users/clw/Projects/BoxGame/android/jni/helloworld/../../../libs/Box2D/Box2D.h:36,
                 from /Users/clw/Projects/BoxGame/android/jni/helloworld/../../../Classes/HelloWorldScene.h:13,
                 from /Users/clw/Projects/BoxGame/android/jni/helloworld/../../../Classes/AppDelegate.cpp:12:
/Users/clw/Projects/BoxGame/android/jni/helloworld/../../../libs/Box2D/Collision/Shapes/b2CircleShape.h:22:44: error: Box2D/Collision/Shapes/b2Shape.h: No such file or directory
In file included from /Users/clw/Projects/BoxGame/android/jni/helloworld/../../../libs/Box2D/Box2D.h:39,
                 from /Users/clw/Projects/BoxGame/android/jni/helloworld/../../../Classes/HelloWorldScene.h:13,
                 from /Users/clw/Projects/BoxGame/android/jni/helloworld/../../../Classes/AppDelegate.cpp:12:
/Users/clw/Projects/BoxGame/android/jni/helloworld/../../../libs/Box2D/Collision/b2BroadPhase.h:22:37: error: Box2D/Common/b2Settings.h: No such file or directory
/Users/clw/Projects/BoxGame/android/jni/helloworld/../../../libs/Box2D/Collision/b2BroadPhase.h:23:41: error: Box2D/Collision/b2Collision.h: No such file or directory
/Users/clw/Projects/BoxGame/android/jni/helloworld/../../../libs/Box2D/Collision/b2BroadPhase.h:24:43: error: Box2D/Collision/b2DynamicTree.h: No such file or directory
// goes on and on

As you can see, box2d is successfully built (I checked, it also shows up in libs/armeabi as libbox2d.so).

I inspected the tests directory and took note of how Box2D is referenced in the makefiles and made the following changes to my Android makefiles:

android/jni/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

subdirs := $(addprefix $(LOCAL_PATH)/../../libs/,$(addsuffix /Android.mk, \
           Box2D \                                                                                        <<< added this line right here
           cocos2dx \
           CocosDenshion/android \
    ))
subdirs += $(LOCAL_PATH)/helloworld/Android.mk

include $(subdirs)

android/jni/Application.mk

APP_STL := stlport_static

APP_MODULES := cocos2d cocosdenshion box2d game

android/jni/helloworld/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := game

LOCAL_SRC_FILES := main.cpp \
../../../Classes/AppDelegate.cpp \
../../../Classes/HelloWorldScene.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../libs/cocos2dx \
                    $(LOCAL_PATH)/../../../libs/cocos2dx/platform \
                    $(LOCAL_PATH)/../../../libs/Box2D \
                    $(LOCAL_PATH)/../../../libs/cocos2dx/include \
                    $(LOCAL_PATH)/../../../libs/CocosDenshion/include \
                    $(LOCAL_PATH)/../../../Classes

LOCAL_LDLIBS := -L$(call host-path, $(LOCAL_PATH)/../../libs/armeabi) \
                -lGLESv1_CM \
                -lbox2d \
                -lcocos2d -llog -lcocosdenshion \
                -L$(call host-path, $(LOCAL_PATH)/../../../libs/cocos2dx/platform/third_party/android/libraries) -lcurl

include $(BUILD_SHARED_LIBRARY)

Am I missing something? Was I supposed to add something to main.cpp? I tried adding both #include “Box2D/Box2D.h” and #include <Box2D/Box2D.h> but that’s not helping.

Thanks!

Hmmm, It seems that

LOCAL_C_INCLUDES := $(LOCAL_PATH)/…/…/…/
is missed in android/jni/helloworld/Android.mk
According to your error log, “Box2D/Common/b2Settings.h: No such file or directory”, which means the #include command starts from “Box2D”, so your path $(LOCAL_PATH)/…/…/…/libs/Box2D can not work in this situation.

One more thing is that, don’t forget to add

System.loadLibrary(“box2d”);

in android/src/org/cocos2dx/application/ApplicationDemo.java, looks like

     static {
         System.loadLibrary("cocosdenshion");
         System.loadLibrary("box2d");
         System.loadLibrary("cocos2d");
         System.loadLibrary("MyGame");
     } 

Otherwise the game will crash at start up.

I think you should change

 $(LOCAL_PATH)/../../../libs/Box2D \ 

to

 $(LOCAL_PATH)/../../../libs \ 

to include header files of Box2D.
Because all the Box2D header files are included as <Box2D/xxx>.

Of course! Thanks a lot Minggo and Walzer!

That was the problem, I had to add the directory that contained the Box2D folder.

For whoever is interested I also wrote a step by step guide about setting up an Android project with Box2D: http://gameit.ro/2011/08/creating-a-cocos2d-x-box2d-android-project/

Fantastic! I promoted this blog in weibo, twitter & facebook group.

I am still currently having problems with trying to compile a android project with Box2D.
I’ve followed the instructions from http://gameit.ro/2011/08/creating-a-cocos2d-x-box2d-android-project/#comment-270 and was still unable to compile. Been trying this 8 hours straight.

Here’s where the point where it’s unable to compile.

In file included from jni/…/…/Classes/AppDelegate.cpp:4:
jni/…/…/Classes/HelloWorldScene.h:6:25: error: Box2D/Box2D.h: No such file or directory
In file included from jni/…/…/Classes/AppDelegate.cpp:4:
jni/…/…/Classes/HelloWorldScene.h:31: error: ISO C++ forbids declaration of ‘b2Body’ with no type
jni/…/…/Classes/HelloWorldScene.h:31: error: expected ‘;’ before ‘’ token
jni/…/…/Classes/HelloWorldScene.h:32: error: ISO C++ forbids declaration of ’b2World’ with no type
jni/…/…/Classes/HelloWorldScene.h:32: error: expected ’;’ before ’
’ token
/cygdrive/c/android-ndk-r7/build/core/build-binary.mk:241: recipe for target `obj/local/armeabi/objs-debug/game_logic/AppDelegate.o’ failed
make: * [obj/local/armeabi/objs-debug/game_logic/AppDelegate.o] Error 1
make: Leaving directory `/cygdrive/c/cocos2d-1.0.1-x-0.10.0/test8/android’

If anyone could help me out I’d greatly appreciate it

You should add the path of cocos2dx installation to LOCAL_C_INCLUDES, because Box2D header files are used as <Box2D/…>.

hmm right now I’m getting a new list of errors…

C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/…/…/Box2D/Collision/Shapes/b2CircleShape.h:70: undefined reference to `vtable for b2CircleShape’
./obj/local/armeabi/objs-debug/game_logic/HelloWorldScene.o: In function `b2EdgeShape’:
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/…/…/Box2D/Collision/Shapes/b2EdgeShape.h:72: undefined reference to `vtable for b2EdgeShape’
./obj/local/armeabi/objs-debug/game_logic/HelloWorldScene.o: In function `~b2EdgeShape’:
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/…/…/Box2D/Collision/Shapes/b2EdgeShape.h:28: undefined reference to `vtable for b2EdgeShape’
./obj/local/armeabi/objs-debug/game_logic/HelloWorldScene.o: In function `~b2CircleShape’:
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/…/…/Box2D/Collision/Shapes/b2CircleShape.h:26: undefined reference to `vtable for b2CircleShape’
./obj/local/armeabi/objs-debug/game_logic/HelloWorldScene.o: In function `HelloWorld::init()‘:
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:63: undefined reference to `b2World::b2World(b2Vec2 const&)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:64: undefined reference to `b2World::SetAllowSleeping(bool)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:70: undefined reference to `b2World::CreateBody(b2BodyDef const**)‘
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:75: undefined reference to `b2EdgeShape::Set(b2Vec2 const&, b2Vec2 const&)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:76: undefined reference to `b2Body::CreateFixture‘
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:77: undefined reference to `b2EdgeShape::Set(b2Vec2 const&, b2Vec2 const&)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:78: undefined reference to `b2Body::CreateFixture‘
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:79: undefined reference to `b2EdgeShape::Set(b2Vec2 const&, b2Vec2 const&)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:80: undefined reference to `b2Body::CreateFixture‘
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:81: undefined reference to `b2EdgeShape::Set(b2Vec2 const&, b2Vec2 const&)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:82: undefined reference to `b2Body::CreateFixture’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:89: undefined reference to `b2World::CreateBody’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:99: undefined reference to `b2Body::CreateFixture‘
./obj/local/armeabi/objs-debug/game_logic/HelloWorldScene.o: In function `HelloWorld::tick(float)’:
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:110: undefined reference to `b2World::Step‘
collect2: ld returned 1 exit status
/cygdrive/c/android-ndk-r7/build/core/build-binary.mk:312: recipe for target `obj/local/armeabi/libgame_logic.so’ failed
make:**** [obj/local/armeabi/libgame_logic.so] Error 1

Box2D is updated to 2.2.1, did you update your using of it?

yep i am sure it’s 2.2.1

right those errors have seemed to fix themselves somehow…now for some reason I am getting

/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/…/lib/gcc/arm-linux-androideabi/4.4.3/…/…/…/…/arm-linux-androideabi/bin/ld.exe: cannot find -lbox2d
collect2: ld returned 1 exit status
/cygdrive/c/android-ndk-r7/build/core/build-binary.mk:312: recipe for target `obj/local/armeabi/libgame_logic.so’ failed
make: * [obj/local/armeabi/libgame_logic.so] Error 1

I take that back… the errors have appeared again…

C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/…/…/Box2D/Collision/Shapes/b2CircleShape.h:70: undefined reference to `vtable for b2CircleShape’
./obj/local/armeabi/objs-debug/game_logic/HelloWorldScene.o: In function `b2EdgeShape’:
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/…/…/Box2D/Collision/Shapes/b2EdgeShape.h:72: undefined reference to `vtable for b2EdgeShape’
./obj/local/armeabi/objs-debug/game_logic/HelloWorldScene.o: In function `~b2EdgeShape’:
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/…/…/Box2D/Collision/Shapes/b2EdgeShape.h:28: undefined reference to `vtable for b2EdgeShape’
./obj/local/armeabi/objs-debug/game_logic/HelloWorldScene.o: In function `~b2CircleShape’:
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/…/…/Box2D/Collision/Shapes/b2CircleShape.h:26: undefined reference to `vtable for b2CircleShape’
./obj/local/armeabi/objs-debug/game_logic/HelloWorldScene.o: In function `HelloWorld::init()‘:
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:63: undefined reference to `b2World::b2World(b2Vec2 const&)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:64: undefined reference to `b2World::SetAllowSleeping(bool)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:70: undefined reference to `b2World::CreateBody(b2BodyDef const**)‘
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:75: undefined reference to `b2EdgeShape::Set(b2Vec2 const&, b2Vec2 const&)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:76: undefined reference to `b2Body::CreateFixture‘
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:77: undefined reference to `b2EdgeShape::Set(b2Vec2 const&, b2Vec2 const&)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:78: undefined reference to `b2Body::CreateFixture‘
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:79: undefined reference to `b2EdgeShape::Set(b2Vec2 const&, b2Vec2 const&)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:80: undefined reference to `b2Body::CreateFixture‘
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:81: undefined reference to `b2EdgeShape::Set(b2Vec2 const&, b2Vec2 const&)’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:82: undefined reference to `b2Body::CreateFixture’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:89: undefined reference to `b2World::CreateBody’
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:99: undefined reference to `b2Body::CreateFixture‘
./obj/local/armeabi/objs-debug/game_logic/HelloWorldScene.o: In function `HelloWorld::tick(float)’:
C:2d-1.0.1-x-0.10.0\testbox1\android/jni/…/…/Classes/HelloWorldScene.cpp:110: undefined reference to `b2World::Step‘
collect2: ld returned 1 exit status
/cygdrive/c/android-ndk-r7/build/core/build-binary.mk:312: recipe for target `obj/local/armeabi/libgame_logic.so’ failed
make:**** [obj/local/armeabi/libgame_logic.so] Error 1

…I’m on my wits end with this

May be you should refer how tests doing.
Compiling errors are easy to resolve, just add the header path and lib path into searching path.

Sorry I do not know what you mean by the searching path

I’m having the same problem.
I couldn’t integrate box2d in this cocos’ release

After a 2 day struggle i managed to get box2d and cocos2d running happy (even on a hybrid project, iOS and android sharing the same code) thanks to the http://gameit.ro tutorials! I really wish I could buy him a beer!

Be sure you read and re-read his tutorials. But my main pointers are:

  1. My main project directory is on the cocos2dx root folder. This advice is given and should be a no brainer.

  2. Cocos2d default project creationg build an APP_MODULE called game_logic, this was killing me when i was trying to build (giving me linking errors and such). I just removed it and everything went fine! Dont know if removing it is a good idea, but my project is doing fine without it!

I will not post how my .mk files are:

Main Android.mk file (this is under the folder jni):

**LOCAL_PATH := $
include $
subdirs := $/…/…/libs/,$)
subdirs += $/helloworld/Android.mk
include $*
Application.mk file :
**# it is needed for ndk-r5
APP_STL := stlport_static
APP_MODULES := cocos2d cocosdenshion box2d game*

Android.mk (this is under the helloworld folder, the most important one!):

**LOCAL_PATH := $
include $
LOCAL_MODULE := game
LOCAL_SRC_FILES := main.cpp …/…/…/Classes/AppDelegate.cpp …/…/…/Classes/HelloWorldScene.cpp
LOCAL_C_INCLUDES := $/…/…/…/libs/cocos2dx $/…/…/…/libs/cocos2dx/platform $/…/…/…/libs/cocos2dx/include $/…/…/…/libs/CocosDenshion/include $/…/…/…/libs/ $/…/…/…/libs/Box2D $/…/…/…/Classes
# it is used for ndk-r5
# if you build with ndk-r4, comment it
# because the new Windows toolchain doesn’t support Cygwin’s drive
# mapping
LOCAL_LDLIBS := ~~L$/…/…/libs/armeabi) ~~lGLESv1_CM ~~lbox2d ~~lcocos2d lloglcocosdenshion ~~L$/…/…/…/libs/cocos2dx/platform/third_party/android/libraries)~~lcurl
include $
**

This is where i struggled! Well, libs is a foler on my project root folder, it contains the used modules (box2d, cocos2d, cocosdenhsion), I had to copy over them from the current cocos2dx root folder because the project creation somehow was not copying the right folders (missing files and other stuff, i didnt went to further into, but i might) :frowning:

build_native.sh (just changed the main processor variables):

# set params
COCOS2DX_ROOT=/Users/joe/Desktop/works/Monumenta/Embratur/Game/Code/Cocos2dX/Dev/cocos2d-1.0.1-x-0.10.0
GAME_ROOT=$COCOS2DX_ROOT/BrasilQuestX
GAME_ANDROID_ROOT=$GAME_ROOT/android
RESOURCE_ROOT=$GAME_ROOT/Resources

BrasilQuestX is my main game folder and as you can see, its under the cocos2d root folder!

Im using NDK r5. The variable for the r5 directory is set under the bash_profile, but you could set under the build_native.sh just like the tutorial!

*This was pretty much all i had to do! I was pulling my hair off, untill i saw the breakout demo using box2d on gameit.ro website! Link: [http://gameit.ro/2011/09/breakout/] After downloading it and seeing how he has done it was a life changer for me and within minutes i had my project set up![](*

It uses box2d and had compiled so perfectly i looked into all the .mk files and made all the changes, after a few tweaks here and there, i managed to build everything without any compile/link errors)

I hope it helps you! I know how hard it its to get it right the first time! Will do everything i can to help you out! Good luck! :wink:

Sorry about the * (asterisks) and the formatting, im getting used to post on this forum. Some formatting was not the way i intended to, so dont just copy and paste ok ? :slight_smile:

actually i found a different solution… as well as modifying the mk files in jni, I modified the file android.mk inside the classes folder with :-

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := game

LOCAL_SRC_FILES := main.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/…/…/…/…/cocos2dx $(LOCAL_PATH)/…/…/…/…/cocos2dx/platform $(LOCAL_PATH)/…/…/…/…/cocos2dx/include $(LOCAL_PATH)/…/…/…/ $(LOCAL_PATH)/…/…/…/Classes

LOCAL_LDLIBS := ~~L$/…/…/libs/$) ~~lGLESv1_CM ~~lbox2d ~~lcocos2d lloglgame_logic

include $(BUILD_SHARED_LIBRARY)

The Changes I made were adding:

~~lGLESv1_CM
and
~~lbox2d
as well as adding:

$(LOCAL_PATH)/…/…/…/
and this solved my problem

Great! You even managed to get it along with game_logic. Do you have any clues of what this module is for ? Im starting to build my game and it does not have this module. Maybe on the long run it will bite me in the ass ? :stuck_out_tongue: