游戏绳摆动物理行为怪异

时间:2014-08-22 22:30:14

标签: java physics game-physics

我正试图在this tutorial之后在平台游戏中实现绳索摆动。玩家不是在绳子上晃动,而是看着他在斜坡上滑行:他向底部移动非常缓慢。

这就是现在的样子:

what it looks like now

相反,我希望玩家拥有更自然的动作,就像他真的在绳子上摇摆一样。

这是我的播放器类的更新方法:

@Override
    public final void update() {
        setPosition(getNextPosition());
        if (direction == Direction.LEFT && moving) {
            getVelocity().x = -WALK_SPEED;
        } else if (getVelocity().x < 0) {
            getVelocity().x *= COEF_FRIC;
        }

        if (direction == Direction.RIGHT && moving) {
            getVelocity().x = WALK_SPEED;
        } else if (getVelocity().x > 0) {
            getVelocity().x *= COEF_FRIC;
        }

        checkAsleep();
        animations.update();

        if (ropePoint != null) {
            //getCenter() returns the center position of the player
            if (getCenter().toPoint().distanceSq(ropePoint) > ROPE_LENGTH * ROPE_LENGTH) {

                final Vec2D oldPosition = getCenter();
                final Vec2D oldVelocity = getVelocity();
                final Vec2D ropePosition = new Vec2D(ropePoint);

                setCenter((oldPosition.subtract(ropePosition).unit().multiply(ROPE_LENGTH).add(ropePosition)));
                setVelocity(oldPosition.subtract(getCenter()).unit().multiply(oldVelocity));
            }
        }
    }

如果需要,这是我getNextPosition()的实现。

public final Vec2D getNextPosition() {

        final int currCol = (int) (getX() / Tile.SIZE);
        final int currRow = (int) (getY() / Tile.SIZE);

        final double destX = getX() + moveData.velocity.x;
        final double destY = getY() + moveData.velocity.y;

        double tempX = getX();
        double tempY = getY();

        Corners solidCorners = getCornersAreSolid(getX(), destY);
        boolean topLeft = solidCorners.topLeft;
        boolean topRight = solidCorners.topRight;
        boolean bottomLeft = solidCorners.bottomLeft;
        boolean bottomRight = solidCorners.bottomRight;

        framesSinceLastTopCollision += 1;
        framesSinceLastBottomCollision += 1;
        framesSinceLastLeftCollision += 1;
        framesSinceLastRightCollision += 1;
        if (moveData.velocity.y < 0) {
            if (topLeft || topRight) {
                moveData.velocity.y = 0;
                tempY = currRow * Tile.SIZE;
                framesSinceLastTopCollision = 0;
            } else {
                tempY += moveData.velocity.y;
            }
        } else if (moveData.velocity.y > 0) {
            if (bottomLeft || bottomRight) {
                moveData.velocity.y = 0;
                tempY = (currRow + 1) * Tile.SIZE - moveData.collisionBox.getHeight() % Tile.SIZE - 1;
                framesSinceLastBottomCollision = 0;
            } else {
                tempY += moveData.velocity.y;
            }
        }

        solidCorners = getCornersAreSolid(destX, getY());
        topLeft = solidCorners.topLeft;
        topRight = solidCorners.topRight;
        bottomLeft = solidCorners.bottomLeft;
        bottomRight = solidCorners.bottomRight;
        if (moveData.velocity.x < 0) {
            if (topLeft || bottomLeft) {
                moveData.velocity.x = 0;
                tempX = currCol * Tile.SIZE;
                framesSinceLastLeftCollision = 0;
            } else {
                tempX += moveData.velocity.x;
            }
        }
        if (moveData.velocity.x > 0) {
            if (topRight || bottomRight) {
                moveData.velocity.x = 0;
                tempX = (currCol + 1) * Tile.SIZE - moveData.collisionBox.getWidth() % Tile.SIZE - 1;
                framesSinceLastRightCollision = 0;
            } else {
                tempX += moveData.velocity.x;
            }
        }
        return new Vec2D(tempX, tempY);
    }

我应该在此代码中更改什么才能获得自然运动?

1 个答案:

答案 0 :(得分:0)

我的第一个猜测是问题出在第一个if语句:
if (direction == Direction.LEFT && moving) { getVelocity().x = -WALK_SPEED; } else if (getVelocity().x < 0) { getVelocity().x *= COEF_FRIC; }
如果第一件事情是真的,那么你将不断地将速度设定为步行速度,这在你的家伙在绳索上摆动时没有意义。他应该加速,因为他下降并在上升过程中放慢速度 如果第一件事是假的,那么既然他要离开,你肯定会进入else if语句,并且他会因摩擦而放慢速度。我没看到你把它设置在哪里,但它似乎仍然是他在地面上的摩擦,这似乎可以解释为什么他的所有人都很吵闹,看起来更像是滑动而不是摔倒。
你可能想要添加不同的状态,而不仅仅是“移动”,(可能是跳跃,摆动,行走,跑步,停止),并改变他在做这些事情时的表现。