Хабрахабр

Обучающая игра за неделю или попытка таймкиллера по английскому

Я провел в играх сотни часов по статистике Стима, и тысячи, если считать на всех платформах. Но что меня поразило, так это соотношение времени в некоторых случаях. На прохождение великолепного Bioshock Infinite у меня ушло 8.5 часов, но на Sacura Clicker — на 12 минут больше. На Clicker Heroes — больше сорока часов, почти столько же, как на Torchlight 2. Фокус в том, что я помнил и хорошо представлял затраты времени на большие игры. Но маленькие игрушки совершенно не отложились в памяти, они украли мое время незаметно, растаскивая по пять-десять минут в течение недель и месяцев.

То есть сделать полезный таймкиллер — простенькую игру, которая будет не воровать, а инвестировать мое время по пять-десять минут. Когда я осознал это, то подумал, что было бы неплохо прикрутить к этой балерине турбину. К примеру, в словарный запас по английскому.

Потом уволился из офиса и привычка пропала, я забыл про карточки.
Когда-то я купил кучу карточек с английскими словами и читал их в маршрутке по пути в офис. Игра, в которой надо составлять пары (в отличие от match 3, где берут по три и больше). Полез перетряхивать рюкзак, и когда из верхнего бокового кармана веером выпали разные слова, понял — это же match 2!

Таймкиллеры с принципом «составь пару» известны давно — к примеру, компьютерная игра маджонг-пасьянс (не путать с классической азартной китайской игрой, в которую играл еще Сэммо Хунг в гонконгских боевиках).


Маджонг из KDE Games

В википедии можно прочитать, что его называют сисэн-сё (англ. У маджонга-пасьянса есть упрощенная разновидность Mahjong Connect, где фишки выкладываются в простую раскладку, без фигурных пирамид. Shisen-Sho), но если вы хотите прогуглить образцы — первое название будет более подходящим.

Подозреваю, что первую версию сделал программист вроде меня, у которого не было опыта в программировании полноценного маджонга со сложной выкладкой — но игра внезапно стала популярной и породила собственную ветвь клонов.


Сисэн-сё из KDE Games или Mahjong Connect в народе

Остается только превратить каждую карточку в пару фишек. Посмотрите на карточки со словами и на Маджонг Коннект — они отлично подходят друг к другу — и там, и там есть пары.

Дизайн фишек и геймплея

Пять новых слов в каждом сеансе и еще несколько повторяющихся слов из предыдущих — вот идея, от которой я отталкивался. Это означало, что в игре должно участвовать как минимум около 20 фишек.

Бумажные карточки позволяют разместить довольно много текста, но фишки с такими пропорциями получились бы слишком большими. На каждой фишке необходимо было разместить хотя бы одно слово с хорошей читаемостью. Если повернуть костяшку маджонга на 90 градусов, то получится достаточная для текста площадка. Кроме того, я очень хотел сохранить ощущение «как будто маджонг», а это означало, что одна игровая фишка должна быть очень компактной и по форме, и по тексту.

Посмотрев снова на скриншоты с маджонгами, попробовал добавить разные графические элементы для оживления картинки. Смоделировав игровую раскладку с такими костяшками в графическом редакторе (Fireworks 2003 года, если любопытно), я увидел, что игра выглядит довольно скучно. Тогда это будет работать не только как оживляющий элемент, придающий хотя бы внешнее сходство с казуальными игрушками, но и как подсказка. И тут меня осенило — можно же просто добавить на каждую пару по самоцвету.


Черновой вариант игрового поля с разными вариантами фишек

Это давало подсказку с шансом случайного совпадения около 25%. Финальный вариант получился таким — три самоцвета на 10-11 пар слов. Если забыл слово — можно просмотреть фишки с теми же словами.

Изначальная идея была в том, чтобы помечать один элемент из пары, а не национальный признак, поэтому я не стал делать триколор или еще что-то в этом духе. Дополнительный элемент оформления, ускоряющий ориентацию — серый флажок, отмечающий все слова на одном (русском) языке.

Экзамен — это стресс, а мне нужен был максимально легкий и приятный геймплей, чтобы во время игры формировалось чувство победы и уверенности в своих силах. Выглядит как почти читерство, но я не хотел делать экзамен или полноценный тест знаний. Игрок идет по оптимальной границе между своим скиллом и неумением, получая удовольствие и возвращаясь к игре снова и снова. Мне кажется, это одно из важнейших качеств культовых таймкиллеров вроде Bejeweled или Zuma.

Есть две причины, почему это произошло. Что насчет правил — я сделал еще один шаг в упрощении от Mahjong Connect и позволил составлять пары из любых подходящих друг к другу фишек, а не только из тех, что разблокированы. Вторая — что я обнаружил, что фишки со словами на разных языках сами по себе усложняют геймплей и составление пар из них уже создает ощущение игры. Первая заключается в том, что у меня не было под рукой готового кода для маджонга и я тестировал просто составление пар.

Дело в том, что дополнительные ограничения на фишки сузят выбор и игроку можно будет только проверять все подходящие по самоцветам свободные для хода фишки — а это даст резкое увеличение вероятности совпадения с 25% до 50 или даже ста, в зависимости от раскладки. Забегая вперед — если сделать полноценный коннект и маджонг с такими же фишками, играть на самом деле станет гораздо легче.

Если кому-то удастся сделать такой таймкиллер, то десятки часов в нем обернутся пользой для игроков, как бы они ни читерили. Но как бы ни было легко играть или читерить, главная цель в такой игре все равно будет выполняться — мозг игрока будет постоянно сопоставлять пару слов на родном и чужом языке. Хотя сознательное обучение — безусловно всегда лучше.

Программирование

Для этого проекта я использовал обычный JavaScript и игровой движок Phaser.io 2.10.2. Чем хороши HTML5-игры — они позволяют быстро предоставить доступ для тестирования и обкатки прототипов. Я уже успел убедиться на других проектах, что как средство для создания кроссплатформенной игры HTML5 не очень хорош (ощутимая просадка по FPS на слабых телефонах, проблемы кроссбраузерной совместимости, необходимость продумывать мосты к нативному API в ряде случаев). Но как средство для создания веб-прототипов и веб-игрушек — это хороший выбор.

Как и в случае с постъядерным караваном, я начал разработку с составления модели состояния игры — то есть data-класса с полями, которые просто отражают текущий прогресс игрока.

function GameState() ); this.portion = 0; // текущая порция // настройки this.options = { tutorial: true, // включить туториал по умолчанию }
}

Для сохранения и загрузки состояния игры в браузерном JS достаточно просто сериализовать и десериализовать эту модель при записи и чтении в локальное хранилище — и так мы получаем сохранение прогресса на компьютере пользователя буквально парой строчек.

В нем есть класс Group, который позволяет автоматически выравнивать все добавленные в него визуальные объекты по заданной сетке. Выкладка фишек на поле, обработка нажатий мышки и тачскрина в Phaser реализуются достаточно просто.

Поэтому я написал свою функцию раскладки, в которой каждый второй ряд смещается на половину фишки — получается выкладка «кирпичами». Впрочем, так можно делать только правильные прямоугольники (или сетки, если задать большой шаг), что выглядит довольно примитивно.

// выравнять как кирпичи - каждый второй ряд смещен на определенное расстояние function layAsBricks(group, offsetBase) { offsetBase = offsetBase || Math.floor(AppConfig.CHIP_WIDTH / 2); var N = group.length; var i = 0, row, col, COLS = getColAmount(N), ROWS = N / COLS; var offsetX, min = Math.floor(offsetBase / 2), max = offsetBase + min; var lastWidth = 0, lastX = 0; var nextChip; for (row = 0; row < ROWS; row++) { if (row % 2 > 0) offsetX = offsetBase; else offsetX = 0; lastWidth = 0; lastX = 0; for (col = 0; col < COLS; col++) { nextChip = group.children[i]; if (nextChip === undefined) break; group.children[i].y = row * AppConfig.CHIP_HEIGHT; group.children[i].x = lastX + lastWidth; lastX = group.children[i].x; lastWidth = group.children[i].width; group.children[i].x += offsetX; i++; } } }

Но главные вопросы мне пришлось решать со словарем.

Игры со словарем и шрифтами

Первое, что бросится в глаза каждому, если уже не бросилось — длина фишек не является достаточной для адекватного отображения всех слов в словаре. Можно решить это, произвольно меняя размер шрифта в зависимости от длины слова.


Разный размер шрифта для разной длины — выглядит немного безумно, на мой взгляд

В моем случае это было позволительно, потому что я взял за основу частотный словарь — то есть слова в нем были отсортированы по частоте употребления. Но этот вариант показался мне слишком плохим, поэтому я решил просто отфильтровать словарь и оставить только слова не длиннее 9 знаков в обоих случаях (русский и английский). В первой тысяче слов длинее 9 знаков было очень мало, а в первых десятках, то есть самых частых, их не было вовсе.

Скорее всего, менять пропорции фишек или увеличивать их размер. Лимит в 9 знаков годится на этапе проверки концепции и для самых употребительных слов, но если развивать прототип — рано или поздно с этим придется что-то делать. Для немецкого языка это придется сделать даже в рамках первых самых популярных сотен слов — а немецкий я тоже хочу потестировать, вспомнить школьные годы.

Русское «не» и английский he в верхнем регистре часто совпадают просто до пикселя. Второй момент — визуальное совпадение букв в английском и русском языке. Частотный словарь усиливает этот эффект, потому что эти короткие слова оказываются в одном уроке почти в самом начале.


Русское НЕ и английский HE в верхнем регистре выглядят одинаково

После первых жалоб тестеров я поменял регистр у надписей на обычный lowercase. Серый флажок помогал слабо, слова путались. И тут увидел следующий баг — буквы стали плясать, в некоторых словах уплывая по вертикали на целый пиксель.

В большинстве случаев это проходит гладко, но на мелких буквах возникают ошибки округления — иногда съедается один пиксель, что и дает эффект пляски.
Причина была в том, что я использовал для вывода один растровый шрифт (сформированный как набор картинок-букв в одном размере), масштабируя его по мере надобности.

Мораль: растровый шрифт для мелких текстов надо сразу готовить в нужном размере

После подготовки отдельного шрифта все перестали плясать и встали строго по базовой линии.

Иначе это дает дополнительную нагрузку на процессор, что в играх с кучей действия и эффектов может привести к сильному проседанию FPS. Если вы будете использовать Phaser или другой HTML5-движок в своих проектах, то вот еще один совет: выводите растровый шрифт сразу в том цвете, который будет использоваться в игре. Кроме того, даже в последнем мобильном Chrome на некоторых Android-планшетах «неродной» цвет, заданный растровому шрифту программно, может не отображаться совсем — будет вывод в дефолтном.

И, разумеется, словарь для такой игры лучше всего подключать как отдельно загружаемый файл — это позволит обновлять его, если будут замечены опечатки или сомнительные варианты.

Понятно, что в таком значении эта частица употребляется значительно чаще, чем вопрос, но для обучения без контекста это не годится. К примеру, мой вариант словаря, похоже, составлялся по массивам переведенных текстов с учетом контекста, поэтому «что» в первых уроках там переводилось как «that».

Варианты решения, которые я вижу — делать какую-то отдельную игрушку по частицам или создавать фишки с более длинными текстами. Мой главный вывод по словарю — частицы и другие слова, сильно зависящие от контекста, не годятся для обучения по таким чистым парам. А это значит — впереди еще много экспериментов! Второй вариант выглядит более логичным, так как одними словами грамотен не будешь и полноценно учить язык необходимо все же с контекстом, хотя бы на примере небольших выражений.

Туториал

Сначала я тестировал игру, в которой просто выкладывались фишки — и это было занятно, поскольку геймплей сводился к радостному припоминанию уже известных выражений и это давало чувство легкой победы, что и требовалось. Но потом я понял, что это не будет работать с абсолютно незнакомым языком. Поэтому пришлось добавить опцию обучения — перед началом урока игра показывает фишки в правильных парах, а затем перемешивает их.

Затем, если включена опция туториала, запускается функция, которая запоминает исходные координаты фишек, добавляет к ним анимацию полета и раскладки в рабочие пары, а потом все возвращает на свои места. Технически это реализовано так — уровень изначально выкладывается как обычно, то есть в случайном порядке. Поскольку выкладка и подготовка туториала происходит до начала первого цикла update (перерисовки экрана), пользователю кажется, что игра сначала выводит фишки в правильном порядке, а затем случайно перемешивает их.

Это очень удобная функция, которая безусловно пригодится для реализации полноценного маджонга и других игр, где есть хотя бы условное третье измерение и элементы накладываются друг на друга. В движке Phaser у Group есть метод shuffle, который работает как перемешивание обычного массива, но попутно обновляет Z-index.

Алгоритм начала игры выглядит просто — берем N пар из словаря пар для заданного урока, формируем из них визуальные элементы-фишки, затем делаем shuffle и выстраиваем в сетку — получается псевдослучайная раскладка.

В туториале происходит обратный процесс — на массиве фишек вызывается функция sort, где значимым параметром является id пары из словаря — так фишки выстраиваются друг за другом попарно, после чего остается разместить их в две колонки.

Прогресс

Для наблюдения за прогрессом я добавил небольшие индикаторы в стартовое меню и звездочку, которая должна появиться при полном прохождении всех уровней в сотне слов. На скриншоте изображена искусственная ситуация с тестовой звездочкой.

Просто, чтобы оживить заставку. Султана с лицом Картмана я взял на Craftpix.net — он шел в том же бесплатном наборе, что и алмазы. Хотя если вы не любите султанов или Картмана — признаю, что ход не особо удачен.

Выводы и перспективы

Я уверен, что обучающий таймкиллер — настоящий таймкиллер, а не этот прототип, что я сделал — возможен. И когда они появятся в массовом количестве, мир может измениться к лучшему. Как минимум, миллионы людей будут тратить сотни часов не впустую.

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

Все match3 и match2 игры — с шариками, алмазами, фишками для маджонга, рыбками и медвежатами, с фрактальной динамической выкладкой как Zuma или статическим полем, как в большинстве игр — это по сути задания на составление комбинаций, на подбор групп по какому-то признаку.

А что, если эти медвежата будут насыщены полезными витаминами? В текущих играх этот признак не несет никакой полезной нагрузки, люди просто комбинируют красные и зеленые шарики, полупрозрачные полосатые желейные конфеты и липких мармеладных медвежат. Я помню, что ряд английских слов я выучил по Fallout и Heroes Might and Magic, значит, такие витамины существуют.

Там есть выбор разных сотен и уровней, сохранение, прогресс и тысяча самых употребительных английских слов. Мой прототип игры можно потестить здесь. Каждый уровень рассчитан на несколько минут, содержит 5 новых слов и 6 повторных с предыдущих (по формуле случайной выборки 3, 2, 1). Верстка рассчитана на десктопные мониторы или планшеты.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть