Каким образом лучше реализовать такую карту на canvas?
Есть разные локации, для каждой локации есть своя картинка в jpg размерами от 3440*1440 (есть и в 10 раз большего размера картинки), на каждой картинке есть свои области для взаимодействия (можно ходить, доп. действия и пр.). Области имеют разные формы, не стандартные фигуры (прямоугольники, круги и пр.).
Также на карте нужно отображать героя игрока, различные объекты, героев других игроков. А также, игроку, чтобы перемещать своего героя по карте, нужно рисовать путь. При этом нужно отслеживать, через какие области для взаимодействия проходит путь (и соответствующе реагировать на это).
Подскажите, какой лучший вариант решения для отслеживания, над каким объектом на карте находится курсор?
И при этом, чтобы этот вариант мог обеспечить хорошую производительность, с такими-то огромными картинками?
Знаю про такие варианты:
1. Для каждой картинки сделать такого же размера картинку png, на которой обрисовать индивидуальными цветами все нужные области. На странице ставить два элемента canvas, один под другим, на нижнем отрисовывать png, а на верхнем (который и будет виден игроку) – jpg. И по координатам курсора определяем цвет на нижнем – так можно определить область.
2. Тот же принцип, что и в 1, только вместо закрашивания полностью цветом, обрисовывать области путями svg. А на странице для координат курсора определять, входят они в какой-либо из путей или нет.
2. Для каждой картинки составить и хранить в файле на сервере массив координат пикселей с соответствующим номером области. На страницу игроку подгружать картинку локации и отправлять сохранённый массив координат – легко определяем области. Но остаётся тот же вопрос для динамических объектов..
3. Возможно есть подходящие библиотеки для всего этого? Если есть, то какие?
Что думаете насчёт них?
Насчёт огромных картинок, думаю порезать каждую на несколько меньшего размера, и подгружать нужные из них, когда координаты героя окажутся близко к краям холста. Или есть вариант лучше?
Можете вкратце объяснить принцип работы этого в моём случае?
Мне поверх канваса или под ним отобразить свг областей? Или так как я описала в варианте 2?
Alixx, в данном случае можно полностью всё сделать на свг.
Собственно, мне неясно что тебе неясно из скинутых мной ссылок? Карту можно на бекграунд поставить, но лучше разрезать и в свг запихнуть фоном запихнуть. Хотя можно и неразрезать, а просто цссом смещать картинку в нужную позицию.
Впрочем, чтобы сгенерировать path для свг стоит разметить области и далее пнгшку в свг конвертировать.
Также на карте нужно отображать героя игрока, различные объекты, героев других игроков. А также, игроку, чтобы перемещать своего героя по карте, нужно рисовать путь
И потом ещё анимацию делать для разных действий.
Поняла сейчас, что вы предлагаете, но нужен канвас..
WbICHA, не подходит. Рисовать путь надо "как в paint", поверх фона с свг надо размещать другие объекты - png картинки (хоть и со своим свг), т.е. обычные прямоугольные элементы, которые своими краями будут перекрывать другие элементы. У пользователя есть прямой доступ ко всем элементам через инструмент разработчика. Плавной последовательной анимации не сделать - только то, что может css + js. Получается как-то ещё более загонно, чем на канвасе.
Alixx, зачем? Это довольно сложная и очень бесполезная реализация в рамках данной задачи. Тебе достаточно фиксировать по каким объектам свг прошёлся курсор во время указания пути.
т.е. обычные прямоугольные элементы, которые своими краями будут перекрывать другие элементы.
И что же мешает их запихнуть в бегграунд отдельного элемента свг, чтобы он не выходил за рамки?
Да, этот момент будет реализовать сложнее, чем в канвасах, но на фоне моментов, которые упрощают использование свг, это небольшая плата.
У пользователя есть прямой доступ ко всем элементам через инструмент разработчика.
И?
Плавной последовательной анимации не сделать - только то, что может css + js.
Эм, а что мешает? Более того, с учётом того, что это часть дома, транзишн на элементы свг также прекрасно воздействует, в то время как на канвасе всю плавность придётся реализовывать самой.
Получается как-то ещё более загонно, чем на канвасе.
Канвас 2д ─ это достаточно низкоуровневые операции, в следствии чего множество желаемых эффектов придётся воплощать самостоятельно.
Так что если есть такое большое желание поработать с канвасом, то готовься страдать.)
Alixx, и да, я уже полгода пытаюсь начать делать (лень) нечто схожее, что и ты, так что я тебе расписал то, как я такое реализовывал бы.
Изначально я тоже планировал делать всё через канвас, но потом я пришёл к выводу, что это крайне геморойно.
WbICHA, откройте любую браузерную игру и вы увидите там канвас, свг используют разве что для окон с незначительной информацией, сама же игра - вся на канвасе. В данном случае свг даже не рассматривается.
Alixx, что за абсолютное непонимания, что каждой технологии своё место?
Хорошо, давай взглянем на https://surviv.io/, вся игра на канвасе, кроме, внезапно, всех кликабельных элементов, они на дивах.
Искать схожий пример мне лень, поскольку абсолютное большинство браузерных игр вообще не имеют кликабельного интерфейса непосредственно во время игры.
Канвас нужен при постоянной динамике, тебе же нужна практически статичная сцена со множеством кликабельных элементов сложной формы. Так скажи мне, зачем тебе в таких условиях канвас? В 99% играх позиция мыши использует лишь для расчёт направления? И это очень простая операция, в отличии от расчёта пересечений с объектами сложной формы.
Короче, хочешь писать на канвасах? Пиши. Только я себе слабо представляю, как ты реализуешь всё, что задумала за адекватное количество времени.
WbICHA, для меня тут 2 основных момента - нельзя рисовать путь как в paint, нужно именно такую дать возможность игроку, да. И прямой доступ к объектам через инструмент. Т.о. можно просто в стилях объектов менять их места, удалять и менять как угодно. По мне так замучаешься все проверки на это сочинять. И будет постоянная динамика - одновременное движение и героев других игроков и их круги обзора, анимация разных объектов и природы (напр., течение воды).
И прямой доступ к объектам через инструмент. Т.о. можно просто в стилях объектов менять их места, удалять и менять как угодно.
И каким же образом это является минусом? Вернее это минус, только канвас от него вообще никак не спасает, как и всё, что находится у клиента.
Во-первых, все данные, с которыми будет работать код у клиента, будет, внезапно, в самом коде. То есть изменение дома приведёт лишь к визуальным изменением у клиента, не более.
Во-вторых, всё, что не относится к отображению информации, должно выполняться на сервере.
В-третьих, на сервере должна проводиться полная проверка валидности действий, поскольку клиенту ничего не мешает отправить запрос серверу через тот же fetch, вручную прописав всё, что он хочет.
Иными словами, реализация фронка никаким образом не повлияет на реализацию бека, при любой реализации необходимо будет делать одни и те же проверки.
И будет постоянная динамика - одновременное движение и героев других игроков и их круги обзора
Это всё статика (почти). Обзор всё равно завязан на иконке/фигурке игрока и с свг будет достаточно перемещать весь элемент героя со всем, что к нему относится.
Единственное "но": если объекты надо перемещать с разной скоростью, то реализацию надо будет писать самому. Или искать готовую. Но в канвасах её итак и так придётся реализовывать.
анимация разных объектов и природы (напр., течение воды).
У меня большие сомнения, что ты собираешься реализовывать детализированную анимацию с кучей кадров. То есть всё это можно реализовать через видео/таймауты, но тут надо смотреть, конечно.
В любом случае никто не мешает использовать анимированный канвас на фоне прозрачного элемента свг.
И про динамику ты неверно меня поняла. У тебя динамики будет минимум. В большинстве текущих браузерных игр канвас необходим, т.к. каждый следующий кадр будет практически новым, а у тебя есть карта, которая сама по себе статична. Объекты на карте большую часть времени тоже статичны.
На выходе у тебя получится статичная игра с элементами динамики, а ты в первую очередь смотришь на динамичные игры с элементами статики, что в корне неверно.
WbICHA, хорошо, поняла вас насчёт динамики. Вы так настаиваете, что я всерьёз теперь думаю на свг перейти, как вы советуете. В целом вроде всё понятно, всё реально, даже для рисования можно поверх всего канвас налепить и по нему рисовать путь, по координатам потом смотреть, в какие свг попадает путь. Получится же так сделать?
И как быть с передвиганием карты? У игрока окно карты, напр. 1500х800, а картинки все от 3440х1440. Поэтому показываем всегда часть карты, и игрок её может передвигать зажав лкм.
И ещё вопрос, т.к. с свг я никогда не работала, если в фоне показана часть картинки, то нужны и только части свг, соответствующие для этой части фона. Часть фона показать просто с css, а часть свг показать можно?
даже для рисования можно поверх всего канвас налепить и по нему рисовать путь
Alixx, можно и так, конечно, но есть важный нюанс: если канвас будет перед свг, то выделить свг курсором будет невозможно. Именно поэтому я и писал про альтернативу рисования пути через свг.
И как быть с передвиганием карты?
Тут как раз вообще нет проблем, будет 1 большой свг с множеством элементов внутри. Достаточно будет просто сдвигать свг. Или же просто использовать стандартные полосы прокрутки.
И ещё вопрос, т.к. с свг я никогда не работала, если в фоне показана часть картинки, то нужны и только части свг, соответствующие для этой части фона. Часть фона показать просто с css, а часть свг показать можно?
Я не думаю, что возникнут проблемы с производительностью, а значит ничего не мешает сразу отрендерить весь свг. По сути, это дом, часть дома будет за границами экрана, что абсолютно нормально.
В целом, если что, пиши сюда, мне самому интересно, если найдутся какие-то неприятные (или приятные) нюансы, которые я пропустил.
если канвас будет перед свг, то выделить свг курсором будет невозможно.
Почему? А elementfrompoint разве не подойдёт?
Тут как раз вообще нет проблем, будет 1 большой свг с множеством элементов внутри. Достаточно будет просто сдвигать свг. Или же просто использовать стандартные полосы прокрутки.
Погоди, не поняла сейчас вообще. Полосы прокрутки сразу исключаем. Это игра, а здесь важна любая визуальная часть. Поэтому хорошо бы сделать как drag&drop - зажал лкм в точке фона и двигаешь фон.
Но! Не получится для фона загружать картинки целиком - они весят десятки мб и размером 20000х10000px (примерно пишу). Не каждый слабый комп/ноут такое потянет. Поэтому такие картинки нарежу на квадраты и буду подгружать по мере надобности. А как с свг? Его можно загрузить целиком, да, но спозиционировать и уменьшить масштаб под текущий размер фона можно?
В целом, если что, пиши сюда, мне самому интересно, если найдутся какие-то неприятные (или приятные) нюансы, которые я пропустил.
Возможно, я чего-то не понимаю, но каким образом он может вообще подойти? Канвас же будет на переднем плане. Разве что elementsFromFoint, но если нужен эвент на ховер, то эта операция на моусмув будет достаточно ресурсопрожорлива, хотя здесь могу ошибаться.
Но! Не получится для фона загружать картинки целиком - они весят десятки мб и размером 20000х10000px (примерно пишу). Не каждый слабый комп/ноут такое потянет. Поэтому такие картинки нарежу на квадраты и буду подгружать по мере надобности.
Разумно. Так же предложу дополнительно сжать изображения, до 90-95%, если речь о жпг, глазом не отличишь от оригинала.
А как с свг? Его можно загрузить целиком, да, но спозиционировать и уменьшить масштаб под текущий размер фона можно?
Возможно, я чего-то не понимаю, но каким образом он может вообще подойти? Канвас же будет на переднем плане. Разве что elementsFromFoint,
elementsFromFoint даже не гуглится, нет такого метода.
А elementFromFoint я пользуюсь на странице боя, там drag&drop аватаркиперсонажа (элемент с ней само собой, это я для простоты пишу) и перемещение её по полю по центру курсора. В mousemove делаю display:none аватарки и с elementFromFoint получаю объект под ней и сразу обратно display block. Почему же здесь так же не получится?
Если так, то да, но тогда, имхо, лучше сделать наоборот, свг держать дисплей нон и когда надо диплей блок/флот/что угодно. Причём можно сделать визабилити хайден или опасити 0, чтобы даже теоретического мерцания не было.
Если так, то да, но тогда, имхо, лучше сделать наоборот, свг держать дисплей нон и когда надо диплей блок/флот/что угодно. Причём можно сделать визабилити хайден или опасити 0, чтобы даже теоретического мерцания не было.
Тут, конечно, в теории всё прикольно, но когда до дела дойдёт, только тогда смогу понять, чё подходит, а что нет (практики во фронте у меня мало, поэтому многое по факту уже смотрю, тестирую). Чёто сколько сегодня читаю про свг, тем больше он меня пугает. Теперь даже больше, чем канвас. Хз, чё делать, честно говоря. Но на сегодня я всё уже, завтра продолжу долбить
практики во фронте у меня мало, поэтому многое по факту уже смотрю, тестирую
Alixx, забавно, я сам нод жс бекендер, поэтому с фронтом тоже много дел не имею.) Так что с этим:
когда до дела дойдёт, только тогда смогу понять, чё подходит, а что нет
полностью согласен.
Чёто сколько сегодня читаю про свг, тем больше он меня пугает.
Меня он тоже пугает местами, честно говоря, но по факту он довольно простой и лаконичный. Path непростой, да, но есть лайфхак, как получить легко и быстро все точки необходимой области. Когда дойдёшь до этого, расскажу, а то там много расписывать, а сейчас мне лень.)
забавно, я сам нод жс бекендер, поэтому с фронтом тоже много дел не имею.)
А у меня php, ларавел)
Попробовала друг над другом поставить свг, див с фоном и канвас для рисования - elementsFromPoint как раз подошёл, в нём указан и сам path. Но, так работает только если код свг поместить в саму страницу. Если же через object вставлять, то уже elementsFromPoint не будет показывать нужный path. Поэтому приходиться, т.к. я использую шаблоны blade, на странице (общая для всей локаций) свг подключать через @include('шаблон с свг кодом картинки'), соответственно, делаю шаблон для конкретной картинки, куда вставляю код её свг. Костыль какой-то, но времени у меня мало, а в инете ничего не смогла найти. Что думаете насчёт этого?
Alixx, с этим шаблонизатором я дел не имел, так что если так реализовывать, то да, импортить надо будет через хтмл.
Но вообще можно создать свг через жс и добавить его на страничку.
Вообще у меня есть старый-старый минипроект с говнокодом (писал, когда ещё только, по сути, начал учить жс), генерирующий гексагоновую карту на свг. Могу скинуть, если хочешь.
WbICHA, эм, так я сама в фш для каждой картинки обрисовываю области и перевожу потом в свг картинку. Я думала на страницу подгружать такую картинку через object, но, ладно хоть проверила сразу, тогда elementsFromPoint не видит внутренности свг. Поэтому теперь код каждой свг картинки помещаю в отдельный для неё подшаблон и его уже подгружаю, тогда на странице получаю сам открытый свг код. Вот такая схема. Мне так не очень нравится, но иначе, чтобы object видел, не знаю как делать.
Alixx, если ты откроешь свг как текст, то у увидешь там пути. Их точно так же можно создать через жс, запихнув в свг, тебе будет достаточно взять точки из сгенерированого тобой свг.
И да, раз у нас такое активное общение, может перейдём на более удобные для этого площадки, а то я уже устал мотать вниз каждый раз... :/