2011-12-13 3 views
5

cocos2d에서 CCSprite를 쉽게 사용할 수 있고 모든 방법으로 이동할 수 있습니다. 가장 중요한 것은 - 그들은 편한 입/출고를 가질 수 있습니다. Box2D의 몸을 이동시킬 경우 대부분은이 게임 등Box2d 바디를 CCSprite 오브젝트와 같이 이동

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

원활한 이동을 위해 바람직하다 첨부 스프라이트가 Box2D의 단계 이후에 업데이트된다(). 스프라이트를 이동 한 다음 바디를 업데이트하는 것은 여기서는 선택 사항이 아닙니다. 물리 프레임 워크의 목적을 완전히 상실하기 때문입니다.

그래서 성공적으로 구현 한 다른 옵션은 스프라이트의 위치, 속도 및 가속도를 자체적 인 메커니즘 엔티티로 처리하여 계산하는 것입니다. 캐릭터가 어디로 움직일 지 결정할 수 있도록 스프라이트에서 update()를 호출 할 때마다 내 슈퍼 클래스는 이전 위치와 속도도 저장합니다. 이것들은 PTM_RATIO로 나누어 box2d 호환 값으로 저장됩니다. FMSprite라는 CCSprite의 서브 클래스

는 :

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

} 

는 I는 등 b2Body 저장 "FMObject"로 "FMSprite을"서브 클래스 한

본체를 이동하기 위해서 스프라이트의 움직임을 추적하는 데 필요한 힘 (질량 사용)을 찾을 수 있도록 스프라이트를 이동하고 가속도를 추적해야합니다. 객체의 스프라이트 (몸체와 동기화 됨)를 움직일 수 없기 때문에 "비콘"이라고하는 다른 스프라이트를 만들어 객체에 어린이로 추가하고 주위를 이동합니다. 우리가해야 할 일은 전에 언급 한 힘을 사용하여이 비컨 스프라이트와 box2d 본문의 위치를 ​​동기화하는 기능을 갖는 것입니다. 결과는 훌륭

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

, 이동 b2body의 원활한 완화 움직임 어디 자신의 힘의 주위에 놀고, 오히려 CCSprite의 복사와 그 동작을 복제하지 않고, 그것을 원하는 지금. 모든 힘이기 때문에 다른 b2Body 객체와 충돌 할 때 흔들림이나 왜곡이 발생하지 않습니다. 다른 사람이이 작업을 수행 할 수있는 방법이 있으면 답변을 게시하십시오. 감사!

+0

안녕하세요, 감사합니다. 나는 한 가지를 이해하지 못했습니다. 왜 비콘 스프라이트가 필요하니? FMObject (CCSprite) 유형의 객체가 사용자 정의 액션을 사용하여 이동되는 경우 FMObject의 b2Body를 부모 스프라이트에 따라야합니다. 몸에 무엇이 싱크로나이즈되는지 확실하지 않습니다. 비콘 스프라이트가 따로 필요하고 주변을 이동하는 이유는 무엇입니까? – Aks

+0

게시한지 거의 3 년이 지났지 만, 내가 맞다고 생각합니다. 비콘 스프라이트가있는 이유를 알 수 없습니다. 나는 그것이 단지 구현 세부 사항이라고 생각한다. 'FMObject' 자체를 대체 할 수 있어야합니다. –

답변

4

내가하는 일은 당신과 다르지만, Box2d 바디를 CCSprite 오브젝트와 같이 움직일 수 있으며 심지어 CCAction을 사용할 수도 있습니다. 가장 중요한 것은 ccSprite 및 b2body가 포함 된 개체를 만드는 것입니다.

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

그런 다음 setPosition 메소드를 다시 작성하십시오.

-(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 메소드는 위치 변경 양을 계산하고이를 b2body로 설정합니다.

귀하의 질문을 이해하고 답변 해 주시면 감사하겠습니다.

+0

이것은 포지셔닝을 위해 작동하지만 SetTransform은 힘을 사용하지 않고 매번 몸체 위치를 설정합니다.즉, 두 개의 RigidBody 객체가 충돌 할 때 서로 부드럽게 튀어 나오지 않고 지터 효과를 생성합니다. addForce 메서드는 더 많은 작업이지만 물리학이 원활하도록 보장합니다. –

+0

네,하지만 힘을 사용하면 몸을 안정된 속도와 확실한 자세로 유지하기가 어렵습니다. 제 방법을 사용하면 결코 실수가 없습니다.하지만 두 신체가 모두 b2_dynamicBody인지 전혀 알 수 없습니다. –

관련 문제