【问题标题】:Game rope swing physics acting weird游戏绳索摆动​​物理行为怪异
【发布时间】:2014-10-16 20:44:48
【问题描述】:

我正在尝试在我的平台游戏中实现绳索摆动,遵循this tutorial。玩家没有在绳索上挥动,而是看起来像是在滑下斜坡:他向底部移动非常缓慢。

这就是现在的样子:

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

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

@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);
    }

我应该在此代码中进行哪些更改才能获得自然运动?

【问题讨论】:

  • 看起来很酷。我会尝试将角色稍微移向圆圈的中心,这样绳子的末端就是他的手所在的位置,而不是他的头部。我也会尝试旋转角色,使他始终垂直于绳索。如果你想走得更远,你可以玩一些弹性和弯曲绳子之类的东西。
  • 您是否关心更好地模拟加速度?另外,为什么玩家在到达底部时会减速和抖动?

标签: java physics game-physics


【解决方案1】:

我的第一个猜测是问题出在第一个 if 语句上:
if (direction == Direction.LEFT && moving) { getVelocity().x = -WALK_SPEED; } else if (getVelocity().x < 0) { getVelocity().x *= COEF_FRIC; }
如果第一件事是正确的,那么您将不断将速度设置为步行速度,当您的人在绳索上摆动时,这没有任何意义。他应该在下降时加速并在上升时减速。
如果第一件事是假的,那么既然他要离开了,你肯定会进入 else if 语句,他会因摩擦而减速。我不明白你在哪里设置的,但它似乎仍然是他在地面上的摩擦,这似乎可以解释为什么他口吃,看起来更像是在滑倒而不是跌倒。
您可能想要添加不同的状态,而不仅仅是“移动”(可能是跳跃、摆动、行走、跑步、停止),并改变他在做这些事情时的行为方式。

【讨论】:

    猜你喜欢
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    相关资源
    最近更新 更多