Forward, please stay at address: http://blog.csdn.net/stalendp/article/details/8757660
In the previous article, I introduced cocosbuilder's simple integration. This article describes how to use cocosbuilder to develop physics games.
The robot model first introduces the combined robot model. For example, if a robot combines 10 images, we must first correct the positions of various images in cocosbuilder, then read the positions among images in the code, and create the corresponding body, then, use revolute joint to join a whole. Create a CCB named robot in cocosbuilder and combine the following conditions: Adjust the anchor (except chest) of each module. These anchor points will be read by the program and used as the joint point. Then export the CCBI file. Import robot in xcode. CCBI, and then create a robot class that inherits from the ccbbase class (see [cocos2dx development skills 2] cocosbuilder usage-integration in the previous article). Override the onassignccbmembervariable method as follows:
bool onAssignCCBMemberVariable(cocos2d::CCObject * pTarget, const char * pMemberVariableName, cocos2d::CCNode * pNode) { CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "head", CCSprite *, this->head); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "chess", CCSprite *, this->chess); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "leftArm", CCSprite *, this->leftArm); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "leftHand", CCSprite *, this->leftHand); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "leftLeg", CCSprite *, this->leftLeg); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "leftFoot", CCSprite *, this->leftFoot); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "rightArm", CCSprite *, this->rightArm); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "rightHand", CCSprite *, this->rightHand); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "rightLeg", CCSprite *, this->rightLeg); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "rightFoot", CCSprite *, this->rightFoot); return NULL; }
The onnodeloaded override method is as follows:
Void onnodeloaded (cocos2d: ccnode * pnode, cocos2d: Extension: ccnodeloader * pnodeloader) {Pipeline * robot = pipeline: createwithtexture (Head-> gettexture ()); // spritebatchnode will be used here to improve performance addchild (robot); myphysicssprite: attach (robot, head); myphysicssprite: attach (robot, chess); myphysicssprite :: attach (robot, leftarm); myphysicssprite: attach (robot, lefthand); myphysicssprite: attach (robot, leftleg); Role: attach (robot, LeftFoot); Role :: attach (robot, rightarm); myphysicssprite: attach (robot, righthand); credential: attach (robot, rightleg); myphysicssprite: attach (robot, rightfoot ); createjoin (chess, head, head-> getanchorpoint (); createjoin (chess, leftarm, leftarm-> getanchorpoint (); createjoin (leftarm, lefthand, lefthand-> Merge (); createjoin (chess, rightarm, rightarm-> getanchorpoint (); createjoin (chess, leftleg, leftleg-> getanchorpoint (); createjoin (chess, rightleg, rightleg-> aggregate (); createjoin (rightarm, righthand, righthand-> aggregate (); createjoin (leftleg, LeftFoot, LeftFoot-> getanchorpoint ()); createjoin (rightleg, rightfoot, rightfoot-> getanchorpoint ());}
The code for creating a join statement is as follows:
void createJoin(CCSprite* a, CCSprite* b, CCPoint anchor) { b2RevoluteJointDef rjd; rjd.maxMotorTorque = 50.0f; rjd.enableMotor = false; rjd.collideConnected=false; rjd.motorSpeed= 20*DEGTORAD; rjd.Initialize(((MyPhysicsSprite*)a)->getBody(), ((MyPhysicsSprite*)b)->getBody(), ((MyPhysicsSprite*)b)->getBody()->GetPosition()); MyWorld::getWorld()->CreateJoint(&rjd); }
The scenario is created here to create a robot venue. Create a CCB file. The layout scenario is as follows: Export CCBI, import CCBI to xcode, and create a playground class. The associated attributes are as follows:
virtual bool onAssignCCBMemberVariable(cocos2d::CCObject * pTarget, const char * pMemberVariableName, cocos2d::CCNode * pNode) { CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "apple", CCSprite *, this->apple); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "ground", CCSprite *, this->ground); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "wleft", CCSprite *, this->wleft); CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "wright", CCSprite *, this->wright); return false; }
Create a box2d object:
virtual void onNodeLoaded(cocos2d::CCNode * pNode, cocos2d::extension::CCNodeLoader * pNodeLoader) { GB2ShapeCache::sharedGB2ShapeCache()->addShapesWithFile("apple_pe.plist"); MyWorld::init(); MyPhysicsSprite::attach(this, apple, false, "apple"); MyPhysicsSprite::attach(this, ground, true); MyPhysicsSprite::attach(this, wleft, true); MyPhysicsSprite::attach(this, wright, true); scheduleUpdate(); robot = (Robot*)RobotLoader::loadCcbi(); addChild(robot); CCSize size = CCDirector::sharedDirector()->getVisibleSize(); robot->setPhysicPos(ccp(size.width/2, size.height/2)); //robot->setPosition(ccp(size.width/2, size.height/2)); }
The next step is to implement the play button function. In response to the play button clicking, apply an upward impluse to the chess of Apple and robot to make them move. Select the play button in cocosbuilder, name selector onplay in ccmenuitem on the right, and select target as document root. The following code is implemented in the playground class:
virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, const char * pSelectorName) { CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "onPlay", Playground::btnPlay); return NULL; }
Btnplay:
Void btnplay (cocos2d: ccobject * psender) {// apply an upward 30 impulse b2body * Body = dynamic_cast <myphysicssprite *> (Apple) -> getbody (); Body-> applylinearimpulse (b2vec2 (0, 30), body-> getworldcenter (); // apply b2vec2 () to the chess of the robot) impulse b2body * BB = (myphysicssprite *) robot-> chess)-> getbody (); bb-> applylinearimpulse (b2vec2 (10, 20 ), b2vec2 (bb-> getworldcenter (). X + 0.5, BB-> getworldcenter (). Y ));}
OK. Now box2d is integrated. For the effect, refer to [cocos2dx development skills 1] tool cocosbuilder usage-demo introduction. Additional code is provided: This myphysicssprite can use the ccphysicssprite class.
# Ifndef shoottheapple_physicssprite_h # define shoottheapple_physicssprite_h # include "cocos2d. H "# include" cocos-ext.h "# include" box2d. H "# include" myworld. H "# include" GB2ShapeCache-x.h "# define ptm_ratio 32using_ns_cc; counter; # define degtorad counter # define radtodeg 57.295779513082320876 fclass myphysicssprite: Public cocos2d: ccsprite {PRIVATE: b2body * m_pbody; // strong ref Publ IC: static myphysicssprite * attach (ccnode * parent, ccsprite * & Sprite, bool isstatic = false, const char * pename = NULL) {myphysicssprite * pobsprite = new myphysicssprite (sprite, isstatic, pename); ccspriteframe * pspriteframe = sprite-> displayframe (); ccpoint anchor = sprite-> getanchorpoint (); If (scheme & pobsprite-> Scheme (pspriteframe )) {pobsprite-> autorelease (); Parent-> addchild (pobsprite); cocos2d: cclog (cocos2d: ccstring: createwithformat ("anchor <%. 2f, %. 2f> ", anchor. x, anchor. y)-> getcstring (); sprite-> autorelease (); // No need anymore sprite-> setvisible (false); sprite = pobsprite; sprite-> setanchorpoint (Anchor); Return pobsprite;} cc_safe_delete (pobsprite); return NULL;} b2body * getbody () {return m_pbody;} myphysicssprite (ccsprite * Sprite, bool Static, const char * pename): m_pbody (null) {Init (sprite, isstatic, pename);} virtual void Init (ccsprite * Sprite, bool isstatic, const char * pename) {b2world * World = myworld: getworld (); b2body * Body = NULL; ccpoint P = sprite-> getposition (); ccsize size = sprite-> getcontentsize (); ccpoint anchor = sprite-> getanchorpoint (); float angle =-Sprite-> getrotation () * degtorad; b2bodydef bodydef; bodyd Ef. type = isstatic? B2_staticbody: b2_dynamicbody; bodydef. position. set (P. x/ptm_ratio, P. y/ptm_ratio); bodydef. angle = angle; body = World-> createbody (& bodydef); // If (pename! = NULL) {// gb2shapecache * SC = gb2shapecache: sharedgb2shapecache (); // SC-> addfixturestobody (body, pename ); // setanchorpoint (SC-> anchorpointforshape (pename); //} else {// define another box shape for our dynamic body. b2polygonshape dynamicbox; b2vec2 Center (0.5-anchor. x) * size. width/ptm_ratio, (0.5-anchor. y) * size. height/ptm_ratio); dynamicbox. setasbox (size. width/ptm_ratio/2, size. height/ptm_ra Tio/2, center, 0); // These are mid points for our 1 m box // define the dynamic body fixture. b2fixturedef fixturedef; fixturedef. shape = & dynamicbox; fixturedef. density = 1.0f; fixturedef. friction = 0.1f; // fixturedef. restitution = 0.5f; body-> createfixture (& fixturedef); //} This-> m_pbody = body;} virtual bool isdirty (void) {return m_pbody! = NULL & m_pbody-> isawake (); // update the display only when the object is in motion} void setphysicpos (ccpoint POS) {m_pbody-> settransform (b2vec2 (POS. x/ptm_ratio, POS. y/ptm_ratio), 0);} void physicstrans (ccpoint POS) {If (m_pbody = NULL) return; b2vec2 cur = m_pbody-> getposition (); m_pbody-> settransform (b2vec2 (cur. X + POS. x/ptm_ratio, cur. Y + POS. y/ptm_ratio), 0);} virtual cocos2d: ccaffinetransform nodetoparenttransform (void ){ B2vec2 Pos = m_pbody-> getposition (); float x = POS. x * ptm_ratio; float y = POS. y * ptm_ratio; If (isignoreanchorpointforposition () {x + = m_obanchorpointinpoints.x; y + = bytes;} // make matrix float radians = m_pbody-> getangle (); float c = cosf (radians); float S = sinf (radians); If (! Centers (ccpointzero) {x + = C *-m_obanchorpointinpoints.x +-S *-percent; y + = S *-m_obanchorpointinpoints.x + C *-m_obanchorpointinpoints.y;} // rot, translate matrix m_stransform = ccaffinetransformmake (C, S,-S, C, x, y); Return m_stransform ;}; # endif
#ifndef ShootTheApple_MyWorld_h#define ShootTheApple_MyWorld_h#include "Box2D.h"#define VELOCITY_ITER 8#define POSITION_ITER 1class MyWorld {private: static b2World* world;public: static void init() { if (world!=NULL) { return; } b2Vec2 gravity; gravity.Set(0.0f, -10.0f); world = new b2World(gravity); // Do we want to let bodies sleep? world->SetAllowSleeping(true); world->SetContinuousPhysics(true); } static b2World* getWorld() { if(world==NULL) { init(); } return world; } static void update(float dt) { getWorld()->Step(dt, VELOCITY_ITER, POSITION_ITER); }};b2World* MyWorld::world=NULL;#endif