2011-12-13 17 views
5

, sen CCSprites kolaylığı ve yolları her türlü etrafında taşıyabilirsiniz Nesneleri. En önemlisi - giriş/çıkış kolaylığı sağlayabilirler. Bir box2d gövde taşırken çok oyun için, bu gibiHareketli Box2D Oluşumu Cocos2D olarak

id action = [CCMoveTo actionWithDuration:dur position:pos]; 
move = [CCEaseInOut actionWithAction:action rate:2]; 
[self runAction: move]; 

düzgün hareket için tercih edilir, buna bağlı hareketli grafik box2d adımından sonra güncellenir(). Spritin hareket ettirilmesi ve daha sonra bedenin güncellenmesi, fizik çerçevesinin amacını tamamen yitirdiği için burada bir seçenek değildir.

Yani başarıyla uygulayan diğer seçenek, kendi başına bir mekanik varlık olarak işlenerek hareketli grafiğin yer değiştirme, hız ve ivme hesaplamaktır. Karakterlerim nereye gideceğine karar verebilmem için sprite() yazımımı her aradığımda, üst sınıfım da önceki konumu ve hızı kaydeder. Bunlar PTM_RATIO tarafından bölünerek box2d uyumlu değerleri olarak saklanır. FMSprite denilen CCSprite ait alt sınıfında

:

-(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 { 

} 

Sonra vb b2Body depolayan "FMObject", içine "FMSprite" sınıflandırma var

vücut hareket etmek için İlk önce bir hareketli çizgiyi hareket ettirmeliyim ve sprite'ın hareketini takip etmek için gerekli olan gücü (kütleyi kullanarak) bulabildiğim ivmesini takip etmeliyim. Ben (vücuda senkronize edilir) nesnenin sprite hareket edemez beri, bir "işaret" adlı başka bir sprite yapmak nesneye bir çocuk olarak ekleyin ve etrafında hareket. Yapmamız gereken tek şey, daha önce bahsettiğim güçleri kullanarak box2d gövdesinin konumunu bu işaret sprite ile senkronize etmek için bir fonksiyona sahip olmaktır. Sonuç parlak

-(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)]; 
} 

, hareketli b2body sorunsuz kolaylaştırılması hareket nereye kendi güçlerinin herhangi uğraşırken, daha ziyade bir CCSprite o kopyalama ve hareketini taklit etmeden, bunu hiç tercih. Tüm kuvvetler olduğu için, diğer b2Body nesneleriyle çarpıştığında titreme ve çarpıtmalara neden olmaz. Bunu yapmak için başka herhangi bir yöntem varsa, lütfen bir yanıt gönderin. Teşekkürler!

+0

Merhaba, Bu yazı için teşekkürler. Yine de bir şey anlamadım. Neden bir fener sprite ihtiyacınız var? tip FMObject bir nesne (bir CCSprite olan) bazı özel işlem kullanıyorsa taşınıyor, neden FMObject içinde b2Body ebeveyn sprite izleyin yapamaz. 'Vücutla eş zamanlı olarak' ne anlama geldiğinden emin değilim. Neden ayrı olarak bir fener grafiğine ihtiyacınız var ve onu hareket ettiriyorsunuz? – Aks

+0

Bunu yayınladığımdan yaklaşık 3 yıl geçti, ama bence haklı olabilirsin. Bir işaret işaretine sahip olmanın sebebini göremiyorum. Bence bu sadece bir uygulama detayıydı. FMObject’in kendisini değiştirebilmelisiniz. –

cevap

4

Ne yapmam sizinkinden farklı değil, aynı zamanda CCSprite Nesneleri gibi Box2D Bodies Hareketli ve hatta CCAction kullanabilirsiniz. en önemli şey ccSprite ve b2body içerirler bir nesne yaratmaktır.

@interface RigidBody : CCNode { 
    b2Body *m_Body; 
    CCSprite *m_Sprite; 
} 

Ve sonra, setPosition yöntemi yeniden.

-(void)setPosition:(CGPoint)position 
{ 
    CGPoint currentPosition = position_; 
    b2Transform transform = self.body->GetTransform(); 
    b2Vec2 p = transform.p; 
    float32 angle = self.body->GetAngle(); 
    p += [CCMethod toMeter:ccpSub(position, currentPosition)]; 
    self.body->SetTransform(p, angle); 
    position_ = position; 
} 

SetPosition yöntemi, konumun ne kadar değiştiğini hesaplar ve bunu b2body'ye ayarlar.

Umarız, sorunuzu anlıyorum ve cevap sizin için yararlıdır ...

+0

Bu, konumlandırma için çalışır ancak SetTransform, her defasında güç kullanmak yerine vücut konumunu ayarlayacaktır.Bu, iki RigidBody nesnesi çarpıştığında, birbirlerini sorunsuz bir şekilde sektirmek yerine bir çarpıtma etkisi yaratacağı anlamına gelir. AddForce yöntemi daha fazla iştir, ancak fiziğin pürüzsüz olmasını sağlayacaktır. –

+0

Evet, Ama kuvvet kullanarak vücudun sabit bir hızda ve kararlı bir konumda tutmak zordur. Metodu kullanırken hiçbir zaman bir hata alamıyorum, ama her iki beden de b2_dynamicBody olup olmadığına dair bir fikrim yok. –