Game Maker - создание игр | HellRoom Games
Апрель 19, 2025, 23:23:19 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   Game Maker Помощь Правила форума Поиск Календарь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Столкновения(коллизия) двух движущихся объектов  (Прочитано 1190 раз)
0 Пользователей и 1 Гость смотрят эту тему.
kliec
Новичок
*

Репутация: 0
Offline Offline

API: GameMaker Studio 2
Сообщений: 4


« : Май 10, 2022, 08:45:40 »

Доброго времени суток, помогите разобраться, два объекта с разной скоростью speed сталкиваются и один проваливается в другой.




Видео
Видео 2

Мяч отскакивает только событием столкновения с батутом, с кодом:
Код:
direction = point_direction(other.x,other.y,x,y);

Как правильно прописать столкновение чтобы такого не возникало и например отскок был только от верхней поверхности батута? Уже много всего перепробовал, он то застревает, то дёргается если в шаге задаю столкновения.
Вот пример как мне бы хотелось сделать.
Записан
Лер да Рим
On standby...
GM Pro user
*

Репутация: 103
Offline Offline

Пол: Мужской
Награды:
500 сообщений!За постоянность! [50 дней на форуме]
API: Game Maker 8.0 Pro
Сообщений: 896


фрр-фрррр


« Ответ #1 : Май 10, 2022, 10:33:54 »

Я не эксперт в базовых коллизиях, но могу предложить варианты через код.
Суть в том, что у тебя он сталкивается и застревает в доске, постоянно обрабатывая коллизию. Возможно, есть более традиционные методы, но я бы предложил

либо делать некий таймер коллизии:
при столкновении, кроме изменения направления:
Код:
if !col_timer {
direction = point_direction(other.x,other.y,x,y);
col_timer = 2;
}
, в шаге
Код:
if col_timer col_timer--
Т.е. столкновение будет срабатывать раз в несколько шагов, что чревато при очень быстрой скорости и близких отскоках, может не успеть обнулиться. Двух шагов по идее достаточно, чтобы отскочить, но и не слишком много, но всё равно вариант имхо не лучший.

Либо, что надёжнее и правильнее, проверять столкновение ещё до самого столкновения, заранее отпихивая шарик от доски:
Код:
//board - объект доски
if collision_line( x, y, x + lengthdir_x( speed, direction ), y + lengthdir_y( speed, direction ), board, 0, 0 )
dir = point_direction( board.x, board.y, x, y );

x += lengthdir_x( speed, direction );
y += lengthdir_y( speed, direction );


Если нужна проверка только верхней грани, почитай про переменную bbox_top, она отвечает за верхнюю грань столкновения. Либо, если опять же делать кодом, математически - можно упороться в уравнения прямых, находя через координаты (нынешние мяча, новые мяча (со смещением на скорость и направление), левый верхний и правый верхний края доски или стены) точку столкновения с поверхностью и рассчитывая зеркально отражённые координаты с сохранением импульса.
Да, я знаю, я упоролся.



Добавлено: Май 10, 2022, 10:35:43
При первом варианте не забудь заранее объявить col_timer
А при втором используй свою переменную скорости, а не встроенную, т.к. встроенная вроде как сама смещает шарик на speed, и будет двойное смещение.
Записан

Всё гениальное просто.
kliec
Новичок
*

Репутация: 0
Offline Offline

API: GameMaker Studio 2
Сообщений: 4


« Ответ #2 : Май 10, 2022, 17:19:45 »

Я не эксперт в базовых коллизиях, но могу предложить варианты через код.
Суть в том, что у тебя он сталкивается и застревает в доске, постоянно обрабатывая коллизию. Возможно, есть более традиционные методы, но я бы предложил

либо делать некий таймер коллизии:
при столкновении, кроме изменения направления:
Код:
if !col_timer {
direction = point_direction(other.x,other.y,x,y);
col_timer = 2;
}
, в шаге
Код:
if col_timer col_timer--
Т.е. столкновение будет срабатывать раз в несколько шагов, что чревато при очень быстрой скорости и близких отскоках, может не успеть обнулиться. Двух шагов по идее достаточно, чтобы отскочить, но и не слишком много, но всё равно вариант имхо не лучший.

Либо, что надёжнее и правильнее, проверять столкновение ещё до самого столкновения, заранее отпихивая шарик от доски:
Код:
//board - объект доски
if collision_line( x, y, x + lengthdir_x( speed, direction ), y + lengthdir_y( speed, direction ), board, 0, 0 )
dir = point_direction( board.x, board.y, x, y );

x += lengthdir_x( speed, direction );
y += lengthdir_y( speed, direction );


Если нужна проверка только верхней грани, почитай про переменную bbox_top, она отвечает за верхнюю грань столкновения. Либо, если опять же делать кодом, математически - можно упороться в уравнения прямых, находя через координаты (нынешние мяча, новые мяча (со смещением на скорость и направление), левый верхний и правый верхний края доски или стены) точку столкновения с поверхностью и рассчитывая зеркально отражённые координаты с сохранением импульса.
Да, я знаю, я упоролся.



Добавлено: Май 10, 2022, 10:35:43
При первом варианте не забудь заранее объявить col_timer
А при втором используй свою переменную скорости, а не встроенную, т.к. встроенная вроде как сама смещает шарик на speed, и будет двойное смещение.

Спасибо за подробный ответ, пока что не получилось сделать, но на счет обсчёта в каждом шаге стало понятно куда копать. Просто там ещё несколько вещей которые нужно учитывать, что например шар(мяч) зажимается и останавливается между стеной и доской даже если только сталкивается с верхней поверхностью, я решал это просто остановкой доски при приближении к стене + ширина экземпляра, но это не выглядит как хорошее решение и из-за недоработки столкновения всё равно визуально смотрится кривовато.

Второй способ работает почти как надо, но нужен более подробный расчёт для каждой ситуации я полагаю, благодарю за подсказку. Всё таки склоняюсь к 3му варианту, насколько я понял, нужно получить данные х, у точки столкновения с верхней плоскостью и потом отражать vspeed и hspeed, в зависимости от направления мяча, выложу если получится.

Добавлено: Май 11, 2022, 14:37:12
В общем столкновения через collison_line стали выглядеть намного лучше, но вот как решить проблему с тем, когда мяч движется перпендикулярно вниз, а доска движется быстрее горизонтально и врезается внутрь мяча у стены я совсем не понимаю.

Однако пока что хороший способ оказался сделать 3 маски для каждой из ситуаций: обычная, доска прижата к правой стороне, доска прижата к левой. Во время прижатия маска уменьшается со стороны стены, на ширину мяча, за счёт этого получаем приятный на вид отскок и не вжимаем в стену маску мяча, собственно пока что такое решение.
« Последнее редактирование: Май 11, 2022, 14:38:12 от kliec » Записан
Dmi7ry
Гл. Администратор
*

Репутация: 1379
Offline Offline

Пол: Мужской
Награды:
5000 сообщений!За постоянность! [200 дней на форуме]За лояльность! [+1000 репутации]За помощь в развитии форума!Знаток Game Maker!За помощь новичкам!
API: GameMaker Studio Master
Деятельность: Code, design
Сообщений: 6626



WWW
« Ответ #3 : Май 11, 2022, 18:51:22 »

В общем столкновения через collison_line стали выглядеть намного лучше, но вот как решить проблему с тем, когда мяч движется перпендикулярно вниз, а доска движется быстрее горизонтально и врезается внутрь мяча у стены я совсем не понимаю.
Я бы сделал просто два случая:
1. Если мяч ниже верха доски на заданную величину (например, на 1/3 или 1/2 высоты доски), то столкновения с доской игнорируются и мяч пролетает вниз
2. Если же мяч выше, тогда он просто выталкивается на поверхность биты
Записан

- А какой, собственно, командой процессора колобок ест черта?
- Командой EAT...
Справка и FAQ в правом верхнем углу...
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

HellRoom Games © 2006-2012 All Rights Reserved
Powered by SMF 1.1.21 | SMF © 2013, Simple Machines
Страница сгенерирована за 0.13 секунд. Запросов: 28.