box2d:使用特定角度定位box2d主体而不使用setTransform()?

时间:2012-09-16 14:46:39

标签: java box2d libgdx

我正在使用包含在libgdx api(java)

中的box2d

我使用矩形box2d机身作为传感器,用于检测4个方向的剑侠碰撞(使用身体作为传感器) (向上,向下,向左,向右倾斜90°)。 所以为了向上削减我基本上创建一个新的矩形box2d体并每次设置其起始位置:

swordBodyDef.position.set(playerBody.getPosition().x, playerBody.getPosition().y + 4);

仅这一点就会导致玩家将剑直接向上(12点钟)。 但它应该在12:10开始(然后通过施加力量移动到11:50) 因此,为了将剑的天使设置为玩家面前的12:10,我使用以下代码:

swordBody.setTransform(playerBody.getPosition().x, playerBody.getPosition().y + 4 ), (float)Math.toRadians(-125));

整个剑侠都有效,但每次击中敌人时,命中数都为2。 我感觉当我在12:00(setPosition)创建剑时,它已经参与了物理模拟并计入命中。 因此,当我通过setTransform方法将其调整为适当的天使(12:10)时,它将再次出现。 至少它可以在我不通过setTransform方法更改天使时起作用。 我认为如果有办法以原子方式设定剑的位置和天使,它会起作用。

有关如何防止双击的任何想法都值得赞赏:)

修改 关于Revolute Joints的box2d手册中我发现了以下内容: “要指定旋转,您需要在世界空间中提供两个实体和一个锚点。初始化函数假定实体已经处于正确的位置。” 这与我所做的完全相反。首先,我创建RevoluteJoint,然后设置swordBody的位置(所需的天使)。 所以很明显会导致物理上的麻烦,但我仍然不知道如何才能正确设置剑身的初始天使

EDIT2: 我推荐使用iforce2d来解决问题。 该问题仅出现在以下world.step中,所以我正在做的是通过

禁用swordBody
swordBody.setActive(false);

这个游戏循环并在下一个游戏中将其设置为true。 这有点难看,但至少它有效。

完整的box2d代码,用于向上方向的斜杠(12:10至11:50)

    //if the sword is active (slashing)
    if(swordBody != null)
    {
        //destroy swordbody when it reaches a certain angel (11:50)
        if(swordBody.getAngle() >= (float)Math.toRadians(50)) 
        {                               
            for (Body box : swordBody_List)
                GameplayScreen.world.destroyBody(box);
            swordBody_List.clear();

            swordBody = null;                           
        }           
    }           
    //construct a sword, set its position over the player's head, join it to the player's body, set the sword's angel to 12:10 and the      
    else if (playerInput.getMoveDirection() == Action.HIT) 
    {       
        //start state of hitting
        hitUp = true;


        //a short delay before the next hit starts
        if (hitTestUpdateTimer < .50f)
        {
            hitTestUpdateTimer += Gdx.graphics.getDeltaTime();
        }           
        else
        {   
            //Player's sword (box2d collision detection) 
            BodyDef swordBodyDef = new BodyDef();           
            swordBodyDef.type = BodyDef.BodyType.DynamicBody;
            swordBodyDef.position.set(playerBody.getPosition().x, playerBody.getPosition().y + 4);                  

            swordBody = GameplayScreen.world.createBody(swordBodyDef);                      
            swordBody.setUserData(this);    

            PolygonShape swordShape = new PolygonShape();       
            swordShape.setAsBox(.1f , 1.3f); //sword size   

            FixtureDef swordFixtureDef = new FixtureDef();      
            swordFixtureDef.shape = swordShape;
            swordFixtureDef.density = 1f; 
            swordFixtureDef.isSensor = true;                
            swordBody.createFixture(swordFixtureDef);       
            swordShape.dispose();               

            swordBody_List.add(swordBody);  


            //Connection between sword & player
            swordJointDef = new RevoluteJointDef();     
            swordJointDef.initialize(playerBody, swordBody, playerBody.getPosition().sub(new Vector2(0, -2))); 
            @SuppressWarnings("unused")
            RevoluteJoint swordRevJointDef = (RevoluteJoint)GameplayScreen.world.createJoint(swordJointDef);                


            //set the angel of the sword to 12:10 when the hit starts
            swordBody.setTransform(new Vector2(playerBody.getPosition().x, playerBody.getPosition().y + 4 ), (float)Math.toRadians(-125)); 
            //rotate the sword (left-direction) 
            swordBody.applyTorque(1600f);               


            //Set update timer back to zero
            hitTestUpdateTimer = 0;                 
            hitUp = false; //state of hitting is finished       
        }               


    }   

0 个答案:

没有答案