cocos2d x - Box2d body generation dynamically in cocos2dx using c++ in Xcode -


i new developer in cocos2dx.i developing game in using box2d bodies loading through physics editor.there more 20 bodies using in level of game,that making separate body separate sprite attached them , similar bodies used in other levels , there 50 levels in game , each level,i have made separate class , again making b2body loading function,all code working want make generic function loading bodies in class can use same b2body loading function in levels.also have destroy particular body , sprite on touching sprite

//sprites: rect_sprite1=ccsprite::create("rect1.png"); rect_sprite1->setscalex(rx); rect_sprite1->setscaley(ry); this->addchild(rect_sprite1,1);  rect_sprite2=ccsprite::create("rect2.png"); rect_sprite2->setscalex(rx); rect_sprite2->setscaley(ry); this->addchild(rect_sprite2,1);  rect_sprite3=ccsprite::create("circle.png"); rect_sprite3->setscale(rz); this->addchild(rect_sprite3,1);  gb2shapecache::sharedgb2shapecache()->addshapeswithfile("obs.plist");  //body loading function  void level1::addnewspritewithcoords() { ccsize winsize = ccdirector::shareddirector()->getwinsize(); b2bodydef bodydef1; bodydef1.type=b2_dynamicbody; bodydef1.position.set((winsize.width*0.38)/ptm_ratio,(winsize.height*0.4) /ptm_ratio); bodydef1.userdata = rect_sprite1; body1 = (myphysicsbody*)world->createbody(&bodydef1); body1->settypeflag(7); // add fixture definitions body gb2shapecache *sc1 = gb2shapecache::sharedgb2shapecache(); sc1->addfixturestobody(body1,"rect1", rect_sprite1); rect_sprite1->setanchorpoint(sc1->anchorpointforshape("rect1"));  b2bodydef bodydef2; bodydef2.type=b2_dynamicbody; bodydef2.position.set((winsize.width*0.62)/ptm_ratio,   (winsize.height*0.4)/ptm_ratio); bodydef2.userdata = rect_sprite2; body2 = (myphysicsbody*)world->createbody(&bodydef2); body2->settypeflag(7); // add fixture definitions body gb2shapecache *sc2 = gb2shapecache::sharedgb2shapecache(); sc2->addfixturestobody(body2,"rect2", rect_sprite2); rect_sprite2->setanchorpoint(sc2->anchorpointforshape("rect2"));  b2bodydef bodydef3; bodydef3.type=b2_dynamicbody; bodydef3.position.set((winsize.width*0.5)/ptm_ratio, (winsize.height*0.23)/ptm_ratio); bodydef3.userdata = rect_sprite3; body3 = (myphysicsbody*)world->createbody(&bodydef3); body3->settypeflag(7); // add fixture definitions body gb2shapecache *sc3 = gb2shapecache::sharedgb2shapecache(); sc3->addfixturestobody(body3,"circle", rect_sprite3); rect_sprite3->setanchorpoint(sc3->anchorpointforshape("circle")); } void level1::cctouchesbegan(cocos2d::ccset* touches, cocos2d::ccevent* event) {  if(box->containspoint(touchpoint))                 {                     this->removechild(((ccsprite*)rect),true);                     if(((ccsprite*)rect)==rect_sprite1)                     {                         rect_sprite1=null;                         world->destroybody(body1);                         utils::setcount(utils::getcount()-1);                      }                     if(((ccsprite*)rect)==rect_sprite2)                     {                         rect_sprite2=null;                         world->destroybody(body2);                         utils::setcount(utils::getcount()-1);                     }                       if(((ccsprite*)rect)==rect_sprite3)                     {                         rect_sprite3=null;                         world->destroybody(body3);                         utils::setcount(utils::getcount()-1);                      }  }  

similarly doing other levels. if know it,please suggest.thanks

this seems more "what design pattern should use?" specific problem loading code.

in general, when want create "entities" require physical body, use base class contains box2d body 1 of members. base class container body (which assigned it) , responsible destroying body (removing box2d world) when entity destroyed.

derived classes can load body box2d shape cache. best shown through example. there game working on have swarm of different shaped asteroids circling sun. here screen shot:

enter image description here

the base class, entity, contains body , destroys when entity destroyed:

class entity : public hasflags { public:     enum    {       default_entity_id = -1,    }; private:    uint32 _id;    // every entity has 1 "main" body    // controls in way.  or not.    b2body* _body;    // every entity has scale size 1 100.    // maps on meters size of 0.1 10    // in physics engine.    uint32 _scale;  protected:    void setscale(uint32 value)    {       assert(value >= 1);       assert(value <= 100);       _scale = value;    }  public:     void setbody(b2body* body)    {       assert(_body == null);       if(_body != null)       {          cclog("body should null before assigning");          _body->getworld()->destroybody(_body);          _body = null;       }       _body = body;       if(body != null)       {          _body->setuserdata(this);          (b2fixture* f = _body->getfixturelist(); f; f = f->getnext())          {             f->setuserdata(this);          }       }    }       inline void setid(uint32 id)    {       _id = id;    }     inline uint32 getid() const    {       return _id;    }     virtual string tostring(bool updatedescription = false)    {       string descr = "id: ";       descr += _id;       descr += "flags: ";       if(isflagset(hf_is_graph_sensor))          descr += "is_flag_sensor ";       return descr;    }      entity() :    _id(default_entity_id),    _body(null),    _scale(1)    {    }     entity(uint32 flags, uint32 scale) :    hasflags(flags),    _id(default_entity_id),    _body(null),    _scale(scale)    {     }     virtual void update()    {     }     virtual void updatedisplay()    {     }     virtual ~entity()    {       if(_body != null)       {          _body->getworld()->destroybody(_body);       }    }     inline static float32 scaletometers(uint32 scale)    {       return 0.1*scale;    }     inline body* getbody()    {       return _body;    }     inline const body* getbody() const    {       return _body;    }     inline uint32 getscale()    {       return _scale;    }     inline float32 getsizemeters()    {       return scaletometers(_scale);    } }; 

the asteroid class responsible loading 1 of several different "asteroid" shapes shape cache. however, asteroids have common logic making them move center of screen. have rope joint attached , update(...) function adds "spin" them rotate around center:

 class asteroid : public entity     {     private:        b2fixture* _hull;        vec2 _anchor;        ccsprite* _sprite;        float32 _targetradius;     public:        // getters out.        b2fixture& gethullfixture() const { return *_hull; }        float32 gettargetradius() { return _targetradius; }        ccsprite* getsprite() { return _sprite; }          void updatedisplay()        {           // update sprite position , orientation.           ccpoint pixel = viewport::instance().convert(getbody()->getposition());           _sprite->setposition(pixel);           _sprite->setrotation(-cc_radians_to_degrees(getbody()->getangle()));        }         virtual void update()        {           body* body = getbody();            vec2 vradius = body->getposition();           vec2 vtangent = vradius.skew();            vtangent.normalize();           vradius.normalize();             // if not moving...give spin.           if(fabs(vtangent.dot(body->getlinearvelocity())) < 1)           {              body->setlineardamping(0.001);              body->applyforcetocenter(body->getmass()*1.5*vtangent);              body->applyforce(vradius,body->getmass()*0.05*vradius);           }           else           {              body->setlineardamping(0.05);           }        }         ~asteroid()        {         }         asteroid() :        entity(hf_can_move | hf_update_prio_5,50)        {         }         bool create(b2world& world, const string& shapename,const vec2& position, float32 targetradius)        {           _targetradius = targetradius;           _anchor = position;            string str = shapename;           str += ".png";           _sprite = ccsprite::createwithspriteframename(str.c_str());           _sprite->settag((int)this);           _sprite->setanchorpoint(ccp(0.5,0.5));            //      _sprite->setvisible(false);            b2bodydef bodydef;           bodydef.position = position;           bodydef.type = b2_dynamicbody;           body* body = world.createbody(&bodydef);           assert(body != null);            // add polygons body.           box2dshapecache::instance().addfixturestobody(body, shapename, getsizemeters());            setbody(body);                 return true;        }      }; 

the create(...) function asteroid called loading code in scene, .csv file shape names in it. reuses names several times (there 10 asteroid shapes).

you notice asteroid has ccsprite associated it. not entities have sprite, do. have created entity-derived class (entitywithsprite) case sprite managed well, try avoid many nested classes. have put base class, , may still. regardless, asteroids contain own sprites , load them spritecache. updated in different part of code (not relevant here, happy answer questions if curious).

note: part of larger code base , there features zooming, cameras, graph/path finding, , lots of other goodies in code base. feel free use find useful.

you can find (ios) code on github , there videos , tutorials posted on site here.


Comments

Popular posts from this blog

user interface - How to replace the Python logo in a Tkinter-based Python GUI app? -

objective c - Greedy NSProgressIndicator Allocation -

how to set an OCR language in Google Drive -