ios - Stoping the movement of a sprite- Box2D (cocos2d) -
i in process of making game , need object move when buttons pressed. have method begins movement, , far ending movement of object having destroying body of object. problem have can't move object again since program crash. i'm wondering if there way recreate body once destroyed since current method of checking if body still exists isn't working.
here code.
nsmutablearray *spaceobjectsarray; #pragma mark - helloworldlayer @interface helloworldlayer() -(void) initphysics; -(void) addnewspriteatposition:(cgpoint)p; -(void) createmenu; @end @implementation helloworldlayer +(ccscene *) scene { // 'scene' autorelease object. ccscene *scene = [ccscene node]; // 'layer' autorelease object. helloworldlayer *layer = [helloworldlayer node]; // add layer child scene [scene addchild: layer]; // return scene return scene; } -(void)gamelogic:(cctime)delta { [self addspaceobjects]; } -(void) addspaceobjects { _spaceobject = [ccsprite spritewithfile:@"bluedot.jpg"]; //create spaceobject body b2bodydef spaceobjectbbodydef; spaceobjectbbodydef.type=b2_dynamicbody; spaceobjectbbodydef.userdata = _spaceobject; //make location of spaceobject cgsize winsize = [ccdirector shareddirector].winsize; int minx= _spaceobject.contentsize.width/2; int maxx = winsize.width - _spaceobject.contentsize.width/2; int rangex = maxx - minx; int actualx = (arc4random() % rangex) + minx; _spaceobject.position = ccp(actualx, winsize.height + _ship.contentsize.height); spaceobjectbbodydef.position.set(actualx/ptm_ratio, (winsize.height+_ship.contentsize.height)/ptm_ratio); _spaceobjectbody= _world->createbody(&spaceobjectbbodydef); //create spaceobject shape b2polygonshape spaceobjectshape; spaceobjectshape.setasbox(_spaceobject.contentsize.width/ptm_ratio/2, _spaceobject.contentsize.height/ptm_ratio/2); //create spaceobject fixture b2fixturedef spaceobjectshapedef; spaceobjectshapedef.shape= &spaceobjectshape; spaceobjectshapedef.density = 2; spaceobjectshapedef.restitution =0; spaceobjectshapedef.friction=0; _spaceobjectfixture = _spaceobjectbody->createfixture(&spaceobjectshapedef); [self addchild:_spaceobject]; _spaceobject.tag=1; [spaceobjectsarray addobject:_spaceobject]; //aply force on object int randomvalue = ((arc4random() % 5) *-1); b2vec2 force = b2vec2(0,randomvalue); _spaceobjectbody ->applylinearimpulse(force, _spaceobjectbody->getposition()); } init method contains body creations , definitions
-(id) init { if( (self=[super init])) { cgsize s = [ccdirector shareddirector].winsize; //create spaceship sprite , add layer _ship = [ccsprite spritewithfile:@"theship.gif" ]; _ship.position = ccp(s.width/2, 1.25*_ship.contentsize.height); [self addchild:_ship]; //create world b2vec2 gravity = b2vec2_zero; _world = new b2world(gravity); //create ship body b2bodydef shipbodydef; shipbodydef.type = b2_dynamicbody; shipbodydef.position.set((s.width/2)/ptm_ratio, (1.25*_ship.contentsize.height)/ptm_ratio); shipbodydef.userdata = _ship; if(_shipbody == null){ _shipbody =_world->createbody(&shipbodydef); } //create ship shape b2polygonshape shipshape; shipshape.setasbox(_ship.contentsize.width/ptm_ratio/2, _ship.contentsize.height/ptm_ratio/2); //create ship definition , add body b2fixturedef shipshapedef; shipshapedef.shape = &shipshape; shipshapedef.density = 3; shipshapedef.friction =0; shipshapedef.restitution =0; _shipfixture = _shipbody->createfixture(&shipshapedef); //make paddles //bottom left 1 _paddle1 = [ccsprite spritewithfile:@"spritepaddle.jpeg"]; int bottomofscreenx = 0 + _paddle1.contentsize.width/2; int bottomofscreeny = 0+_paddle1.contentsize.height/2; _paddle1.position = ccp(bottomofscreenx,bottomofscreeny); [self addchild:_paddle1]; //bottom right 1 _paddle2 = [ccsprite spritewithfile:@"spritepaddle.jpeg"]; int bottomrightofscreenx = s.width - _paddle2.contentsize.width/2; _paddle2.position = ccp(bottomrightofscreenx, bottomofscreeny); [self addchild:_paddle2]; //continuously spawn spaceobjects [self schedule:@selector(gamelogic:) interval:1]; // enable events self.touchenabled = yes; // init physics [self schedule:@selector(tick:)]; } return self; } -(void)tick:(cctime) delta {//this method simulate physics , test position of objects should if force has been applied them _world->step(delta, 8, 8); (b2body *b=_world->getbodylist(); b; b=b->getnext()){ if (b->getuserdata() != null){ ccsprite *shipdata = (ccsprite *)b->getuserdata(); shipdata.position = ccp(b->getposition().x *ptm_ratio, b->getposition().y *ptm_ratio); } } } the paddles move ship touched logic
-(void)cctouchesbegan:(nsset *)touches withevent:(uievent *)event { //set way touches turned locations onscreen nsset *alltouches = [event alltouches]; uitouch *touch = [alltouches anyobject]; cgpoint location = [touch locationinview:[touch view]]; location = [[ccdirector shareddirector] converttogl:location ]; //check see if left paddle being pressed if (cgrectcontainspoint([_paddle1 boundingbox], location)){ b2vec2 force = b2vec2(-5,0); _shipbody->applylinearimpulse(force, _shipbody ->getposition()); } if (cgrectcontainspoint([_paddle2 boundingbox], location)){ b2vec2 force = b2vec2(5,0); _shipbody->applylinearimpulse(force, _shipbody->getposition()); } } the paddle box no longer being touched logic
-(void)cctouchesended:(nsset *)touches withevent:(uievent *)event { _world->destroybody(_shipbody); } -(void) dealloc { delete _world; _world = null; [super dealloc]; } @end
destroying body end movement of not best solution. should remove body if don't want part of simulation more.
there several options stopping body's movement:
1 - set linear velocity 0. bring immediate stop. if else pushing on (e.g. contact wit body), have decide do.
body->setlinearvelocity(b2vec2(0,0))); 2 - set linear/angular damping 0. dissipate momentum has stop. factor use should greater 0. body come halt more larger values and resistant movement other bodies (if bump it, slow down , stop again). remember turn linear/angular damping 0 when want body start moving.
body->setlineardamping(0.2); body->setangulardamping(0.2); 3 - give target position seek , set position place want be. feedback control loop applying force move towards want body stay. can used make body follow paths, etc. code below part of larger code base (you can see here), should able general idea. function applies thrust object pushes towards target.
void movingentity::applythrust() { // distance target. b2vec2 totarget = gettargetpos() - getbody()->getworldcenter(); totarget.normalize(); b2vec2 desiredvel = getmaxspeed()*totarget; b2vec2 currentvel = getbody()->getlinearvelocity(); b2vec2 thrust = getmaxlinearacceleration()*(desiredvel - currentvel); getbody()->applyforcetocenter(thrust); }
Comments
Post a Comment