Я прошу прощения за несколько общий заголовок. Я действительно не очень разбираюсь в том, как выполнить то, что я пытаюсь сделать, что затрудняет даже поиск возможного решения.
Я пытаюсь реализовать своего рода маркер пути (может быть, есть наиболее подходящее название для него, но это лучшее, что я мог придумать).
Перед игроком будет маркер пути, который будет определять, как игрок будет двигаться после того, как он закончит планирование своего хода. Игрок может щелкнуть и перетащить маркер в выбранную им позицию, но маркер можно перемещать только в пределах определенной рабочей области (серый бит).
Итак, я застрял с двумя проблемами:
Прежде всего, как именно я должен определить эту рабочую область? Я могу представить, может быть, два вектора, в которых игрок является отправной точкой для формирования рабочего угла, и, может быть, эти две дуги могут исходить из кругов, в центре которых находится игрок, но я определенно не знаю, как все это поместить вместе.
И во-вторых, после того как я определил область, где маркер может быть размещен, как я могу обеспечить, чтобы маркер оставался только в этой области? Например, если игрок щелкает и перетаскивает маркер, он может свободно перемещаться в пределах рабочей области, но не должен выходить за границы области. Так, например, если игрок начинает перетаскивать маркер вверх, он будет двигаться вверх до тех пор, пока не достигнет конца рабочей области (первая диаграмма ниже), но если после этого игрок начнет перетаскивать вбок, маркер должен следовать за перетаскиванием, оставаясь неподвижным. в пределах области (вторая диаграмма ниже).
Я надеюсь, что это не слишком запутанно. Спасибо, парни.
Изменить: В случае, если это имеет значение, я использую C ++ с Marmalade SDK.
Ответы:
Вы можете определить рабочую область, такую как в вашем вопросе, с тремя значениями:
Эти значения будут основаны на центральной точке, которая может быть или не быть позицией игрока. Форма обрабатываемой области зависит от того, где вы разместите эту точку.
В приведенном выше примере центральная позиция находится на некотором расстоянии (скажем, 50 единиц) позади игрока. Это можно легко рассчитать как:
Чтобы ограничить положение маркера этой обрабатываемой областью, сначала переместите маркер, как обычно. Затем проверьте расстояние между центральной точкой и маркером:
Наконец, проверьте угол наклона маркера в указанном диапазоне. Я буду использовать псевдокод для этого:
Посмотрите вокруг, как повернуть точку вокруг другой. Это можно сделать с помощью тригонометрии или матрицы преобразования.
Вы также можете принять во внимание размер маркера и сделать радиус и угол немного меньше, чтобы компенсировать.
Редактировать: подумав, может показаться более естественным, если сначала проверить угол, а затем расстояние, поэтому попробуйте обе альтернативы!
источник
cos
иsin
операцию, так что я не уверен. Но для вычисления этих двух векторов вам также нужно повернуть их, хотя вам нужно делать это только при изменении вектора вперед. В любом случае это не должно иметь большого значения, выберите тот, который вы предпочитаете реализовать.Я думал о том, как можно решить проблему, если форма была неправильной, и никто не мог определить ее математически. Предупреждение: это грязное решение, не для слабонервных.
1. Возьмите свою область:
2. И преобразовать его в монохроматическое растровое изображение:
и назовите его scale_0
3. Клонируйте растровое изображение и уменьшите его до 50%:
и назовите его scale_1
4. И так далее, пока не появится растровое изображение менее 4 пикселей в ширину / высоту:
шкала: 2, 3, 4, 5, 6
5. Теперь у нас есть монохромные растровые изображения разного разрешения:
6. Возьмите последнее изображение (здесь «scale_6») и переберите все его пиксели.
x = Math.pow ( 2, scale_level );
где scale_level - это число, которое мы добавили после «scale_». Мы также можем назвать его уровнем дерева квадрантов, хотя на самом деле мы не работаем с деревом квадрантов. Сделайте то же самое с y.continue
перейти к следующему шагу циклаx *= 2; y*=2;
чтобы перевести их в координаты на следующем изображении (предыдущий масштаб)7. Возьмите предыдущее изображение (здесь «scale_5»), но не просматривайте все пиксели; начинаются с x = сохраненные_x и заканчиваются с x = сохраненные_x + 2, то же самое с y. То есть, поскольку теперь вы будете проходить только 4 пикселя для каждого уровня! Остальное как на с. 6.
8. Возьмите первое изображение (самое большое = изображение с наибольшим разрешением), снова пройдитесь по 4 пикселям, и у вас наконец получится пиксель, ближайший к курсору мыши:
9. Однако я рассматриваю «М» как точку здесь. Если вы хотите, чтобы это был полностью подходящий круг, вам нужно
circle.radius
сначала сжать (сжать) форму на пиксели.Я подумал, что добавлю, что этот алгоритм будет работать, только если вы будете использовать не монохроматические, а полутоновые изображения и рассматривать пиксель как «полный», если он не белый, и как «пустой», если он точно белый ... ИЛИ, если вы изменяете размер алгоритм меняет каждую группу из 4 пикселей на 1 черный пиксель каждый раз, когда хотя бы один из этих 4 пикселей не был белым.
источник
closest
и проверяете расстояние до самой дальней точки вclosest
- давайте назовем расстояниеfurthest_dist
. Теперь вам нужно убрать из списка все ячейки, у которых есть ближайшая точка дальше, чемfurthest_dist
и перейти на уровень глубже. Итак, вместо чего-то вроде этого: i.imgur.com/4UuFo.png Это что-то вроде этого: i.imgur.com/dyTT3.png