Когда-то, когда я еще сидел в ПервоЛого, сосед по подъезду попросил меня сделать игру типа Mortal Combat. Ясный перец, что настоящий боевик с десятками комбо и персов сделать в ПервоЛого нереально, но что-то простое вполне можно было соорудить.
Все просто - среди стандартных формочек нарыли африканского мальчика в красных бутсах и синих штанишках. Я перекрасил мальчика и придал ему более суровый вид, после чего добавил несколько боевых формочек мальчика (удар рукой, ногой и т.д.).
Потом сделал второго мальчика, повернутого в противоположную сторону (противник).
После того, как задали черепашкам реакцию на друг друга (принимать "упавшую" форму и отлетать назад), получился нехитрый боевичок. Смысл - ударами заставить противника отшатнуться к самому краю проекта, а там он наткнется на зеленый лазер и игра будет пройдена.
Минусы - удары нельзя было блокировать. Можно было и не драться: просто идешь вперед, а противник отлетает и отлетает назад.
Эта игра, наверно, уже давно стерлась, но я вдруг опять задался мыслью сообразить что-то вроде боевичка. Тогда я уже знал ЛогоМиры и любую задачу представлял себе тут же в программном виде. Mortal Combat? Не проблема, структура игры тут же появилась перед глазами, но всегда обрывалось двумя "но": во-первых, на написание такого количества кода и рисования формочек ушел бы год, а во-вторых, в ЛогоМирах были кое-какие ограничения по количеству формочек и по размерам листа программ.
На этот раз я поставил себе на вид несколько условий: удары можно блокировать; продвижением вперед сбить противника с ног невозможно; если противники делают удары одновременно, это не значит, что они должны так же синхронно разлететься в стороны.
Первый способ реализовать все это был громоздкий и неудобный (десять черепашек - по одной на каждое действие). Тут же появился второй вариант с использованием глобальных переменных.
В процедуре sturtup объявляем несколько глобальных переменных:
это sturtup
пусть "удар "нет
пусть "занят "нет
пусть "иду "нет
конец
Создадим две черепашки (ч1 и ч2 - проще не бывает). ч1 - игрок; ч2 - противник aka бот.
Предположим, при нажатии какой-либо клавиши или кнопки у нас вызывается процедура удар_ногой.
Тело процедуры удар ногой:
это удар_ногой
если (и не :удар не :занят не :иду не: блок)
[
пусть "удар "да
ч1, пусть "расс путь "ч2
если :расс < 50 [warning]
...анимация удара...
упал "ч2
пусть "удар "нет
]
конец
Поясняю. В начале процедуры делаем проверки.
Переменная удар имеет положительное значение в процессе выполнения любого удара. Если значение положительно, значит, черепашка уже делает какой-то удар и еще один удар мы сделать не можем (иначе начнется графическая какофония).
Переменная занят имеет положительное значение тогда, когда игрок лежит на земле (после успешного проведения противником удара). Если мы валяемся на земле, мы не можем делать какие-либо удары.
Переменная иду имеет положительное значение тогда, когда игрок идет. В данном случае подразумевается, что игрок не может бить ногой во время продвижения вперед/назад (систему комбинаций я уже не буду трогать ибо лень; кому очень надо - мне в ЛС).
Переменная блок имеет положительное значение тогда, когда игрок поставил блок. Подразумевается, что мы не можем бить ногой, пока блокируем удар (каратисты с их "контратаками" молчат - мы сейчас только основы изучаем).
Так вот, если игрок не выполняет удар, не валяется на земле, не блокирует удар и не идет куда-либо, мы можем считать, что персонаж вполне достоен проветсти какой-либо удар. В начале мы присваиваем переменной удар значение "да", т.е. обозначаем, что мы проводим какой-то прием. Далее идем проверка на расстояние. Если расстояние меньше пятидесяти черепашьих шагов, значит, противнику (далее - боту) стоит обеспокоится. О процедуре warning, заставляющая бота среагировать (сделать блок, отойти назад и т.д.), мы поговорим позже.
Далее идет процесс смена формочек, т.е. анимация удара и т.д. Тут я не привожу ничего, т.к. количество формочек у каждого человека получится уникальное. В процессе анимации, когда нога игрока достигает свою цель, надо вставить вызов процедуры упал и передаем ей строковой входной параметр "ч2".
Начнем рассматривать процедуру упал:
это упал :объект
если (и :объект = "ч1 не :блок)
[
ч1, пусть "расс путь "ч2
ч1, если :расс < 50
[
пусть "занят "да
...анимация падения...
пусть "занят "нет
]
]
если (и :объект = "ч2 не :блок2)
[
ч2, пусть "расс путь "ч1
ч2, если :расс < 50
[
пусть "занят2 "да
...анимация падения...
пусть "занят2 "нет
]
]
Как видите, тут у нас проявилось нескольно новых переменных: занят2 блок2. Это тоже самое, что и обычные занят блок, но переменные с суффиксами 2 у нас относятся к ч2.
Тут все понятно: проверка, кого именно кто попытался ударить, защитился ли тот, кого бьют.
Проверяем расстояние. Если все условия для того, чтобы кулак одного человечка достиг челюстей другого, выполнены, то мы "говорим в мир", что персонаж падает и начинаем анимацию падения. Ну или не падения - может, у вас вместо падения удар человечков только оглушает на какое-то время (не забудьте подрисовать звездочки и птичек над головой).
Теперь рассмотрим процедуру warning:
это warning
пусть "случай случайный 3
если :случай = 1 [блокировка2]
конец
Все просто - рандомизация (хотя мне иногда кажется, что случайности неслучайны - даже в пределах выбора до 100 вариантов ЛогоМиры часто заедают на каком-нибудь одном числе и выбирают его по три раза подряд). Четыре варианта - от нуля до трех. Если выберится единичка, то вызывается процедура блокировка2. Блокировка2, в свою очередь, заставляет бота заблокировать удар. Тут уже почти все понятно:
это блокировка2
если (и :занят2 = 0 :удар2 = 0)
[
ч2, жди 0,5
пусть "блок2 "да
...анимация блока...
пусть "блок2 "нет
]
конец
Ждем немного (ради справедливости - даже бот не может делать блоки моментально). Далее кричим, что мы заняты защитой, проводим блок и обозначаем, что защита закончилась.
Вот основные принципы, на которых я теперь создаю "мочиловки". Можно вертеться в листе программ как хочешь - ограничено только фантазией. Я, например, уже предусмотрел хитрую систему чит-кодов, которая активируется при вводе специального пароля, указанного в game_config.cfg))
Все вопросы - пишите в этой теме ниже, либо шлите все в ЛС (кнопочка "сообщения" в меню навигации).