Я сделал простое наклонное движение в своей игре Game Maker.
Все работает нормально, за исключением случаев, когда игрок идет вверх по склону и его скорость достаточно высока, чтобы не успевать реагировать на код столкновения, и он застревает в стене.
Вот как это выглядит: гифка.
Итак, мой код выглядит так:
Создать событие:
hspd = 0;
vspd = 0;
grav = 2;
Шаговое событие:
// Movement
if (keyboard_check(vk_right) && !keyboard_check(vk_left)) {
hspd = 9;
} else
if (keyboard_check(vk_left) && !keyboard_check(vk_right)) {
hspd = -9;
}
// Check not moving
if ((!keyboard_check(vk_right) && !keyboard_check(vk_left)) || (keyboard_check(vk_right) && keyboard_check(vk_left))) {
hspd = 0;
}
// Gravity
if (!place_meeting(x, y+1, parent_ground)) {
vspd += grav;
}
// Jumping
if (place_meeting(x, y+1, parent_ground)) {
if (keyboard_check_pressed(vk_up)) {
vspd = -20;
}
}
// Variables
var hspd_final = hspd;
// Horizontal collision
horizontal_collision = instance_place(x+hspd_final, y, parent_ground);
if (horizontal_collision != noone) {
if (horizontal_collision.object_index == object_ground) {
while (!place_meeting(x+sign(hspd_final), y, horizontal_collision)) {
x += sign(hspd_final);
}
hspd_final = 0;
} else {
// Declare yplus
yplus = 0;
// Loop
while (place_meeting(x+hspd_final, y-yplus, parent_ground) && yplus <= abs(1*hspd_final)) {
yplus += 1;
}
y -= yplus;
while (place_meeting(x, y+1, parent_ground)) {
y -= 1;
}
}
}
// Down slope
down_slope = instance_place(x, y+1, parent_ground);
if (down_slope != noone && down_slope.object_index != object_ground) {
if (place_meeting(x, y+1, parent_ground)) {
yminus = abs(hspd_final);
while (place_meeting(x+hspd_final, y+yminus, parent_ground) && yminus != 0) {
yminus --;
}
y += yminus;
}
}
// Initialize horizontal speed
x += hspd_final;
// Vertical collision
if (place_meeting(x, y+vspd, parent_ground)) {
while (!place_meeting(x, y+sign(vspd), parent_ground)) {
y += sign(vspd);
}
vspd = 0;
}
// Initialize vertical speed
y += vspd;
У меня есть 3 объекта стены: object_ground (базовый блок), object_slope (объект для определения уклона) и parent_ground (объект, дочерними объектами которого являются object_ground и object_slope).
Спасибо.
Это довольно распространенная проблема с производителями игр, и у нее есть только два реальных решения.
Простое и правильное решение, чтобы исправить это, - проверить промежуточные позиции. Вместо того, чтобы перемещать его на spd
пикселей сразу, переместите его на 1 пиксель spd
раз. Если в это время вы столкнулись со столкновением, вы достигли максимума.
Таким образом, не имеет значения, двигаетесь ли вы со скоростью 0.01
или со скоростью 9999.0
.
Как именно я могу переместить своего игрока spd
раз? Лайкнуть repeat (spd) { hspd += 1; }
и потом зажать мой hspd
?
Да, или через некоторое время/для цикла. Но, глядя на ваш код, на самом деле похоже, что вы перемещаете объект назад, если он сталкивается (это делает цикл while). Я думаю, что происходит то, что ваше «вертикальное движение» тянет игрока вниз после выполнения кода наклона. Обычно я использую свои собственные переменные скорости и направления, а затем стараюсь двигаться плавно, пиксель за пикселем, проверяя каждую вдоль линии.
Ну, скорость моего игрока не является четным значением, поэтому я думаю, что из-за этого игрок застревает внутри стен. Я хотел бы сделать свое движение нелинейным, чтобы у игрока было ускорение и прочее, но это означает, что значение скорости будет иметь нечетное число. Как я могу это реализовать?