Skip to content

Commit de71f45

Browse files
CardillosCreationsCardillosCreations
authored andcommitted
Initial commit of JBox2D test. Looking good on emulator and on a physical device (Motorola Droid) but some problems noticed seem to be elsewhere in the library.
1 parent 6b97b13 commit de71f45

File tree

5 files changed

+262
-1
lines changed

5 files changed

+262
-1
lines changed

.classpath

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
44
<classpathentry kind="src" path="src"/>
55
<classpathentry kind="src" path="gen"/>
6+
<classpathentry exported="true" kind="lib" path="libs/JBox2D-2.0.1-b250-Library.jar"/>
67
<classpathentry kind="output" path="bin"/>
78
</classpath>

AndroidManifest.xml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
package="org.cocos2d"
44
android:versionCode="1"
55
android:versionName="1.0">
6-
<application android:label="@string/app_name" android:icon="@drawable/icon">
6+
<application android:label="@string/app_name" android:icon="@drawable/icon" android:debuggable="true">
77
<activity android:name=".Cocos2D"
88
android:label="@string/app_name">
99
<intent-filter>
@@ -99,6 +99,16 @@
9999
</intent-filter>
100100
</activity>
101101

102+
<activity android:name=".tests.JBox2DTest"
103+
android:debuggable="true"
104+
android:launchMode="singleInstance"
105+
android:label="@string/activity_jbox2dtest" android:configChanges="keyboardHidden|orientation" android:screenOrientation="portrait">
106+
<intent-filter>
107+
<action android:name="android.intent.action.MAIN"/>
108+
<category android:name="android.intent.category.TEST"/>
109+
</intent-filter>
110+
</activity>
111+
102112
<activity android:name=".tests.ClickAndMoveTest"
103113
android:debuggable="true"
104114
android:launchMode="singleInstance"
@@ -170,4 +180,6 @@
170180
</activity>
171181

172182
</application>
183+
184+
<uses-sdk android:minSdkVersion="4"></uses-sdk>
173185
</manifest>

libs/JBox2D-2.0.1-b250-Library.jar

548 KB
Binary file not shown.

res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<string name="activity_menutest">Menu Test</string>
99
<string name="activity_atlastest">Atlas Test</string>
1010
<string name="activity_atlasspritetest">Atlas Sprite Test</string>
11+
<string name="activity_jbox2dtest">JBox2D Test</string>
1112
<string name="activity_clickandmovetest">Click And Move Test</string>
1213
<string name="activity_cocosnodetest">Cocos Node Test</string>
1314
<string name="activity_drawprimitivestest">Draw Primitives Test</string>

src/org/cocos2d/tests/JBox2DTest.java

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
package org.cocos2d.tests;
2+
3+
import org.cocos2d.events.TouchDispatcher;
4+
import org.cocos2d.layers.Layer;
5+
import org.cocos2d.nodes.AtlasSprite;
6+
import org.cocos2d.nodes.AtlasSpriteManager;
7+
import org.cocos2d.nodes.Director;
8+
import org.cocos2d.nodes.Label;
9+
import org.cocos2d.nodes.Scene;
10+
import org.cocos2d.nodes.TextureManager;
11+
import org.cocos2d.opengl.CCGLSurfaceView;
12+
import org.cocos2d.types.CCColor3B;
13+
import org.cocos2d.types.CCMacros;
14+
import org.cocos2d.types.CCPoint;
15+
import org.cocos2d.types.CCRect;
16+
import org.cocos2d.types.CCSize;
17+
import org.jbox2d.collision.AABB;
18+
import org.jbox2d.collision.shapes.EdgeChainDef;
19+
import org.jbox2d.collision.shapes.PolygonDef;
20+
import org.jbox2d.common.Vec2;
21+
import org.jbox2d.dynamics.Body;
22+
import org.jbox2d.dynamics.BodyDef;
23+
import org.jbox2d.dynamics.World;
24+
25+
import android.app.Activity;
26+
import android.os.Bundle;
27+
import android.view.MotionEvent;
28+
import android.view.Window;
29+
import android.view.WindowManager;
30+
31+
/**
32+
* A test that demonstrates basic JBox2D integration by using AtlasSprites connected to physics bodies.
33+
* <br/>
34+
* <br/>
35+
* This implementation is based on the original Box2DTest (from cocos2d-iphone) but using the JBox2D
36+
* library and adjusting for differences with the new API as well as some differences in sensitivity
37+
* (and such) that were observed when testing on the Android platform.
38+
*
39+
* @author Ray Cardillo
40+
*/
41+
public class JBox2DTest extends Activity {
42+
private static final String LOG_TAG = JBox2DTest.class.getSimpleName();
43+
44+
private CCGLSurfaceView mGLSurfaceView;
45+
46+
@Override
47+
protected void onCreate(Bundle savedInstanceState) {
48+
super.onCreate(savedInstanceState);
49+
requestWindowFeature(Window.FEATURE_NO_TITLE);
50+
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
51+
WindowManager.LayoutParams.FLAG_FULLSCREEN);
52+
53+
mGLSurfaceView = new CCGLSurfaceView(this);
54+
setContentView(mGLSurfaceView);
55+
}
56+
57+
@Override
58+
public void onStart() {
59+
super.onStart();
60+
61+
// attach the OpenGL view to a window
62+
Director.sharedDirector().attachInView(mGLSurfaceView);
63+
64+
// set landscape mode
65+
Director.sharedDirector().setLandscape(false);
66+
67+
// show FPS
68+
Director.sharedDirector().setDisplayFPS(true);
69+
70+
// frames per second
71+
Director.sharedDirector().setAnimationInterval(1.0f / 60.0f);
72+
73+
Scene scene = Scene.node();
74+
scene.addChild(new JBox2DTestLayer());
75+
76+
// Make the Scene active
77+
Director.sharedDirector().runWithScene(scene);
78+
}
79+
80+
@Override
81+
public void onPause() {
82+
super.onPause();
83+
84+
Director.sharedDirector().pause();
85+
}
86+
87+
@Override
88+
public void onResume() {
89+
super.onResume();
90+
91+
Director.sharedDirector().resume();
92+
}
93+
94+
@Override
95+
public void onDestroy() {
96+
super.onDestroy();
97+
98+
TextureManager.sharedTextureManager().removeAllTextures();
99+
}
100+
101+
static class JBox2DTestLayer extends Layer {
102+
public static final int kTagSpriteManager = 1;
103+
104+
// Pixel to meters ratio. Box2D uses meters as the unit for measurement.
105+
// This ratio defines how many pixels correspond to 1 Box2D "meter"
106+
// Box2D is optimized for objects of 1x1 meter therefore it makes sense
107+
// to define the ratio so that your most common object type is 1x1 meter.
108+
protected static final float PTM_RATIO = 32.0f;
109+
110+
// Simulation space should be larger than window per Box2D recommendation.
111+
protected static final float BUFFER = 1.0f;
112+
113+
protected final World bxWorld;
114+
115+
public JBox2DTestLayer() {
116+
this.isTouchEnabled_ = true;
117+
this.isAccelerometerEnabled_ = true;
118+
119+
CCSize s = Director.sharedDirector().winSize();
120+
float scaledWidth = s.width/PTM_RATIO;
121+
float scaledHeight = s.height/PTM_RATIO;
122+
123+
Vec2 lower = new Vec2(-BUFFER, -BUFFER);
124+
Vec2 upper = new Vec2(scaledWidth+BUFFER, scaledHeight+BUFFER);
125+
Vec2 gravity = new Vec2(0.0f, -10.0f);
126+
127+
bxWorld = new World(new AABB(lower, upper), gravity, true);
128+
bxWorld.setContinuousPhysics(true);
129+
bxWorld.setPositionCorrection(true);
130+
131+
// TODO: JBox2D debug drawing is a bit different now. We could add debug drawing the old way, but looks like that is going away soon.
132+
/*
133+
GLESDebugDraw debugDraw = new GLESDebugDraw( PTM_RATIO );
134+
bxWorld.setDebugDraw(debugDraw);
135+
136+
int flags = 0;
137+
flags |= DebugDraw.e_shapeBit;
138+
flags |= DebugDraw.e_jointBit;
139+
flags |= DebugDraw.e_aabbBit;
140+
flags |= DebugDraw.e_pairBit;
141+
flags |= DebugDraw.e_centerOfMassBit;
142+
debugDraw.setFlags(flags);
143+
*/
144+
145+
BodyDef bxGroundBodyDef = new BodyDef();
146+
bxGroundBodyDef.position.set(0.0f, 0.0f);
147+
148+
Body bxGroundBody = bxWorld.createBody(bxGroundBodyDef);
149+
150+
EdgeChainDef bxGroundOutsideEdgeDef = new EdgeChainDef();
151+
bxGroundOutsideEdgeDef.addVertex(new Vec2(0f,0f));
152+
bxGroundOutsideEdgeDef.addVertex(new Vec2(0f,scaledHeight));
153+
bxGroundOutsideEdgeDef.addVertex(new Vec2(scaledWidth,scaledHeight));
154+
bxGroundOutsideEdgeDef.addVertex(new Vec2(scaledWidth,0f));
155+
bxGroundOutsideEdgeDef.addVertex(new Vec2(0f,0f));
156+
bxGroundBody.createShape(bxGroundOutsideEdgeDef);
157+
158+
AtlasSpriteManager mgr = new AtlasSpriteManager("blocks.png", 150);
159+
addChild(mgr, 0, kTagSpriteManager);
160+
161+
addNewSpriteWithCoords(CCPoint.ccp(s.width / 2.0f, s.height / 2.0f));
162+
163+
Label label = Label.label("Tap screen", "DroidSans", 32);
164+
label.setPosition(s.width / 2f, s.height - 50f);
165+
label.setColor(new CCColor3B(0, 0, 255));
166+
addChild(label);
167+
168+
// schedule the physics update processor
169+
this.schedule("tick");
170+
}
171+
172+
private void addNewSpriteWithCoords(CCPoint pos) {
173+
AtlasSpriteManager mgr = (AtlasSpriteManager) getChild(kTagSpriteManager);
174+
175+
// We have a 64x64 sprite sheet with 4 different 32x32 images. The following code is
176+
// just randomly picking one of the images
177+
int idx = (CCMacros.CCRANDOM_0_1() > 0.5f ? 0:1);
178+
int idy = (CCMacros.CCRANDOM_0_1() > 0.5f ? 0:1);
179+
AtlasSprite sprite = AtlasSprite.sprite(CCRect.make(idx * 32f, idy * 32f, 32f, 32f), mgr);
180+
mgr.addChild(sprite);
181+
182+
sprite.setPosition(pos.x, pos.y);
183+
184+
// Define the dynamic body.
185+
// Set up a 1m squared box in the physics world
186+
BodyDef bxSpriteBodyDef = new BodyDef();
187+
bxSpriteBodyDef.userData = sprite;
188+
bxSpriteBodyDef.position.set(pos.x/PTM_RATIO, pos.y/PTM_RATIO);
189+
bxSpriteBodyDef.linearDamping = 0.3f;
190+
191+
// Define another box shape for our dynamic body.
192+
PolygonDef bxSpritePolygonDef = new PolygonDef();
193+
bxSpritePolygonDef.setAsBox(0.5f, 0.5f);
194+
bxSpritePolygonDef.density = 1.0f;
195+
bxSpritePolygonDef.friction = 0.3f;
196+
197+
synchronized(bxWorld) {
198+
Body bxSpriteBody = bxWorld.createBody(bxSpriteBodyDef);
199+
200+
// Define the dynamic body fixture and set mass so it's dynamic.
201+
bxSpriteBody.createShape(bxSpritePolygonDef);
202+
bxSpriteBody.setMassFromShapes();
203+
}
204+
}
205+
206+
public void tick(float delta) {
207+
// It is recommended that a fixed time step is used with Box2D for stability
208+
// of the simulation, however, we are using a variable time step here.
209+
// You need to make an informed choice, the following URL is useful
210+
// http://gafferongames.com/game-physics/fix-your-timestep/
211+
212+
// Instruct the world to perform a simulation step. It is
213+
// generally best to keep the time step and iterations fixed.
214+
synchronized(bxWorld) {
215+
bxWorld.step(delta, 10);
216+
}
217+
218+
// Iterate over the bodies in the physics world
219+
for (Body b = bxWorld.getBodyList(); b != null; b = b.getNext()) {
220+
Object userData = b.getUserData();
221+
222+
if (userData != null && userData instanceof AtlasSprite) {
223+
// Synchronize the AtlasSprite position and rotation with the corresponding body
224+
AtlasSprite sprite = (AtlasSprite)userData;
225+
sprite.setPosition(b.getPosition().x * PTM_RATIO, b.getPosition().y * PTM_RATIO);
226+
sprite.setRotation(-1.0f * CCMacros.CC_RADIANS_TO_DEGREES(b.getAngle()));
227+
}
228+
}
229+
}
230+
231+
@Override
232+
public boolean ccTouchesBegan(MotionEvent event) {
233+
CCPoint location = Director.sharedDirector().convertCoordinate(event.getX(), event.getY());
234+
235+
addNewSpriteWithCoords(location);
236+
237+
return TouchDispatcher.kEventHandled;
238+
}
239+
240+
@Override
241+
public void ccAccelerometerChanged(float accelX, float accelY, float accelZ) {
242+
// no filtering being done in this demo (just magnify the gravity a bit)
243+
Vec2 gravity = new Vec2( accelX * -2.00f, accelY * -2.00f );
244+
bxWorld.setGravity( gravity );
245+
}
246+
}
247+
}

0 commit comments

Comments
 (0)