如何抓取 b2Body 并将其在屏幕上移动? (cocos2d、box2d、iPhone)

发布于 2024-10-21 18:05:34 字数 401 浏览 3 评论 0原文

我想将屏幕上触摸的任何 b2body 移动到屏幕周围。我听说过一些关于鼠标关节的事情..

我发现: http://iphonedev.net/2009/08/05/how-to-grab-a-sprite-with-cocos2d-and-box2d/

但我只是给了我一个如果我只是将 ccTouch 方法复制到新项目中(当然标头中的变量也是如此),则会出现很多错误。例如,world->Query <- NO MEMBER FOUND

可能有人会制作一个 tut/一个新项目并将其上传到此处。或者有更好的方法吗?

I want to move any b2body that is touched on the screen around the screen. I've heard something about mouse joints..

I found that: http://iphonedev.net/2009/08/05/how-to-grab-a-sprite-with-cocos2d-and-box2d/

but I just gives me a lot of errors if i just copy the ccTouch Methods into a new project (of course the variables in the header too). E.g. world->Query <- NO MEMBER FOUND

May someone make a tut/a new project and upload it here. Or is there a better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

随心而道 2024-10-28 18:05:34

首先,您必须创建 b2QueryCallback 子类:

class QueryCallback : public b2QueryCallback
{
public:
    QueryCallback(const b2Vec2& point)
    {
        m_point = point;
        m_object = nil;
    }

    bool ReportFixture(b2Fixture* fixture)
    {
        if (fixture->IsSensor()) return true; //ignore sensors

        bool inside = fixture->TestPoint(m_point);
        if (inside)
        {
             // We are done, terminate the query.
             m_object = fixture->GetBody();
                 return false;
        }

        // Continue the query.
        return true;
    }

    b2Vec2  m_point;
    b2Body* m_object;
};

然后在您的 touchBegan 方法中:

    b2Vec2 pos = yourTouchPos;
// Make a small box.
b2AABB aabb;
b2Vec2 d;
d.Set(0.001f, 0.001f);
aabb.lowerBound = pos - d;
aabb.upperBound = pos + d;

// Query the world for overlapping shapes.
QueryCallback callback(pos);
world_->QueryAABB(&callback, aabb);         

b2Body *body = callback.m_object;
if (body)
    {
        //pick the body
    }

我认为您可以通过两种方式控制拾取的主体。正如您所注意到的,第一个是创建 mouseJoint,第二个是使您的身体运动并控制其速度(不是位置! - 它会在碰撞时提供非物理行为,因为速度为零)。在第一种情况下,如果您移动物体的速度非常快,则移动时会出现一些延迟。我自己没有尝试第二种方法,因为在这种情况下,物体不会与其他运动和静态物体发生碰撞。

此外,您可能想在移动时锁定身体的旋转。

First you have to create b2QueryCallback subclass:

class QueryCallback : public b2QueryCallback
{
public:
    QueryCallback(const b2Vec2& point)
    {
        m_point = point;
        m_object = nil;
    }

    bool ReportFixture(b2Fixture* fixture)
    {
        if (fixture->IsSensor()) return true; //ignore sensors

        bool inside = fixture->TestPoint(m_point);
        if (inside)
        {
             // We are done, terminate the query.
             m_object = fixture->GetBody();
                 return false;
        }

        // Continue the query.
        return true;
    }

    b2Vec2  m_point;
    b2Body* m_object;
};

Then in your touchBegan method:

    b2Vec2 pos = yourTouchPos;
// Make a small box.
b2AABB aabb;
b2Vec2 d;
d.Set(0.001f, 0.001f);
aabb.lowerBound = pos - d;
aabb.upperBound = pos + d;

// Query the world for overlapping shapes.
QueryCallback callback(pos);
world_->QueryAABB(&callback, aabb);         

b2Body *body = callback.m_object;
if (body)
    {
        //pick the body
    }

There are two ways I see you can control the picked body. The first one, as you notices - to create a mouseJoint and the second is to make your body kinematic and control it's velocity (not position! - it will provide non-physical behavior when collide because the speed will be zero). In first case if you will move your objects very fast there will be some delay when moving. I did not try the second way myself because in this case the body will not collide with other kinematic and static bodies.

Also you may want to lock body's rotation when moving.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文