0

大家怎么了

谢谢你的时间。

我正在制作 Pong 克隆,并且我想将 Box2D 限制为最多两个 MouseJoint;每个桨最多一个 MouseJoint。只有当用户的两次触摸之一落在两个桨的边界内时,才应创建 MouseJoint。

我的代码得到了一个奇怪的结果。如果我的第一次触摸落在左侧拨片内,而我的第二次触摸落在任一拨片之外,则在左侧拨片上创建第二个 MouseJoint(见附图)。

注意:图中除了左边的两个MouseJoints外,还有两个PrismaticJoints;一个附在每个桨上。

在此处输入图像描述

无济于事,我尝试了所有我能想到或从其他人的代码中改编的算法。

如果可以发布代码解决方案示例或链接,我将不胜感激。

这是我的代码:

public class MyScreen implements Screen, InputProcessor{

/*========some variables and methods omitted for clarity========*/


/*multiple mouse joint experiment*/
public MouseJoint mouseJoint[] = new MouseJoint[2];    
Body hitBody[] = new Body[2];
Body tempBody;

public MyScreen(Pong game) {
    this.game = game;
}        

/*---------------------Screen interface methods--------------------------*/
//methods omitted for clarity
/*---------------------end Screen interface methods----------------------*/

/*---------------------InputProcessor interface methods------------------*/
@Override
public boolean keyDown(int keycode) {
    return false;
}

@Override
public boolean keyUp(int keycode) {
    return false;
}

@Override
public boolean keyTyped(char character) {
    return false;
}

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {                                       
                testPoint.set(screenX, screenY, 0);
                camera.unproject(testPoint);

                // ask the world which bodies are within the given
                // bounding box around the mouse pointer
                hitBody[pointer] = null;

                world.QueryAABB(callback, testPoint.x - 1.0f, testPoint.y - 1.0f, testPoint.x + 1.0f, testPoint.y + 1.0f);
                hitBody[pointer] = tempBody;

                // if we hit something we create a new mouse joint
                // and attach it to the hit body.
                if (hitBody[pointer] != null) {

                    MouseJointDef def = new MouseJointDef();
                    def.bodyA = groundBody;
                    def.bodyB = hitBody[pointer];
                    def.collideConnected = true;                                                 
                    def.target.set(hitBody[pointer].getPosition().x, hitBody[pointer].getPosition().y);
                    def.maxForce = 3000.0f * hitBody[pointer].getMass();

                    mouseJoint[pointer] = (MouseJoint)world.createJoint(def);
                    hitBody[pointer].setAwake(true);
                } else {

                }
                return false;                 
}

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) { 
    if (mouseJoint[pointer] != null) {
        world.destroyJoint(mouseJoint[pointer]);
        mouseJoint[pointer] = null;
    }
    return false;
}

/**a temporary vector for delta target destination during touchDragged() method**/
Vector2 target = new Vector2();

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
    if (mouseJoint[pointer] != null) {
        camera.unproject(testPoint.set(screenX, screenY, 0));
        mouseJoint[pointer].setTarget(target.set(testPoint.x, testPoint.y));
    }
    return false;
}

@Override
public boolean mouseMoved(int screenX, int screenY) {
    return false;
}

@Override
public boolean scrolled(int amount) {
    return false;
}
    /*----------------end InputProcessor interface methods------------------*/

/*------------------------helper methods------------------------------------*/
    /*android screen touch vector for a mouse joint*/
    Vector3 testPoint = new Vector3(); //we instantiate this vector and the callback here so we don't irritate the GC
    QueryCallback callback = new QueryCallback() {
       @Override public boolean reportFixture (Fixture fixture) {
          // if the hit fixture's body is the ground body
          // we ignore it
          if (fixture.getBody() == groundBody) return true;

          if (fixture.testPoint(testPoint.x, testPoint.y)) {
              tempBody = fixture.getBody();
                return false;
          } else
                return true;
       }
    };          
/*------------------------end helper methods-------------------------------*/
}
4

1 回答 1

2

从我所见,tempBody永远不会重置为空。这意味着当您第一次触摸垫子时,它将设置为触摸的垫子tempBody,然后当您在身体外部按下时,回调将不会找到新的身体但不会将其重置testBody为空,所以当您分配testBodyhitBody[pointer]它时设置它到第一个桨。

您的着陆功能应如下所示:

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {                                       
            testPoint.set(screenX, screenY, 0);
            camera.unproject(testPoint);

            // ask the world which bodies are within the given
            // bounding box around the mouse pointer
            hitBody[pointer] = null;

            world.QueryAABB(callback, testPoint.x - 1.0f, testPoint.y - 1.0f, testPoint.x + 1.0f, testPoint.y + 1.0f);
            hitBody[pointer] = tempBody;

            // if we hit something we create a new mouse joint
            // and attach it to the hit body.
            if (hitBody[pointer] != null) {

                MouseJointDef def = new MouseJointDef();
                def.bodyA = groundBody;
                def.bodyB = hitBody[pointer];
                def.collideConnected = true;                                                 
                def.target.set(hitBody[pointer].getPosition().x, hitBody[pointer].getPosition().y);
                def.maxForce = 3000.0f * hitBody[pointer].getMass();

                mouseJoint[pointer] = (MouseJoint)world.createJoint(def);
                hitBody[pointer].setAwake(true);
            } else {

            }
            tempBody = null;

            return false;                 

}

这样 tempBody 在使用后总是被重置为 null 。

于 2013-07-30T12:03:07.933 回答