Java libgdx:限制圆周速度(摆动实体)

时间:2016-09-02 00:33:37

标签: java libgdx game-physics

我目前正在研究2D侧卷轴,并且已经在this文章中使用了用于抓钩的技术,并且它非常有效。我的问题是我希望我的球员能够在绳子周围摆动一点点以获得一点动力,但是目前我无法阻止球员一直向上移动90度。可以采用哪些技术来强制限制?

我尝试使用单独的玩家速度进行摆动,但这只会减慢过程,我仍然可以在每侧摆动90度。

这是我在播放器中的更新功能

public void update(float dt){
    //handle friction and air resistance
    if(dx !=0){
        if(touchingGround) {
            // apply friction
            if (dx > 0) {
                dx -= retardation;
            } else {
                dx += retardation;
            }
        } else {
            //applied air resistance
            if (dx > 0) {
                dx -= airResistance;
            } else {
                dx += airResistance;
            }
        }
    }
    // handle gravity
    dy -= Constants.GRAVITY * dt;
    if(dy < -terminalVelocity){
        dy = -terminalVelocity;
    }

    /*
        Handle Player movement
     */

    if(right){
        if(dx <= maxSpeed){
            dx += acceleration;
        }
        dx = maxSpeed;
    }

    if(left){
        if(dx <= -maxSpeed){
            dx -= acceleration;
        }
        dx = -maxSpeed;
    }

    if(isGrappling){

        //If we collide with something we need to stop grappling
        if(hasCollided){
            isGrappling = false;
        } else {

            //  This algorithm from here:
            // http://gamedev.stackexchange.com/questions/61596/player-rope-swing

            float currentD = (float) Math.sqrt(((grappleX - x) * (grappleX - x)) + ((grappleY - y) * (grappleY - y)));
            float prevX = getX(), prevY = getY();

            if (currentD > grappleRadius) {
                Vector2 hookPos = new Vector2(grappleX, grappleY);
                Vector2 testPos = (new Vector2(x, y).sub(hookPos)).nor();

                y = (hookPos.y + testPos.y * grappleRadius);
                x = (hookPos.x + testPos.x * grappleRadius);

                // s = d / t
                dx += (x - prevX) / dt;
                dy += (y - prevY) / dt;
            }
        }
    }

    /*
        Collision Detection, handle last always!
     */

    float oldX = getX(), oldY = getY();
    boolean collisionX = false, collisionY = false;

    // move on x
    x += dx * dt;

    // calculate the increment for step in #collidesLeft() and #collidesRight()
    increment = collisionLayer.getTileWidth();
    increment = getWidth() < increment ? getWidth() / 2 : increment / 2;

    if(dx < 0) // going left
        collisionX = collidesLeft();
    else if(dx > 0) // going right
        collisionX = collidesRight();

    // react to x collision
    if(collisionX) {
        setX(oldX);
        dx = 0;
    }

    // move on y
    y += dy * dt;

    // calculate the increment for step in #collidesBottom() and #collidesTop()
    increment = collisionLayer.getTileHeight();
    increment = getHeight() < increment ? getHeight() / 2 : increment / 2;

    if(dy < 0) {
        touchingGround = collisionY = collidesBottom();
        // we can only jump 2 times before we have to touch the floor again
        if(collisionY){
            numberOfJumps = 2;
        }
    } else if(dy > 0) {
        collisionY = collidesTop();
    }

    // react to y collision
    if(collisionY) {
        setY(oldY);
        dy = 0;
    }

    hasCollided = collisionX || collisionY;
}

1 个答案:

答案 0 :(得分:0)

由于我没有使用任何物理引擎,我选择通过限制玩家向挥杆施加力的角度来模拟物理。

            // check if angle permits movement
            if(grappleAngle < Math.PI/9 && grappleAngle > -Math.PI/9) {
                // handle momentum gaining on rope
                if (right) {
                    dx += swingAcceleration * dt;
                }

                if (left) {
                    dx -= swingAcceleration * dt;
                }
            }