Всегда можно сделать так, как это работает в GameMaker'е:
1. Сделать игроку функцию, возвращающую, столкнется ли он с каким-либо твердым объектом, если его сместить на указанное количество пикселей по x\y:
Код
boolean placeFree(float dx, float dx) {
// сместить на указанные координаты:
this.rect.y += dx;
this.rect.x += dx;
// перебор платформ:
Platform[] platforms = Game.platforms; // список платформ
int n = platforms.length;
boolean result = true;
for (int i = 0; i < n; i++) if (platforms[i].rect.Intersect(this.rect)) {
// Если на новой позиции игрок пересекает i-ую платформу, пометить результат и прекратить перебор.
result = false;
break;
}
// сместить обратно:
this.rect.x -= dx;
this.rect.y -= dy;
// вернуть результат
return result;
}
2. Построить логику на этом:
Код
int walkSpeed = 4; // скорость ходьбы (пкс\кадр)
float ySpeed = 0f; // текущая вертикальная скорость (пкс\кадр)
float jumpVelocity = 10f; // прирост вертикальной скорости при прыжке
float gravity = 0.5f; // "сила" гравитации
void update() { // выполняется раз в кадр
boolean isOnGround = !placeFree(0f, 1f);
if (isOnGround) { // стоит на земле
if (jumpPressed()) { // была нажата кнопка прыжка?
this.ySpeed = -this.jumpVelocity;
}
} else { // в воздухе: применить гравитацию
this.ySpeed += this.gravity;
}
// вычислить горизонтальное направление движения (-1\0\1):
int sx = 0;
if (leftDown()) sx -= 1;
if (rightDown()) sx += 1;
// само горизонтальное движение (если нужно):
if (sx != 0) for (int i = 0; i < this.walkSpeed; i++) {
if (placeFree(sx, 0f)) { // можно сдвинуться на пиксель в направлении - сдвигаемся
this.rect.x += sx;
} else { // ударились в стену. прекратить цикл
break;
}
}
// вертикальное движение:
int ay = (int)(this.ySpeed + 0.5); // округлить скорость
int sx = 0; // направление движения по вертикали
if (ay > 0) {
sx = 1;
} else if (ay < 0) {
ay = -ay;
sx = -1;
}
// само вертикальное движение:
if (sy != 0) for (int i = 0; i < ay; i++) {
if (placeFree(0f, sy)) { // можно сдвинуться на пиксель в направлении - сдвигаемся
this.rect.y += sy;
} else {
this.ySpeed = 0f; // сбрасываем вертикальную скорость при ударе об платформы
break;
}
}
}
Вариант с неиспорченным форматированием: https://gist.github.com/anonymous/f444b4e781c555bc785a