Организация movement персонажа в GameMaker
Самая частая ошибка в первых проектах — “движение прямо в Step через x +=” без структуры. Ниже — простой, но масштабируемый каркас: отдельно собираем ввод, отдельно считаем скорость, отдельно решаем столкновения.
1) Данные и скорость — в Create
В Create удобно завести параметры и текущую скорость по осям. Даже если сейчас движение “плиточное”, через неделю вам захочется ускорение, трение, рывок или скольжение — и эти переменные уже будут на месте.
// obj_player: Create
move_speed = 4; // максимальная скорость
accel = 0.6; // ускорение к цели
friction = 0.7; // затухание, когда нет ввода (0..1)
hsp = 0; // horizontal speed
vsp = 0; // vertical speed
2) Ввод → целевое направление
Сначала превращаем нажатия в вектор направления (dx, dy). Дальше этот вектор можно заменить на геймпад/AI, не переписывая движение.
// obj_player: Step (Input)
var dx = keyboard_check(vk_right) - keyboard_check(vk_left);
var dy = keyboard_check(vk_down) - keyboard_check(vk_up);
// Нормализация диагонали: чтобы по диагонали не было быстрее
if (dx != 0 || dy != 0) {
var len = point_distance(0, 0, dx, dy);
dx /= len;
dy /= len;
}
3) Ускорение/трение → “приятное” управление
Вместо мгновенного x += speed лучше плавно тянуться к целевой скорости. Когда ввода нет — применяем трение.
// obj_player: Step (Velocity)
var target_hsp = dx * move_speed;
var target_vsp = dy * move_speed;
// Плавно приближаемся к цели
hsp = lerp(hsp, target_hsp, accel);
vsp = lerp(vsp, target_vsp, accel);
// Если нет ввода — “гасим” скорость
if (dx == 0) hsp *= friction;
if (dy == 0) vsp *= friction;
4) Перемещение со столкновениями (простая схема)
Двигайтесь по осям отдельно: сначала X, потом Y. Так проще решать столкновения и избегать “залипаний” в углах. Ниже пример для твёрдых стен obj_wall.
// obj_player: Step (Move + Collisions)
// X
if (place_meeting(x + hsp, y, obj_wall)) {
while (!place_meeting(x + sign(hsp), y, obj_wall)) x += sign(hsp);
hsp = 0;
}
x += hsp;
// Y
if (place_meeting(x, y + vsp, obj_wall)) {
while (!place_meeting(x, y + sign(vsp), obj_wall)) y += sign(vsp);
vsp = 0;
}
y += vsp;
Мини-чеклист
- Сначала “ввод” → потом “скорость” → потом “коллизии”.
- Нормализуйте диагональ, если используете 2D движение.
- Параметры (скорость/ускорение/трение) держите в
Create— их удобно твикать. - Когда появятся прыжки/гравитация,
vspстанет вашей базой и ничего ломать не придётся.