Урок 17 SFML перетаскивание объекта мышью

Вы знаете , что сущ-ет такой способ взаимодействия с интерфейсом “Drag and drop”. Буквально означает “тащи и бросай”. Ссылка на более подробное описание https://ru.wikipedia.org/wiki/Drag-and-drop

В этом уроке мы реализуем этот способ взаимодействия , а именно – взаимодействие игрока с персонажем. 

Видеоверсия: http://www.youtube.com/watch?v=ceF8dXecnBY

Игрок сможет двигать персонажа, как только нажмет левую клавишу мыши. Пример этого взаимодействия вы можете встретить не только в играх типа шашки, шахматы и тд, но и при перетаскивании файлов и папок в операционных системах, например Windows.

В int main() объявим логическую переменную, которая будет отвечать за “левый щелчок мыши по спрайту”.

А так же две переменные, которые будут корректировать нажатие и перемещение:

 




 

Далее перед событиями Event пишем:

Координата курсора забирается изначально по позиции курсора в окне, но мы можем переводить координаты в игровые, как у игрока. Если у вас не планируется скроллинг карты, то вам не обязательно переводить их (в шашках например такое не требуется). Но если камера подвинется, то координаты игрока будут уже другими, а курсора теми же, поэтому то и надо их переводить в мировые координаты. Ниже в коде видим вывод этих координат в консоль. Первая координата pixelPos.x не будет больше, чем ширина окна (640 в моем случае) и поэтому когда мы пройдем игроком вправо – программа будет работать не корректно, т.к координата игрока всегда будет больше позиции курсора. Поэтому то и надо переводить в координаты игровые. Вот скриншот , показывающий, что координаты pixelPos.x и pos.x равны до тех пор, пока мы не подвинем камеру влево или вправо.

Вот курсор в крайнем правом углу окна и камера не сдвинута вправо, игрок вправо не ходил:

coordinatecursor648

 

Обе координаты почти 640 и они равны, но как только мы пройдем вправо и камера сдвинется:

coordinatecursor17

Координаты уже не будут равны .pixelPos.x будет принимать координату относительно окна и так же не будет больше его ширины (640), а вот pos.x после преобразования уже ведёт себя “хорошо” для нас.

Далее в цикле событий while (window.pollEvent(event)) пишем:

 

 

Если нажата клавиша мыши,  при этом левая, при этом курсор мыши попадает на спрайт игрока, то:
*выводим в консоль надпись о том , что кликнули,
*запоминаем разность между курсором и серединой спрайта. (не от левого верхнего угла спрайта, т.к спрайт имеет строку в классе игрока sprite.setOrigin(w / 2, h / 2); , но не суть важно)
*делаем переменную “можно двигать” true

Ниже в этом же цикле сделаем обработчик отпускания клавиши, который скажет программе перекрасить персонажа в белый и сделаем переменную “можно двигать” false:

 

После закрытия цикла обработчика событий пишем само движение персонажа за курсором:

Всё, теперь будет работать :)

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

dX и dY служат для корректности, это расстояние до начала спрайта.

centercursor

Мы снимали координаты курсора постоянно при работе программы, лучше будет, если вы сделаете bool переменную, которая отвечает за клик и только после этого снимает координаты. Тогда вы снизите нагрузку на игру. if isMouseClicked == true { isMouseClicked=false; и снимаем координаты}
Или просто при клике – снимать координаты

Код урока:

main.cpp

 

 

Буду благодарен, если поделитесь:
SFML вопросы, прошу, задавайте на форуме.

Добавить комментарий