Возможно, вы захотите пересмотреть свои расчеты, используя дельту движения.
Примерно так (также псевдо):
// assuming player graphics are centered
player_right = player.x + player.width / 2;
player_left = player.x - player.width / 2;
player_top = player.y - player.height / 2;
player_bottom = player.y + player.height / 2;
// assuming block graphics are centered as well
block_right = box.x + box.width / 2;
...
// determine initial orientation
if (player_right block_right) orientationX = 'right';
if (player_top block_top) orientationY = 'top';
// calculate movement delta
delta.x = player.x * force.x - player.x;
delta.y = player.y * force.y - player.y;
// define a rect containing where your player WAS before moving, and where he WILL BE after moving
movementRect = new Rect(player_left, player_top, delta.x + player.width / 2, delta.y + player.height / 2);
// make sure you rect is using all positive values
normalize(movementRect);
if (movementRect.contains(new Point(block_top, block_left)) || movementRect.contains(new Point(block_right, block_bottom))) {
// there was a collision, move the player back to the point of collision
if (orientationX == 'left') player.x = block_right - player.width / 2;
else if (orientationX == 'right') player.x = block_left + player.width / 2;
if (orientationY == 'top') player.y = block_top - player.height / 2;
else if (orientationY == 'bottom') player.y = block_bottom + player.height / 2;
// you could also do some calculation here to see exactly how far the movementRect goes past the given block, and then use that to apply restitution (bounce back)
} else {
// no collision, move the player
player.x += delta.x;
player.y += delta.y;
}
Этот подход даст вам намного лучшерезультаты, если ваш игрок когда-либо движется очень быстро, так как вы по сути рассчитываете, столкнется ли игрок, а не столкнулся ли он.