Игрок застревает в стене, двигаясь по склону вверх

Я сделал простое наклонное движение в своей игре 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).

Спасибо.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
549
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это довольно распространенная проблема с производителями игр, и у нее есть только два реальных решения.

  1. Изменение скорости вашей комнаты, чтобы она могла идти в ногу
  2. Уменьшение скорости игрока (белого куба)

Ну, скорость моего игрока не является четным значением, поэтому я думаю, что из-за этого игрок застревает внутри стен. Я хотел бы сделать свое движение нелинейным, чтобы у игрока было ускорение и прочее, но это означает, что значение скорости будет иметь нечетное число. Как я могу это реализовать?

younyokel 31.05.2019 15:08
Ответ принят как подходящий

Простое и правильное решение, чтобы исправить это, - проверить промежуточные позиции. Вместо того, чтобы перемещать его на spd пикселей сразу, переместите его на 1 пиксель spd раз. Если в это время вы столкнулись со столкновением, вы достигли максимума.

Таким образом, не имеет значения, двигаетесь ли вы со скоростью 0.01 или со скоростью 9999.0.

Как именно я могу переместить своего игрока spd раз? Лайкнуть repeat (spd) { hspd += 1; } и потом зажать мой hspd?

younyokel 05.06.2019 12:59

Да, или через некоторое время/для цикла. Но, глядя на ваш код, на самом деле похоже, что вы перемещаете объект назад, если он сталкивается (это делает цикл while). Я думаю, что происходит то, что ваше «вертикальное движение» тянет игрока вниз после выполнения кода наклона. Обычно я использую свои собственные переменные скорости и направления, а затем стараюсь двигаться плавно, пиксель за пикселем, проверяя каждую вдоль линии.

Rob 05.06.2019 13:05

Другие вопросы по теме