Зрение монстра на эвентах.

Больше
13 года 3 нед. назад - 13 года 3 нед. назад #59856 от knyazkot
Мануал по написанию монстров, которые бесцельно слоняются по карте и нападающих на игрока только после того, как он войдет в их поле зрения.

Начнем.
для начала создадим эвент назовем его "враг". Установки: "автономное движение" случайно, что-бы наш монстр слонялся без дела, скорость и частота движения по желанию. "Запуск от..." параллельно.

И так, начинаем писать эвент.
Сначала нам нужно чтобы эвент рассчитывал позицию игрока относительно врага. Для этого нам понадобиться две переменных, первая будет рассчитывать Х ("враг1 поз Х" на скиншете), вторая будет соответственно рассчитывать У ("враг1 поз у" на скриншете). Даем каждой переменной значение Х и У игрока относительно карты, потом вычитаем Х и У врага относительно карты.
Все просто, но тут же сталкиваемся с проблемой, в некоторых положениях игрока относительно врага наши переменные принимают отрицательное значение, что создает проблемы в вычислении.
Приступаем к следующему этапу.

Модулирование отрицательных чисел.
Нам понадобиться всего два условия, принцип прост. Если переменная меньше либо равна -1, то ее нужно умножить на -1. Применяем это к обоим переменным, как показано на скриншете.

Ну и наконец, расчет радиуса зрения врага.
нам понадобиться одна переменная которая будет проверять вошел игрок в поле зрения врага или нет ("враг1 зрение" на скриншете).
Теперь нужно сделать переменную "враг1 зрение" равной сумме переменных "враг1 поз Х" и "враг1 поз у". для этого сначала придаем значение равное первой переменной, а потом прибавляем вторую (равность, а потом сложение нужно для того, что-бы условия оставались верными и при повторе цикла. При простом сложении этого не происходит).
Теперь выставляем условие: если переменная "враг1 зрение" меньше либо равна 4 то враг видит игрока. Я поставил именно 4 так как мне это было удобно для игры, но поставить можно любое положительное число. Его значение будет радиусом зрения врага. На втором скриншете красным обозначен радиус зрения врага при значении 4, а синим при значении 2. На этом все, простите за безграмотность, надеюсь этот мануал будет полезен.
Последнее редактирование: 13 года 3 нед. назад пользователем knyazkot.
Спасибо сказали: AnnTenna, DeadElf79, strelokhalfer, caveman, SailorSaturn, Maximka68, LiRo

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Программист Ruby Разработчик Проект месяца 3 место Проект месяца 2 место Проект года 1 место Проект года 3 место Учитель Оратор Паладин Проект месяца 1 место 2 место Готв 3 место Организатор конкурсов Ветеран
Больше
13 года 3 нед. назад #59858 от caveman
"простенько и со вкусом", а портянки обрезанных картинок по ссылке, приведенной мной выше не прочитать все-равно.

Хорошо бы еще придумать, что, если игрок сбежит от агрессивного монстра, он может успокоиться :blink:

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 1 место Программист Ruby Писатель 3 место 3 место Учитель Организатор конкурсов 1 место в Готв Ветеран Проект месяца 2 место
Больше
13 года 3 нед. назад - 13 года 3 нед. назад #59859 от DeadElf79
Пещерный, вглядись в последнее условие на втором скриншоте:
Если переменная <=4 то
Враг нападает!!!
Иначе
Сюда ставим агрессию в положение "Выкл."
Конец

Хотя в идеале было бы неплохо сделать гладкий спад агрессии, чтобы выполнялся в зависимости от расстояния. А то получается - подбежал к врагу, стукнул, отбежал на три метра и он уже все забыл!
А еще, неплохо было бы припилить сюда зависимость от направления движения врага и соответственно, вычислять не по радиусу, а по конусу зрения. В идеале - делать вычисление данного конуса в зависимости от области видимости (смотри иллюстрацию ниже).
[IMG

Нарисовал за десять минут, надеюсь все понятно.
Кто возьмется реализовать подобное? :laugh:
Последнее редактирование: 13 года 3 нед. назад пользователем DeadElf79.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Программист Ruby Разработчик Проект месяца 3 место Проект месяца 2 место Проект года 1 место Проект года 3 место Учитель Оратор Паладин Проект месяца 1 место 2 место Готв 3 место Организатор конкурсов Ветеран
Больше
13 года 3 нед. назад #59861 от caveman
подозреваю, что на селфсвитч A = true там активируется вторая закладка, где монстр набигает на тебя, так что там ловить надо это иначе.

Не напоминай мне про конусы и области видимости - я вчера до 3х ночи просидел с руби и виски, разбираясь со стенами =)

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 1 место Программист Ruby Писатель 3 место 3 место Учитель Организатор конкурсов 1 место в Готв Ветеран Проект месяца 2 место
Больше
13 года 3 нед. назад #59862 от DeadElf79
Виски? Новый язык программирования? Или...

На самом деле, я рассчитывал, что автор, раз сумел решить задачу с радиусами, вполне способен решить задачу с конусами!

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Программист Ruby Разработчик Проект месяца 3 место Проект месяца 2 место Проект года 1 место Проект года 3 место Учитель Оратор Паладин Проект месяца 1 место 2 место Готв 3 место Организатор конкурсов Ветеран
Больше
13 года 3 нед. назад #59863 от caveman
Или...
конус не так сложно, со второй картинкой интереснее)

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 1 место Программист Ruby Писатель 3 место 3 место Учитель Организатор конкурсов 1 место в Готв Ветеран Проект месяца 2 место
Больше
13 года 3 нед. назад #59864 от DeadElf79

конус не так сложно, со второй картинкой интереснее)

Через террайн-таг, как решил Khas, не?

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Программист Ruby Разработчик Проект месяца 3 место Проект месяца 2 место Проект года 1 место Проект года 3 место Учитель Оратор Паладин Проект месяца 1 место 2 место Готв 3 место Организатор конкурсов Ветеран
Больше
13 года 3 нед. назад #59865 от caveman
Надо не забыть про то, что поле за препятствием может правильно не иметь тега и это тоже вычислять.


Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 1 место Программист Ruby Писатель 3 место 3 место Учитель Организатор конкурсов 1 место в Готв Ветеран Проект месяца 2 место
Больше
13 года 3 нед. назад - 13 года 3 нед. назад #59866 от DeadElf79
Красный с движением несочетаем, при отсутствии попиксельного передвижения, конечно.
Ну, я имеел ввиду так - если перед персом препятствие в зоне видимости, то начиная с тайла препятствия и далее, по вектору от персонажа к дальней границе видимости, тайлы не учитываются вообще. То есть, проще говоря, считаются невидимыми в любом случае.
Вот придёт Князь-Кот, почитает наш диалог, да и бросит на третьем посту))
Последнее редактирование: 13 года 3 нед. назад пользователем DeadElf79.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Программист Ruby Разработчик Проект месяца 3 место Проект месяца 2 место Проект года 1 место Проект года 3 место Учитель Оратор Паладин Проект месяца 1 место 2 место Готв 3 место Организатор конкурсов Ветеран
Больше
13 года 3 нед. назад #59867 от caveman
В любом случае обсчет не только по тегам)

А разве простые предположения нельзя все-равно реализовать? (нет сетки на работе, так что я твоей картинкой пользуюсь)

Если верхние 3 клетки - стена (верхний ряд красным), то при таком угле обзора через две клетки вперед не видно будет 5 клеток (нижний ряд красным)

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 1 место Программист Ruby Писатель 3 место 3 место Учитель Организатор конкурсов 1 место в Готв Ветеран Проект месяца 2 место
Больше
13 года 3 нед. назад - 13 года 3 нед. назад #59868 от DeadElf79
Что ты имеешь ввиду под предположением?
Сейчас я скачаю муви-гир и нарисую тебе анимашку, как я предполагаю эти расчеты.
Последнее редактирование: 13 года 3 нед. назад пользователем DeadElf79.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Программист Ruby Разработчик Проект месяца 3 место Проект месяца 2 место Проект года 1 место Проект года 3 место Учитель Оратор Паладин Проект месяца 1 место 2 место Готв 3 место Организатор конкурсов Ветеран
Больше
13 года 3 нед. назад #59869 от caveman
зная угол конуса зрения мы можем забить где-то некоторые предположения, как пример на картинке выше (3 клетки стена через клетку => через +2 уже 5 тайлов невидимых)

ну и вообще, школьный курс геометрии никто не отменял, но скорей всего придется писать скрипты, чего автор категорически не желает)

Спасибо, ты развеял мою скуку на работе, попрусь домой мучать стены Кхасом. Инструкцию по нему, кстати, перевел на русский :)

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 1 место Программист Ruby Писатель 3 место 3 место Учитель Организатор конкурсов 1 место в Готв Ветеран Проект месяца 2 место
Больше
13 года 3 нед. назад - 13 года 3 нед. назад #59870 от DeadElf79
Пещерный, ты сейчас сказал то же самое, что я тебе и сказал. Именно это я имел ввиду под вектором.
Но картинку все равно нарисую.
Вот картинка:
[IMG


Надеюсь, анимация отображается.
Желтые стрелки означают тайл, который проверяется на принадлежность к стенам. Желтые крестики означают, что тайл - стена и дальше просчет не идет.
Как можно увидеть, каждая стрелка независима от другой и движется от игрока к границе видимости только вперед. Если стрелка встретиться с главным героем, то будет определено, что герой найден и враг направится к нему. Если герой встал за стенкой и, тем самым, оказался вне зоны видимости, то ни одна стрелка-вектор до него не дойдет. Реализуется на ивентах, хотя ивент получается довольно большой.
Последнее редактирование: 13 года 3 нед. назад пользователем DeadElf79.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
13 года 3 нед. назад #59889 от knyazkot
я еще не пробовал, но мне кажется, это возможно. Если инициировать вызов эвентов которые как бы будут пробегать по прямой от врага и при столкновении с игроком инициировать агрессию. Хотя это только теория надо проверить.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Программист Ruby Разработчик Проект месяца 3 место Проект месяца 2 место Проект года 1 место Проект года 3 место Учитель Оратор Паладин Проект месяца 1 место 2 место Готв 3 место Организатор конкурсов Ветеран
Больше
13 года 3 нед. назад #59891 от caveman
благодарности за первый пост, я придумал, куда мне эти монстры пригодятся, именно с круговым зрением :)

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 2 место Ветеран Оратор
Больше
13 года 3 нед. назад #59895 от Green-Leo

knyazkot пишет: я еще не пробовал, но мне кажется, это возможно. Если инициировать вызов эвентов которые как бы будут пробегать по прямой от врага и при столкновении с игроком инициировать агрессию. Хотя это только теория надо проверить.

А это неплохая идея, она ведь проще даже чем вписывать координаты и т.д.
Я запомню)

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Учитель Даритель Стимкея 3 место
Больше
11 года 8 мес. назад #73171 от Jas6666
Может ли кто небудь выложить демку с этим уроком, не понимаю куда что сделать надо. или выложить побольше скриншотов что и как надо делать
Спасибо сказали: Ren310

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
11 года 8 мес. назад #73231 от Dprizrak1

Jas6666 пишет: Может ли кто небудь выложить демку с этим уроком, не понимаю куда что сделать надо. или выложить побольше скриншотов что и как надо делать

yadi 24Мб в архиве есть сама игра где реализована боёвка и "демо боёвки" и ещё один какой то файл, не помню зачем он там :silly:

(^_^)
Этот форум слишком умный для меня
Спасибо сказали: AnnTenna, DeadElf79, Jas6666, LiRo

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Оратор 1 место в Готв 3 место Готв 2 место Учитель Композитор Победитель конкурса Организатор конкурсов
Больше
10 года 3 мес. назад - 10 года 3 мес. назад #89684 от yuryol

DeadElf79 пишет: А еще, неплохо было бы припилить сюда зависимость от направления движения врага и соответственно, вычислять не по радиусу, а по конусу зрения. В идеале - делать вычисление данного конуса в зависимости от области видимости (смотри иллюстрацию ниже).


Кто возьмется реализовать подобное? :laugh:


Вызов принят :mad: Примерно неделю назад я взялся за реализацию стелс-механики игры. Сначала за 15 минут сделал зрение врага ограниченное квадратом как в первом посте данной теме плюс ограничил его по направлению взора врага. Но это показалось совсем примитивным и неинтересным, поэтмоу склонился в сторону конусовидного поля зрения. Наткнувшись на эту тему еще более уверовал в правильность этого решения.
В итоге сделал стелс-механику с конусовидным зрением и препятствиями, за которыми игроку можно прятаться дабы остаться незачмеченным.
Решил сделать небольшой урок реализации. Возможно, кто-то будет на неоптимизированность,но как уж умею, всё-таки я без учета армейки всего чуть больше года в мейкере. Пока сделал только одно направление,остальные в принципе делаются аналогично этому.
Итак. Разжевал как можно более подробно.

1. Делаем ограничение зрения в зависимости от направления взора врага
Нарисовал табличку в Эксель с координатами для более ясного представления ситуации.



Зелёный квадратик - враг. Он смотрит вверх. Голубые поля - область взора врага.
Тут всё просто. Следует определить направления события, затем проверить, стоит ли Игрок в этом голубом поле зрения врага.
1) Создаем условие "Если событие "враг" смотрит вверх,то... (ошибка перевода в мейкере, последнее "вправо" - это на самом деле "вверх")

ВНИМАНИЕ: Спойлер!


2) внутри него создаем ветвление "если координата У(игрек) игрока МЕНЬШЕ или РАВНО координаты У Врага, то..." (не забываем что У начинается сверху вниз, как и в Эксель).
Для удобства ветвление пишем скриптом $game_player.y<=$game_map.events[1].y
,где
$game_player.y - координата игрока по У.
$game_map.events[1].y - координата события 1 (врага) по У.
ВНИМАНИЕ: Спойлер!


3) Внутри него создаем "показать эмоцию Врага - Восклицательный знак" - так мы будем видеть что Враг видит Игрока
4) ИЛИ "показать эмоцию Врага - вопросительный знак"
5) Не забываем поставить в событии триггер ПАРАЛЛЕЛЬНО





2. Делаем ограничение зрения в зависимости от дальности взора врага
То есть Враг не видит игрока если он стоит далеко. Если вы не хотите делать данное ограничение то просто пропускаем этот шаг.



Для простоты и удобства пока рассмотрим небольшую дальность зрения Врага. Напрмиер как на этом рисунке. Красный квадратик находится вне зрения врага но если он будет в голубом поле то Враг его увидит, а точнее на расстоянии 5 клеток или менее
Здесь тоже всё элементарно.
1) Если координата Игрока на 5 или более клеток отличается от координаты Врага,то...
То есть "координата Врага по У минус 5 должно быть МЕНЬШЕ или РАВНО координаты Игрока, чтобы Враг его уивдел
$game_map.events[1].y-5<=$game_player.y
ВНИМАНИЕ: Спойлер!


3. Делаем конусовидное ограничение зрения врага
То есть нам надо ввести ограничение зрения по Х. Решил что поле зрения Врага должен быть вот такой конус:



И вот тут начинается самое мозголомное. Конечно, можно перебрать ВСЕ клетки,входящие в данный конус описанными выше способами наподобие с координатой по У. Но тогда получится кучу условий, а ведь если мы хотим сделать дальность врага в 9 клеток и более то конус будет совсем огромный.
Приходится искать другое решение. Напишем координаты данных клеток относительно координат Врага и попробуем найти их закономерность. Х - координата Х Врага, У - координата У врага.

drive.google.com/file/d/0Bw4hr3sRpc83THY...dU0/view?usp=sharing

Замечаем, что у клеток,находящихся на самой левой диагонали (выделил красной стрелкой) координата Х МЕНЬШЕ координаты У на 1.
То есть если их Х вычесть У то получится -1.
У диагонали которая находится чуть правее (отметил синей стрелкой) координата Х РАВНА координате У.
То есть если их Х вычесть У то получится 0
У диагонали зеленой стрелкой если вычесть Х то получится 1.
Получается, что если эта разница будет БОЛЬШЕ ИЛИ РАВНО -1, то Враг будет видеть эту клетку.
1) Значит вводим условие "если координата Х игрока минус координата Х врага будет больше или равно на "-1" разницы между координатами по У игрока и врага то.."

($game_player.x-$game_map.events[1].x)-($game_player.y-$game_map.events[1].y)>=-1

drive.google.com/file/d/0Bw4hr3sRpc83amR...RDg/view?usp=sharing [/img]

2) А что делать с правой стороной этого конуса?

drive.google.com/file/d/0Bw4hr3sRpc83Z2x...bE0/view?usp=sharing

Замечаем что координаты с правой стороны полностью идентичны координатам слева, только Х меняет свой знак с плюса на МИНУС. Значит чтобы определить координаты конуса слева необходимо умножить координату Х на -1, сделав ее отрицательной. Вот и всё.

($game_player.x-$game_map.events[1].x)*(-1)-($game_player.y-$game_map.events[1].y)>=-1

3) Теперь необходимо совместить это. Чтобы правая сторона конуса умножалась на -1 а левая сторона - нет.
Вводим условие "если разница между координатой игрока и координатой события по Х положительная, т.е. больше или равно 0.
$game_player.x-$game_map.events[1].x>=0
то выполняем второе условие, умножая на -1.
ИЛИ выполняем первое условия,не умножая.

drive.google.com/file/d/0Bw4hr3sRpc83SnN...Uk0/view?usp=sharing

ВОТ И ВСЁ. Так много текста и трудов и так мало ветвлений в событии.
Несколько подсказок для регулирования зрения Врагов.
1) Регулирование длины зрения врага,путем замены всего одной цифры. На втором шаге вместо 5 можно написать любое число, хоть сотню - конус по-прежнему будет рбаотать.
2) Легко расширить конус или сузить. Меняем -1 на 0 и получается конус как в примере Эльфа.
3) Можно сделать чтоб Враг слышал вас если вы подошли сзади слишком близко. Для этого меняем первый шаг на
$game_player.y<=$game_map.events[1].y+1

Демка надеюсь все ссылки работают drive.google.com/file/d/0Bw4hr3sRpc83WVg...b0k/view?usp=sharing

Также сделал возможность прятаться за укрытия из непроходимых тайлов, но об этом расскажу и сделаю нормальную демку в следующий раз, щас устал :mad:
Да и хочу узнать ваше мнение по укрытиям:
1) Сделал вот так. Нормально ли такия "прятки"? еленые кружки - здесь игрок встанет и его не будет видно. В остальных клетках он виден, в том числе там,где красные кружочки.
drive.google.com/file/d/0Bw4hr3sRpc83YnV...dGs/view?usp=sharing
2) На основе чего можно делать проверку проходимости событий? например тайлы - по коду местности. А события? Как вариант - по айди события, но тогда придется делать чтобы все непроходимые события имел одинаковые айди,это очень уж муторно.

P.S.с картинками проблема, надеюсь переход по ссылкам для их лицезрения никого не напрягет
Последнее редактирование: 10 года 3 мес. назад пользователем yuryol.
Спасибо сказали: I_LORD, DeadElf79, Демий, Jas6666, DesKarD, LiRo

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Проект месяца 3 место Проект месяца 1 место Проект месяца 2 место 3 место Готв Победитель Сбитой кодировки Программист JavaScript 2 место Сбитая кодировка Писатель 3 место 2 место 3 место Организатор конкурсов
Больше
10 года 3 мес. назад - 10 года 3 мес. назад #89688 от Cerberus

yuryol пишет: 2) На основе чего можно делать проверку проходимости событий? например тайлы - по коду местности. А события?

Примерно так:
Code:
$game_map.events_xy_nt(x, y).any? {|ev| ev.normal_priority?}
Пока не тестировал, но по идее - должно сработать.

Жуть болотная, на лапках, в тапках и с пулемётом...
Последнее редактирование: 10 года 3 мес. назад пользователем Cerberus.
Спасибо сказали: yuryol

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Время создания страницы: 0.141 секунд
Работает на Kunena форум