Moviendo cuerpos de Box2d como objetos CCSprite

En cocos2d, puede facilitar CCSprites y moverlos de todo tipo de formas. Lo más importante: pueden tener entrada / salida de relajación. Para la mayoría de los juegos, esto es deseable para un movimiento suave, etc.

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

Al mover un cuerpo box2d, el sprite adjunto se actualiza después del paso box2d (). Mover el sprite y luego actualizar el cuerpo no es una opción aquí, ya que anula por completo el propósito del marco físico.

Así que la otra opción, que he implementado con éxito, es calcular el desplazamiento, la velocidad y la aceleración de un sprite tratándolo como una entidad mecánica por derecho propio. Cada vez que llamo a mi update () en el sprite para que el personaje pueda decidir dónde moverse, etc., mi superclase también almacena la posición y la velocidad anteriores. Estos se almacenan como valores compatibles con box2d dividiéndolos entre PTM_RATIO.

En la subclase de CCSprite, llamada 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 {

}

uego, he subclasificado "FMSprite" en "FMObject", que almacena un b2Body, etc.

Para mover el cuerpo, primero debo mover un sprite y rastrear su aceleración, a través de la cual puedo encontrar la fuerza requerida (usando la masa) necesaria para seguir el movimiento del sprite. Como no puedo mover el sprite del objeto (que está sincronizado con el cuerpo), hago otro sprite llamado "baliza", lo agrego como un niño al objeto y lo muevo. Todo lo que necesitamos hacer entonces es tener una función para sincronizar la posición del cuerpo box2d con este sprite de baliza utilizando las fuerzas que mencioné antes.

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

El resultado es brillante, un movimiento suave de relajación del b2body moviéndose donde quieras, sin jugar con ninguna de sus propias fuerzas, sino más bien copiando el de un CCSprite y replicando su movimiento. Como se trata de todas las fuerzas, no causará temblores ni distorsiones al chocar con otros objetos b2Body. Si alguien tiene otros métodos para hacer esto, publique una respuesta. ¡Gracias

Respuestas a la pregunta(2)

Su respuesta a la pregunta