Перемещение Box2d тела, как объекты CCSprite - PullRequest
5 голосов
/ 13 декабря 2011

В cocos2d вы можете облегчить CCSprites и перемещать их разными способами.Самое главное - они могут иметь ослабление в / из.Для большинства игр это желательно для плавного перемещения и т. Д.

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

При перемещении тела box2d прикрепленный к нему спрайт обновляется после шага box2d ().Перемещение спрайта и затем обновление тела здесь не вариант, так как он полностью отрицает цель физической структуры.

Так что другой вариант, который я успешно реализовал, - это вычислить смещение, скорость иускорение спрайта, рассматривая его как самостоятельную механическую сущность.Каждый раз, когда я вызываю свой метод update () для спрайта, чтобы персонаж мог решить, куда двигаться и т. Д., Мой суперкласс также сохраняет предыдущую позицию и скорость.Они сохраняются как значения, совместимые с box2d, путем деления на PTM_RATIO.

В подклассе CCSprite, называемом 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 {

}

Затем я поместил в подкласс "FMSprite"в «FMObject», в котором хранится b2Body и т. д.

Чтобы переместить тело, я должен сначала переместить спрайт и отследить его ускорение, благодаря которому я могу найти требуемую силу (используя массу), необходимую дляследуйте за движением спрайта.Поскольку я не могу переместить спрайт объекта (который синхронизирован с телом), я создаю другой спрайт, называемый «маяком», добавляю его в качестве дочернего к объекту и перемещаю его.Все, что нам нужно сделать, - это иметь функцию для синхронизации положения тела 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)];
}

Результат блестящий, плавное замедление движенияb2 тело движется туда, куда вы хотите, не играя своими силами, а скорее копируя CCSprite и копируя его движение.Поскольку это все силы, это не вызовет дрожания и искажений при столкновении с другими объектами b2Body.Если у кого-то есть другие способы сделать это, пожалуйста, оставьте ответ.Спасибо!

1 Ответ

4 голосов
/ 08 мая 2012

То, что я делаю, отличается от вашего, но может также перемещать тела 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.

Надеюсь, я понимаю ваш вопрос, и ответ полезен для вас ...

...