移动Box2d机构像CCSprite对象 [英] Moving Box2d Bodies Like CCSprite Objects

查看:185
本文介绍了移动Box2d机构像CCSprite对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在cocos2d中,你可以缓解CCSprites并以各种方式移动它们。最重要的是,他们可以放松/放松。对于大多数游戏,这是平滑移动等所期望的。

In cocos2d, you can ease in CCSprites and move them around in all kinds of ways. Most importantly - they can have easing in/out. For most games this is desirable for smooth movement etc.

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

当移动box2d主体时,附加到它的精灵在box2d步骤()之后更新。移动sprite然后更新body不是一个选项,因为它完全违背了物理框架的目的。

When moving a box2d body, the sprite attached to it is updated after the box2d step(). Moving the sprite and then updating the body is not an option here, as it entirely defeats the purpose of the physics framework.

所以我已经成功实现的另一个选项,是计算一​​个精灵的位移,速度和加速度,把它作为一个力学实体处理它自己的权利。每次我调用我的更新()在sprite,所以角色可以决定移动等,我的超类也存储以前的位置和速度。这些通过除以PTM_RATIO除以符合box2d的值存储。

So the other option, which I have successfully implemented, is to calculate the displacement, velocity and acceleration of a sprite by treating it as a mechanics entity in its own right. Each time I call my update() on the sprite so the character can decide where to move etc, my superclass also stores the previous position and velocity. These are stored as box2d compliant values by dividing by the 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等。

I have then subclassed "FMSprite" into "FMObject", which stores a b2Body etc.

为了移动身体,我必须首先移动精灵并跟踪它的加速度,通过它我可以找到跟随精灵运动所需的力(使用质量)。因为我不能移动对象的精灵(它被同步到body),我使另一个sprite被称为beacon,添加它作为一个孩子到对象,并移动它。所有我们需要做的就是有一个函数使box2d身体的位置与这个信标雪碧使用我之前提到的力量同步。

In order to move the body, I must first move a sprite and track its acceleration, through which I can find the required force (using the mass) needed to follow the sprite's motion. Since I can't move the object's sprite (which is synchronized to the body), I make another sprite called a "beacon", add it as a child to the object, and move it around. All we need to do then is to have a function to synchronize the position of the box2d body with this beacon sprite using the forces I mentioned before.

-(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对象碰撞时,不会导致抖动和扭曲。如果任何人有任何其他方法来做到这一点,请发布一个答案。谢谢!

The result is brilliant, a smooth easing motion of the b2body moving where ever you want it to, without playing around with any of its own forces, but rather copying that of a CCSprite and replicating its motion. Since it's all forces, it won't cause jittering and distortions when colliding with other b2Body objects. If anyone has any other methods to do this, please post an answer. Thanks!

推荐答案

我做的是不同于你的,但也可以移动Box2d机构像CCSprite对象,甚至使用CCAction。
最重要的是创建一个包含ccSprite和b2body的对象。

What I do is different from yours, but can also Moving Box2d Bodies Like CCSprite Objects and even use the CCAction. The most important thing is to create an object that contain ccSprite and b2body.

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

然后,重写setPosition方法。

And then, rewrite the setPosition method.

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

The setPosition method calculate how much the position change,and set it to the b2body.

我希望我了解您的问题,答案对您有帮助...

I hope I have understanding your question and the answer is helpful for you...

这篇关于移动Box2d机构像CCSprite对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆