Java box2d:不使用setTransform()以特定角度定位box2d实体?

Java box2d:不使用setTransform()以特定角度定位box2d实体?,java,box2d,libgdx,Java,Box2d,Libgdx,我使用的是libgdxapijava中包含的box2d 我使用一个长方形的box2d车身作为传感器,用于在4个方向上检测碰撞 上下左右斜切90度。 因此,对于向上的斜线,我基本上创建了一个新的矩形box2d实体,并每次设置其起始位置: swordBodyDef.position.set(playerBody.getPosition().x, playerBody.getPosition().y + 4); 仅此一项就将导致玩家在12点前持剑。 但它应该在12:10开始,然后通过施加力移动到11

我使用的是libgdxapijava中包含的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设定位置创建剑时,它已经在参与物理模拟,并计算为命中。 因此,当我通过setTransform方法将其调整到正确的角度12:10时,它将再次命中。 至少当我不通过setTransform方法更改天使时,它可以工作。 我认为,如果有一种方法可以将剑的位置和角度原子化,这将是可行的

如果有任何关于如何防止双重打击的想法,我将不胜感激:

编辑: 我在box2d手册中找到了关于旋转关节的以下内容: 要指定旋转,需要在世界空间中提供两个实体和一个定位点。初始化功能假定车斗已处于正确位置。 这与我所做的完全相反。首先创建旋转点,然后设置剑身所需的角度位置。 很明显,这在物理上造成了麻烦,但我仍然不知道如何正确设置剑身的初始角度

编辑2: 我按照iforce2d的建议做了一些变通来解决这个问题。 这个问题只出现在下面的步骤中。所以我现在做的是通过禁用剑身

swordBody.setActive(false);
对于此gameloop,请在下一个gameloop中将其设置为true。 这有点难看,但至少能起作用

上方斜线12:10至11:50的完整box2d代码:


如果您在contact listener的BeginContact函数中检测到点击,则每次调用world.Step时只应发生一次,因此不清楚如何获得两次。在任何情况下,如果创建实体后设置角度会让您感到困扰,您可以在创建实体之前通过在实体定义中设置角度来设置初始角度,例如:swordodydef.angle=…iforce2d?我阅读了您的大部分box2d教程,这些教程对我帮助很大!:当然你是对的,双重打击不会发生在同一个世界里。但很抱歉,我的问题解释得很糟糕。让我困惑的是,当我移除剑身。setTransform时,这种双重打击根本不会发生。。。方法正如在给定角度的旋转ti教程中所述,直接设置为给定角度(例如使用setTransform)可能会扰乱模拟。但是由于所有这些代码都应该在下一个世界执行。一步一步,我不确定出了什么问题……当我在bodydef中设置天使时,如你告诉我的,例如swordodydef.angle=floatMath.toRadians-105,剑身围绕其原点旋转,像螺旋桨一样旋转。我的setTransform方法是在我创建了旋转点之后进行的,旋转点在玩家的身体和剑之间创建了一个关节。setTransform影响剑的天使到关节我觉得我的英语太差,无法正确解释这一点,对不起,我将链接一张图片,使剑身和玩家身之间的关系更加清晰;我懂了。那么我想保持SetTransform不变会更容易。关于双重命中,我记不清了,但如果引擎与某个东西重叠,可能会在创建新夹具时立即发送命中。也许您可以忽略在您不期望的情况下发生的任何“点击”。是的,以某种方式防止意外点击本应是计划b^^^,但我发现了一个与初始化接头相关的box2d手动条目。显然,在初始化旋转点之前,应该由旋转点连接的两个车身必须处于所需位置。后来我就这么做了…所以现在我正在使用一些未定义的行为来实现我的刀砍效果,我仍然在寻找一个合适的解决方案^^
    //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       
        }               


    }