Наша функция IPC очень проста!
Вся оставшаяся работа будет проходить в Game Layout (макет игры) и Game Event Sheet (игровой лист событий). Мы разработаем дизайн нашей доски и дисков, а также добавим текст, указывающий, чей ход и статус игры. Для этого перейдите к нашему Game Layout (игровой макет).
Щелкните правой кнопкой мыши по нашему пустому макету и выберите Insert new object (Вставить новый объект). На этот раз мы добавим Sprite (спрайт). Назовите его Board и вы увидите, что открыт Animations (редактор анимаций). Выберите инструмент Fill (Заполнить) и выберите цвет доски на вашем выбор, а затем заполните спрайт этим цветом. Закройте редактор анимаций и измените размер нашей платы до 480x480 пикселей.
Заполнение нашей доски синим цветом
Повторите процесс, добавив еще один спрайт. На этот раз назовите его Disc и нарисуйте белый круг с помощью инструмента Ellipse. Назовите имя анимации 0, а также установите Speed (Скорость) и Repeat Count (счетчик повторов) на 0. Щелкните правой кнопкой мыши на 0 в Animations (панель анимации) и выберите Duplicate (Дублировать). Вызовите дублированную анимацию 1. Дублируйте ее еще раз и вызовите 2. Выберите 1 и заполните круг красным цветом. Выберите 2 и заполните круг желтым цветом. Это наши игровые диски: игрок 1 будет красного цвета, игрок 2 - желтого.
3 анимации наших дисков: белый, красный и желтый
Закройте Animations Editor (Редактор анимаций) и нажмите на наш новый диск в макете. Выберите опцию Instance variables (примеры переменных) в окне Properties (Свойства) и выберите Add new instance variable (Добавить пример переменной). Вызовите имя Column с типом номера. Добавьте еще один пример переменной и назовите его Row, опять же с типом номера. Размер нашего диска 60x60 и поместите его в левый нижний угол доски. Скопируйте и вставьте наш объект диска, чтобы построить сетку из 7 столбцов и 6 строк. Щелкните каждый диск и правильно установите значения переменных Column и Row instance, поэтому нижний левый диск - Column 0, Row 0, следующий вверх - Column 0, Row 1, и так далее, при этом нижний правый диск - Column 6, Row 0, а верхний правый диск - Column 6, Row 5. Помните, что массивы JavaScript начинаются с 0!
Выбранный диск в Column 4, Row 2
Почти готово! Нужно добавить текстовое поле, чтобы указать, чей ход, или если игра окончена. Давайте сделаем это прямо сейчас. Щелкните правой кнопкой мыши по нашему макету и выберите Insert new object (Вставить новый объект). Добавим текстовый объект и назовем его StatusText. Переместите его где-нибудь над дисками и установите цвет на белый, чтобы его можно было прочитать на синем фоне. Увеличьте ширину текстового поля так, чтобы оно покрывало всю ширину нашей доски. Последнее, что нужно сделать, это добавить объект Mouse, чтобы мы могли взаимодействовать с мышкой: так мы можем отправить игровую транзакцию с закодированным smartbridge сообщением, когда игрок кликает по столбцу, чтобы играть.
Теперь мы закончили с нашей версткой. Пора отправляться в Game Event Sheet (игровой лист событий)! Добавьте новую пустую функцию и назовите ее ParseBoard. Затем добавьте новое событие, WebSocket > On text message, действием которого является JSON > Parse. Строка JSON для анализа - WebSocket.MessageText. Теперь добавьте под-событие внутри WebSocket -> On Text Message события. Выберите JSON и затем Has Key. Введите "games" и нажмите Готово. Нажмите кнопку (Добавить действие) для нашего вновь созданного суб-события и перейдите к System > Set value (Система > Установить значение). Мы хотим установить наш JSON объект на значение JSON.get("Games"). Нажмите Готово. Это то же самое событие, которое мы создали в нашем лобби, но нам также нужно, чтобы он срабатывало во время игры, чтобы наш клиент обновлялся при изменении состояния игры. Добавьте дальнейшее действие к этому суб-событию: Functions > ParseBoard (Функции > ParseBoard), так как эта функция будет отвечать за обновление состояния доски.
Также нам необходимо обновить доску, как только откроется макет игры, поэтому давайте создадим еще одно событие. Перейдите в System > On start of layout (Система > начать макет). Действие должно быть Functions > ParseBoard (Функции > ParseBoard).
Время писать логику ParseBoard! Мы выберем нужную игру с помощью сохраненного ранее GameAddress и покажем, чья очередь. Если адрес игрока, чья очередь совпадает с нашим собственным подтвержденным адресом, мы напечатаем "You" вместо адреса. Итак, поехали!
const game = games[runtime.globalVars.GameAddress];
let text = "";
runtime.globalVars.TurnAddress = "";
if (game.outcome === "ongoing") {
text = `Current turn: ${game.players[game.turn]} (${game.turn === 1 ? "Red" : "Yellow"})`;
runtime.globalVars.TurnAddress = game.players[game.turn];
} else if(game.outcome === "tie") {
text = "Game tied!";
} else {
text = `Winner: ${game.players[game.outcome]}!`;
}
if (runtime.globalVars.ValidatedAddress) {
text = text.replace(runtime.globalVars.ValidatedAddress, "You");
}
runtime.objects['StatusText'].getFirstInstance().text = text;
Надеюсь, к этому моменту вы уже смогли понять, как это работает. Мы извлекаем нашу игру из списка игр с помощью переменной GameAddress, а затем проверяем, продолжается ли игра. Если да, то показываем адрес, чей это ход, и цвет, в который они играют (помните, что игрок 1 всегда красный, а игрок 2 всегда желтый). Если результат ничейный или есть победитель, мы покажем эту информацию вместо него. Также, если адрес совпадает с нашим ValidatedAddress, то есть это мы, мы заменяем этот адрес на "You". Мы также сохраняем адрес текущего игрока в нашей переменной TurnAddress, если игра не окончена, в противном случае, значение очищается.
Теперь давайте расширим наш ParseBoard еще больше, чтобы изменить цвет дисков для отображения текущего состояния доски:
for (const column in game.board) {
let row = 0;
for (const position of game.board[column]) {
const disc = (discs.filter(disc => disc.instVars.Column === parseInt(column) && disc.instVars.Row === parseInt(row)))[0];
disc.setAnimation(game.board[column][row].toString());
row++;
}
}
При этом происходит итерация по всем столбцам в данных доски, полученных из WebSocket, и задается цвет подходящего диска в каждом столбце и строке.
Теперь осталось позволить текущему игроку отправить транзакцию по игровому адресу, используя значение smartbridge для столбца, в который мы хотим поместить наш диск. Для этого мы добавим еще одно событие. Выберите Mouse > On object clicked (мышь > кликнутый объект). Мы хотим действовать, когда левой кнопкой мыши нажимаем на объект Диска. Но этого само по себе недостаточно, мы хотим выполнить это действие только тогда, когда наступит наша очередь, и если выбранный столбец не будет заполнен. Поэтому щелкните правой кнопкой мыши наше новое событие и добавьте еще одно условие. Выберите Choose Disc > Is Playing Диск > (выбрать диск > воспроизвести) и введите "0". Это означает, что наше действие сработает только в том случае, если диск будет белым, то есть он еще не проигран (иначе это было бы 1 для красного или 2 для желтого). Наконец, мы хотим запустить это действие только тогда, когда наступит наша очередь, так что добавьте еще одно условие еще раз, и на этот раз выберите System > Compare variable (Система > Сравнить переменную). Выберите ValidatedAddress как переменную, а TurnAddress как значение.
Наше действие для этого нового события Browser > Go to URL (Браузер > Перейти на URL). Мы хотим использовать схему URI ark для отправки транзакции с кошелька нашего игрока на игровой адрес, с номинальным значением 1 arktoshi, с smartbridge сообщением столбца, в которую мы помещаем наш диск. Это может быть достигнуто с помощью следующего URL в нашем действии Construct 3: "ark:" & GameAddress & "?amount=0.00000001 &vendorField=" & (Disc.Column + 1) & "&wallet=" & ValidatedAddress
Наш завершенный Game Event Sheet (игровой лист событий)
Поздравляю, теперь вы создали играбельную блокчейн - игру! Но вы наверняка заметили, что победитель не получает приз, а если ничья, то игроки не получают обратно свою ставку. В этом и заключается следующая часть нашей обучающей серии, в которой мы рассмотрим, как рассчитываются, присуждаются и выплачиваются игровые призы.
Если вы застряли в какой-то момент, обязательно проконсультируйтесь с нашими документами в учебном центре Learn ARK. Кроме того, наша команда и разработчики активны в Slack, так что не стесняйтесь обращаться к нам!