SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › Смещение взаимодействия с объектами
В этой теме 14 ответов, 2 участника, последнее обновление lolomap 5 года/лет, 5 мес. назад.
-
АвторСообщения
-
Сначала я заметил, что персонаж не подходит вплотную к правой и нижней стенкам. Позже, когда я добавил объекты от которых персонаж должен получать урон, я понял, что если находится слева или сверху относительно них, то персонаж реагирует находясь намного дальше самого объекта. Смещение идёт где-то 1-1.75 тайла (у меня 1 тайл равен 32х32 пикселя). Видел тут похожую тему, в которой ответили, что проблема в спрайте (лишняя прозрачная часть), но я думаю, что у меня дело в другом, т.к. я уже перешёл на tiled map editor, и теперь реагирование вроде должно быть привязано к границам самого объекта, а не спрайта, верно? Ещё не могу найти проблему: почему-то вместо того, чтобы постепенно получать немного урона, игрок умирает мгновенно.
Заранее огромное спасибо
Вложения:
You must be logged in to view attached files.Проблему с получением урона решил. Оказалось у меня тип переменной health был int вместо double либо float. Проблема со смещением до сих пор актуальна
Проблема со смещением в спрайте всё же в самом спрайте персонажа. И Tiled Map Editor эту проблему принципиально не решает.
1. Коллизия (столкновение) определяется через пересечение прямоугольника (IntRect) спрайта персонажа с объектом в Tiled Map Editore. В Tiled Map Editore можно настроить довольно точно, так как там объекты не анимированные и вообще квадратные. С ним проблем нет.
У персонажа же обычно прямоугольники для всех фаз анимации одинаковые. И, обычно, они с запасом для картинки персонажа. И если левый верхний край как-то подгоняют, то правый нижний выпирает далеко за собственно картинку.
2. Как проверить так ли это? Легко. Залить каким-нибудь цветом тайлсет персонажа, чтобы он не был прозрачным в игре. Теперь ты увидишь персонажа в цветном квадрате его реального размера. И сможешь проверить, совпадает ли взаимодействие(коллизия) с его реальными размерами.
3. Есть урок на ютубе по ищется по запросу “SFML платформер”, там для загрузки спрайтлиста персонажа используется sprite decomposer. И там можно подогнать прямоугольники более точно.
Но возникает другая проблема. Так как координаты прямоугольника это левый верхний угол, то, например, приседающий персонаж на самом деле подтягивает ноги, а башка его остаётся на том же уровне. Так как сам размер прямоугольника уменьшается, а координаты ху всё те же.
Красивого и рабочего решения я не знаю.
Но виноват однозначно размер спрайта персонажа. Точнее его текущий прямоугольник. Залей цветом тайлсет персонажа и убедишься.
Кстати, придумал как обойти эту проблему.
Создай ДРУГОЙ прямоугольник, поменьше размером (widht и height). А его x,y постоянно приравнивай к x,y спрайта. Используй для расчёта столкновений именно его, а не оригинальный спрайт персонажа.
Получится этакий bounding box.
Решение не красивое, но может сработать.
Большое спасибо. Сегодня попробую
Смог уменьшить смещение поставив кадры анимации вплотную и изменив соответственно размер спрайта. Но, как видно на первом скриншоте, персонаж всё равно не доходит, хотя сам спрайт вроде не мешает. На втором же скриншоте: игрок получает урон только если сам объект 32х32 пересекает камень, а если спрайт пересекает, а нижняя его часть, которая находится в объекте нет, то как на скрине, урон не проходит.
Вложения:
You must be logged in to view attached files.Странно, что после подгона размера объекта под размер спрайта, ничего не изменилось
Заметил странную вещь: при размерах 10х10 спрайт придвигается почти вплотную
Вложения:
You must be logged in to view attached files.Спасибо за советы. Проблема решена путём изменения размеров в функции getRect() и подстановки размеров из этой функции в проверку столкновения.
Получилось:
C++12345678910111213141516if (dX < 0){x = obj[i].rect.left + obj[i].rect.width;}if (dX > 0){x = obj[i].rect.left - 5;}if (dY > 0){y = obj[i].rect.top - 25;}if (dY < 0){y = obj[i].rect.top + obj[i].rect.height;}C++1return FloatRect(x, y, 5, 25);На первом скриншоте, насколько я вижу, тайл странный. Нижний тайл наполовину состоит из стены, наполовину из пола. Или мне кажется?
А, понял, посмотрел тайлы карты, там просто верхняя часть тайла только, а нижняя белая.
На втором скриншоте с пересечением камня он должен получать урон, но не получает?
если сам объект 32х32 пересекает камень, а если спрайт пересекает,
Я думал, что для размеров объекта используется прямоугольник спрайта. Или персонаж тоже 32Х32?
Сорри, на работе сейчас, не могу посмотреть код и запустить.
Сорри, на работе сейчас, не могу посмотреть код и запустить.
Уже нет необходимости. Я решил проблему. И да, коллизия использует прямоугольник спрайта, как оказалось, то что верхняя часть не взаимодействует ни с чем являлось побочным эффектом от общей проблеммы
Такой вопрос, размеры персонажа Вы задаёте в тайлед мэп эдиторе? А то не вижу где у игрока w h присваиваются.
5 и 25 как-то маловато кажется, персонаж явно больше 32. Больше смахивает 10×50.
Размеры задаю в константах X_SPR_PLAYER и Y_SPR_PLAYER в файле const.h и передаю их в конструкторе
Ясно. Просто другое интересно. Связано или нет, понять сейчас не могу. Я слишком мало работал программировал вообще и с сфмл в частности
Очевидно, что 5 и 25 в два раза меньше реальных размеров.
НО вы ставили setorigin(w/2, h/2) то есть точка находится посередине спрайта. То есть x и y это середина спрайта и если считать от неё w или h, то они будут в два раза больше, поэтому ваш персонаж на первом скрине не мог подойти ближе, пока Вы не подобрали размеры где-то в половину спрайта вручную.
В общем из-за сеториджин получается смещение между размерами спрайта и объекта, ибо у вас спрайт выводится в координаты xy с середины, а объект с левого верхнего угла. И спрайт относительно объекта смещён выше и левее.
Мне так кажется. Так что надо теперь совместить прямоугольники в функции
getRect() return FloatRect (x-w\2, y-h\2,w,h)
О, теперь понятно. Большое спасибо за помощь!
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.