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