W kokos2d można ułatwić pracę w CCSprites i przenosić je na różne sposoby. Co najważniejsze - mogą mieć wejście/wyjście. Dla większości gier jest to pożądane dla sprawnego przepływu itpPrzenoszenie obiektów Box2d Podobnie jak obiekty CCSprite
id action = [CCMoveTo actionWithDuration:dur position:pos];
move = [CCEaseInOut actionWithAction:action rate:2];
[self runAction: move];
przypadku przenoszenia box2d ciało, sprite dołączony do niego jest aktualizowana po box2d kroku(). Przesuwanie sprite'a, a następnie aktualizowanie ciała nie jest tutaj opcją, ponieważ całkowicie pokonuje cel ramy fizyki.
Inną opcją, którą z powodzeniem zaimplementowałem, jest obliczenie przemieszczenia, prędkości i przyspieszenia sprite'a poprzez potraktowanie go jako jednostki mechaniki. Za każdym razem, gdy wywołuję moją aktualizację() na ikonce, aby postać mogła zdecydować, gdzie przenieść itd., Moja superklasa również przechowuje poprzednią pozycję i prędkość. Są one przechowywane jako wartości zgodne z box2d, dzieląc je przez PTM_RATIO.
W podklasie CCSprite, zwany FMSprite:
-(CGPoint) displacement {
return ccpSub(self.position, lastPos);
}
-(b2Vec2) getSpriteVelocity:(ccTime)dt {
return b2Vec2(self.displacement.x/dt/PTM_RATIO,
self.displacement.y/dt/PTM_RATIO);
}
-(b2Vec2) getSpriteAccel:(ccTime)dt {
b2Vec2 currVel = [self getSpriteVelocity:dt];
if (dt == 0) {
return b2Vec2(0,0);
} else {
float accelX = (currVel.x - lastVel.x)/dt;
float accelY = (currVel.y - lastVel.y)/dt;
return b2Vec2(accelX, accelY);
}
}
// This is called each update()
-(void) updateLast:(ccTime)dt {
// MUST store lastVel before lastPos is updated since it uses displacement
lastVel = [self getSpriteVelocity:dt];
lastPos = ccp(self.X, self.Y);
}
// Leave this method untouched in subclasses
-(void) update:(ccTime)dt {
[self updateObject:dt];
// Store previous update values
[self updateLast:dt];
}
// Override this method in subclasses for custom functionality
-(void) updateObject:(ccTime)dt {
}
Mam następnie podklasy "FMSprite" na "FMObject", który przechowuje b2Body itp
Aby przenieść ciało Muszę najpierw przesunąć duszka i śledzić jego przyspieszenie, dzięki któremu znajdę potrzebną siłę (wykorzystując masę) potrzebną do podążenia za ruchem sprite'a. Ponieważ nie mogę przesunąć sprite obiektu (który jest zsynchronizowany z ciałem), robię kolejny sprite nazywany "beacon", dodam go jako dziecko do obiektu i poruszam nim. Wszystko, co musimy zrobić, to mieć funkcję synchronizowania pozycji ciała box2d z tym sprite'em beaconowym przy użyciu sił, o których wspomniałem wcześniej.
-(void) followBeaconWithDelta:(ccTime)dt {
float forceX = [beacon getSpriteAccel:dt].x * self.mass;
float forceY = [beacon getSpriteAccel:dt].y * self.mass;
[self addForce:b2Vec2(forceX, forceY)];
}
Rezultatem jest genialny, gładka złagodzenie ruch b2body ruchu gdziekolwiek chcesz go, bez zabawy z któregokolwiek z jej własnymi siłami, ale raczej, że kopiowanie z CCSprite i replikowania jego ruch. Ponieważ jest to cała siła, nie powoduje drgań i zniekształceń podczas kolizji z innymi obiektami b2Body. Jeśli ktoś ma jakieś inne metody, aby to zrobić, opublikuj odpowiedź. Dzięki!
Witam, dzięki za ten wpis. Nie zrozumiałem nawet jednej rzeczy. Dlaczego potrzebujesz sprite'a beacon? jeśli obiekt typu FMObject (który jest CCSprite) jest przenoszony za pomocą niestandardowej akcji, może sprawić, by b2Body w FMObject podążał za ikonką nadrzędną. Nie jestem pewien, co oznacza "zsynchronizowany z ciałem". Dlaczego osobiście potrzebujesz duszka ostrzegawczego i poruszasz nim? – Aks
Minęły prawie 3 lata, odkąd to opublikowałem, ale myślę, że możesz mieć rację. Nie widzę powodu, by mieć sprite'a z beaconu. Myślę, że to był tylko szczegół wdrożenia. Powinieneś być w stanie zastąpić sam "FMObject". –