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