Cocos2D-Android-1 source code explanation: 5. Box2dTest
Package org. cocos2d. tests; import java. util. iterator; import org. cocos2d. actions. updateCallback; import org. cocos2d. config. ccMacros; import org. cocos2d. events. CCTouchDispatcher; import org. cocos2d. layers. CCLayer; import org. cocos2d. layers. CCScene; import org. cocos2d. nodes. CCDirector; import org. cocos2d. nodes. CCLabel; import org. cocos2d. nodes. CCSprite; import org. cocos2d. nodes. CCSpriteSheet; import org. cocos2d. opengl. CCGLSurfaceView; import org. cocos2d. types. CGPoint; import org. cocos2d. types. CGRect; import org. cocos2d. types. CGSize; import org. cocos2d. types. ccColor3B; import android. app. activity; import android. OS. bundle; import android. view. motionEvent; import android. view. window; import android. view. windowManager; import com. badlogic. gdx. math. vector2; import com. badlogic. gdx. physics. box2d. body; import com. badlogic. gdx. physics. box2d. bodyDef; import com. badlogic. gdx. physics. box2d. bodyDef. bodyType; import com. badlogic. gdx. physics. box2d. edgeShape; import com. badlogic. gdx. physics. box2d. fixtureDef; import com. badlogic. gdx. physics. box2d. polygonShape; import com. badlogic. gdx. physics. box2d. world;/*** A test that demonstrates basic JBox2D integration by using AtlasSprites connected to physics bodies. * <br/> * This implementation is based on the original Box2DTest (from cocos2d-iphone) but using the JBox2D * library and adjusting for differences with the new API as well as some differences in sensitivity * (and such) that were observed when testing on the Android platform. ** @ author Ray Cardillo * // Box2dTest, there is a downloadable demo here :// http://code.google.com/p/cocos2d-android-1/downloads/detail?name=cocos2d%20%20and%20jbox2d.3gp&can=2&q=#makechanges//public Class Box2dTest extends Activity {// physical box system // private static final String LOG_TAG = JBox2DTest. class. getSimpleName (); static {System. loadLibrary ("gdx"); // load a gdx library} private CCGLSurfaceView mGLSurfaceView; // create a view @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); requestWindowFeature (Window. FEATURE_NO_TITLE); // getWindow () without a title (). setFlags (WindowManager. layoutParams. FLAG_FULLSCREEN, WindowManager. layoutParams. FLAG_FULLSCREEN); // full screen getWindow (). setFlags (WindowManager. layoutParams. FLAG_KEEP_SCREEN_ON, WindowManager. layoutParams. FLAG_KEEP_SCREEN_ON); // non-black screen mGLSurfaceView = new CCGLSurfaceView (this); // generate a view and associate the context with the director CCDirector ctor = CCDirector. sharedDirector (); // The generated director (unique) director. attachInView (mGLSurfaceView); // submit the view to the director's listdirector. setDeviceOrientation (CCDirector. kCCDeviceOrientationLandscapeLeft); // setContentView (mGLSurfaceView); // map the view to the knife screen // show FPS CCDirector ctor. shareddire (). setDisplayFPS (true); // display frame frequency // frames per second CCDirector. shareddire (). setAnimationInterval (1.0f/60366f); // specifies the frame rate. node (); // get a scenario scene. addChild (new Box2DTestLayer (); // Add a box layer to the Scene. // Make the Scene active CCDirector. shareddire (). runWithScene (scene); // Let the Director run the scenario and run it to the view just now.} @ Override public void onStart () {// start method super. onStart () ;}@ Override public void onPause () {// pause method super. onPause (); CCDirector. shareddire (). onPause () ;}@ Override public void onResume () {super. onResume (); CCDirector. shareddire (). onResume () ;}@ Override public void onDestroy () {// destroy method super. onDestroy (); CCDirector. shareddire (). end (); // CCTextureCache. sharedTextureCache (). removeAllTextures ();} // Demo of calling integrating Box2D physics engine with cocos2d sprites // a cocos2d example // http://code.google.com/p/cocos2d-iphone //// By Steve Oldmeadow // static class Box2DTestLayer extends CCLayer {// The method generated by this method is public static final int kTagTileMap = 1; public static final int kTagSpriteManager = 1; public static final int kTagAnimation1 = 1; // Pixel to meters ratio. box2D uses meters as the unit for measurement. // This ratio defines how does pixels correspond to 1 Box2D "meter" // Box2D is optimized for objects of 1x1 me Ter therefore it makes sense // to define the ratio so that your most common object type is 1x1 meter. protected static final float PTM_RATIO = 32.0f; // Simulation space shocould be larger than window per Box2D recommendation. protected static final float BUFFER = 1.0f; // FPS for the PhysicsWorld to sync to protected static final float FPS = (float) CCDirector. shareddire (). getAnimationInterval (); // Obtain the frame frequency of the entire animation. private static float rdelta = 0; protected final World bxWorld; // generate a reference of the World .. public Box2DTestLayer () {// constructor super (); this. setIsTouchEnabled (true); // you can click this. setIsAccelerometerEnabled (true); // enable set acceleration. The acceleration controller can start CGSize s = CCDirector ctor. shareddire (). winSize (); // obtain the screen size reference // Define the gravity vector. vector2 gravity = new Vector2 (9.8f,-9.8f); // defines a two-dimensional vector float scaledWidth = s. width/PTM _ RATIO; // float scaledHeight = s. height/PTM_RATIO; // zoom height // Vector2 lower = new Vector2 (-BUFFER,-BUFFER); // smaller // Vector2 upper = new Vector2 (scaledWidth + BUFFER, scaledHeight + BUFFER); // larger bxWorld = new World (gravity, true); // create and set the gravity Vector bxWorld in this World. setContinuousPhysics (true); // continuous physical availability // Define the ground body. bodyDef bxGroundBodyDef = new BodyDef (); // defines the ground body bxGroundBodyDef. position. set (0.0f, 0.0f ); // Body position // Call the body factory which allocates memory for the ground body // from a pool and creates the ground box shape (also from a pool ). // The body is also added to the world. body groundBody = bxWorld. createBody (bxGroundBodyDef); // Add the body to the world // Define the ground box shape. edgeShape groundBox = new EdgeShape (); // define a shape Vector2 bottomLeft = new Vector2 (0f, 0f); // define four 2-Dimensional Vectors Vector2 topLeft = new Vector2 (0f, scaledHeight); Vector2 topRight = new Vector2 (scaledWidth, scaledHeight); Vector2 bottomRight = new Vector2 (scaledWidth, 0f); // bottom groundBox. set (bottomLeft, bottomRight); // sets a line groundBody. createFixture (groundBox, 0); // use this line as the boundary of the physical box // top groundBox. set (topLeft, topRight); // Similarly, groundBody. createFixture (groundBox, 0); // left groundBox. set (topLeft, bottomLeft); groundBody. createFi Xture (groundBox, 0); // right groundBox. set (topRight, bottomRight); groundBody. createFixture (groundBox, 0); // Set up sprite CCSpriteSheet mgr = CCSpriteSheet. spriteSheet ("blocks.png", 150); // create an image form to split the small part addChild (mgr, 0, kTagSpriteManager); // Add the form in the order of 0, set the label number to 1 addNewSpriteWithCoords (CGPoint. ccp (s. width/2.0f, s. height/2.0f); // The above is a method. The following explains the CCLabel label = CCLabel. makeLabel ("Tap screen", "Dr OidSans ", 32); // create a label. setPosition (CGPoint. make (s. width/2f, s. height-50f); // sets the coordinate label. setColor (new ccColor3B (0, 0,255); // sets the color addChild (label);} private UpdateCallback tickCallback = new UpdateCallback () {// return @ Overridepublic void update (float d) {// time update tick (d) ;};@ Overridepublic void onEnter () {super. onEnter (); // start ticking (for physics simulation) schedule (tickCallback);} @ O Verridepublic void onExit () {super. onExit (); // stop ticking (for physics simulation) unschedule (tickCallback);} private void Merge (CGPoint pos) {export sheet = (CCSpriteSheet) getChildByTag (kTagSpriteManager ); // obtain a table // We have a 64x64 sprite sheet with 4 different 32x32 images. the following code is // just randomly picking one of the images int idx = (ccMacros. CCRANDOM_0_1 ()>. 5? 0: 1); // defines a random number. Get 1/0 int idy = (ccMacros. CCRANDOM_0_1 ()>. 5? 0: 1); // CCSprite sprite = CCSprite. sprite ("blocks.png", CGRect. make (32 * idx, 32 * idy, 32, 32); // generate an genie. Use that image to extract the image at the specified formula. // this. addChild (sprite); // Add the genie CCSprite sprite = CCSprite. sprite (sheet, CGRect. make (32 * idx, 32 * idy, 32, 32); // generate the genie and use the gallery just now to capture a sheet. addChild (sprite); // Add a subclass sprite. setPosition (pos); // set the vertex // Define the dynamic body. // Set up a 1 m squared box in the physics world BodyDef bodyDef = new BodyDef (); // create a rigid body bodyDef. type = BodyType. dynamicBody; // set to type 3 dynamic rigid body bodyDef. position. set (pos. x/PTM_RATIO, pos. y/PTM_RATIO); // set the body position // Define another box shape for our dynamic body. polygonShape dynamicBox = new PolygonShape (); // create a polygon dynamicBox. setAsBox (. 5f ,. 5f); // These are mid points for our 1 m box // use the vertex 0.5, 0.5 // dynamicBox when serving as a box. density = 1.0f; // dynamicBox. friction = 0.3f; synchronized (bxWorld) {// thread lock // Define the dynamic body fixture and set mass so it's dynamic. body body = bxWorld. createBody (bodyDef); // create this rigid body in the world. setUserData (sprite); // use this data genie FixtureDef fixtureDef = new FixtureDef (); // fixed things fixtureDef. shape = dynamicBox; fixtureDef. density = 1.0f; // density fixtureDef. friction = 0.3f; // friction coefficient body. createFixture (fixtureDef); // give these fixed parameters to this object} public synchronized void tick (float delta) {// time class if (rdelta + = delta) <FPS) return; // do not calculate the frame speed .. // It is recommended that a fixed time step is used with Box2D for stability // of the simulation, however, we are using a variable time step here. // You need to make an informed choice, the following URL is useful // http://gafferongames.com/game-physics/fix-your-timestep/ // Instruct the world to perform a simulation step. it is // generally best to keep the time step and iterations fixed. synchronized (bxWorld) {bxWorld. step (FPS, 8, 1); // calculation speed} rdelta = 0; // accumulative time // Iterate over the bodies in the physics world Iterator <Body> it = bxWorld. getBodies (); // create an iterator to get the world's rigid body set while (it. hasNext () {Body B = it. next (); // get the rigid Object userData = B. getUserData (); // the data of the rigid body if (userD Ata! = Null & userData instanceof CCSprite) {// if the data is not empty, and it is a sprite instance and // Synchronize the Sprites position and rotation with the corresponding body final CCSprite sprite = (CCSprite) userData; // get this image final Vector2 pos = B. getPosition (); // get the vertex sprite of the rigid body. setPosition (pos. x * PTM_RATIO, pos. y * PTM_RATIO); // set the sprite. setRotation (-1.0f * ccMacros. CC_RADIANS_TO_DEGREES (B. getAngle (); // set radians }}@ Override public boolean ccTouchesBegan (MotionEvent event) {// CGPoint location = CCDirector. shareddire (). convertToGL (CGPoint. make (event. getX (), event. getY (); // get the vertex addNewSpriteWithCoords (location); // Add an item at that vertex return CCTouchDispatcher. kEventHandled; // return data} static float prevX = 0, prevY = 0; Vector2 gravity = new Vector2 (); // define a 2-dimensional array @ Override public void ccAccelerometerChanged (float accelX, float accelY, float accelZ) {// when the acceleration sensor feels it // # define kFilterFactor 0.05 ffloat kFilterFactor = 1.0f; // don't use filter. the code is here just as an examplefloat accX = (float) accelX * kFilterFactor + (1-kFilterFactor) * prevX; // float accY = (float) in the x direction) accelY * kFilterFactor + (1-kFilterFactor) * prevY; // In the y direction, prevX = accX; prevY = accY; // no filtering being done in this demo (just magnify the gravity a bit) gravity. set (accY * 9.8f, accX *-9.8f); // obtain the Gravity Vector bxWorld. setGravity (gravity); // set the gravity vector for the world }}}