Добрый день! Хочу представить Вашему вниманию проект-игру «Слова из Слова». Относительно недавно я стал изучать web-программирование и, так как лучший учитель — это практика, решил написать свой вариант довольно-таки известной игры «Слова из Слова». Основная цель — использование чистого Javascript без подключения дополнительных библиотек.

Вид игрового поля
Задача игрока – из букв представленного на экране слова составлять другие. Составленное слово должно быть нарицательным именем существительным в единственном числе, уменьшительно-ласкательные формы, а также сокращения не принимаются. Минимальная длина – 3 буквы. За каждое отгаданное слово начисляются очки в зависимости от его длины (базовая ставка за каждую букву, умножаемая на коэффициент). Базовая ставка равняется десяти очкам. Коэффициент рассчитывается следующим образом:
На каждом уровне игрок может заработать дополнительные очки, выполняя определенные условия:
Отгаданные игроком слова отображаются на игровом поле в алфавитном порядки, сгруппированные по количеству букв в слове. Игрок может посмотреть значение каждого, нажав на него. Результаты охраняются каждый раз после верно отгаданного слова.
В ходе работы над приложением использовались элементы подхода MVC (model, view, controller). В отдельные компоненты также вынесено управление звуком, обработка результатов игры и общие методы для всего приложения.
В процессе разработки ощутил все преимущества использования замыканий и немедленно вызываемых функций. Так, их использование избавило от постоянного поиска элементов на странице посредством getElementById и т.п.
В процессе инициализации приложения создаются все необходимые html-элементы, формируются объекты-списки для упрощения доступа к ним.
Все информация о прохождении игроком уровня сохраняется в объекте GAME.model.level
Для того, чтобы как-то сохранять прогресс и не задействовать при этом серверные скрипты и базы данных, был выбран способ сохранения в localStorage браузера. Кроме того, реализовал «таблицу рекордов» для игроков, которые используют это приложение в одном и том же браузере
Таким образом, представляю Вам на обсуждения мой проект. Буду рад выслушать конструктивную критику и предложения как в комментариях, так и в личном общении. Если интересуют подробности, с удовольствием расскажу о процессе написания подробнее.

Вид игрового поля
Описание игры
Задача игрока – из букв представленного на экране слова составлять другие. Составленное слово должно быть нарицательным именем существительным в единственном числе, уменьшительно-ласкательные формы, а также сокращения не принимаются. Минимальная длина – 3 буквы. За каждое отгаданное слово начисляются очки в зависимости от его длины (базовая ставка за каждую букву, умножаемая на коэффициент). Базовая ставка равняется десяти очкам. Коэффициент рассчитывается следующим образом:
- три буквы – 1;
- от четырех до пяти букв – 1.25;
- от шести до семи букв – 1.5;
- от восьми до девяти букв – 1.75;
- более девяти букв – 2.
На каждом уровне игрок может заработать дополнительные очки, выполняя определенные условия:
- отгадать 40 проц. возможных слов на уровне (1 000 очков);
- отгадать три слова, начинающихся на ту же букву, что и слово уровня (500 очков);
- отгадать все возможные слова на уровне (50 000 очков).
Отгаданные игроком слова отображаются на игровом поле в алфавитном порядки, сгруппированные по количеству букв в слове. Игрок может посмотреть значение каждого, нажав на него. Результаты охраняются каждый раз после верно отгаданного слова.
Использованные техники и приемы
В ходе работы над приложением использовались элементы подхода MVC (model, view, controller). В отдельные компоненты также вынесено управление звуком, обработка результатов игры и общие методы для всего приложения.
Общая структура приложения
GAME = { "utils":{}, // общие инструменты "sounds":{}, // обработка звуков "view":{}, // представление "controller":{}, // обработка поведения "model":{}, // основные данные "results":{} // обработка результатов } GAME.init(place) // инициализация приложения GAME.namespace(ns_string) // создание пространств имен
В процессе разработки ощутил все преимущества использования замыканий и немедленно вызываемых функций. Так, их использование избавило от постоянного поиска элементов на странице посредством getElementById и т.п.
Пример использования замыканий
controller.play = (function () { // блокировка множественного нажатия var cancelClick = false; return function (letter) { if (cancelClick) return; cancelClick = true; setTimeout(function () { cancelClick = false; }, 200) //код функции })()
Этапы выполнения приложения
В процессе инициализации приложения создаются все необходимые html-элементы, формируются объекты-списки для упрощения доступа к ним.
Содержимое html до инициализации
<body> <div id="gamefield"></div> <div id="help"> <h2>Правила</h2> <div class='textGuide'> <p>Необходимо составлять слова из показанного на экране слова. Слово должно быть нарицательным именем существительным в единственном числе. Уменьшительно-ласкательные формы, а также сокращения не принимаются. Минимальная длина слова - 3 буквы.</p> </div> <h2>Управление</h2> <div class='textGuide'> <p>Чтобы выбрать букву, кликните мышкой. Повторный клик по последней выбранной букве снимает выделение.</p> <p>Клавиша Esc отменяет ввод всего слова.</p> <p>Клавиша Backspace (←) отменяет ввод последней буквы.</p> </div> <h2>Игровые бонусы</h2> <div class="textGuide"> <p>Первая звезда - отгадать 40% возможных слов на уровне. Бонус: 1 000 очков.</p> <p>Вторая звезда - отгадать три слова, начинающихся на ту же букву, что и слово уровня. Бонус: 500 очков.</p> <p>Третья звезда - отгадать все возможные слова на уровне. Бонус: 50 000 очков.</p> </div> <h2>Подсказки</h2> <div> <img src="images/icons/tips/definition.png"> <p>Показать определение неотгаданного слова. Стоимость подсказки: 100 очков</p> </div> <div> <img src="images/icons/tips/word.png"> <p>Показать неотгаданное слово. Стоимость подсказки: 500 очков.</p> </div> <h2>Элементы интерфейса</h2> <div> <img src="images/icons/buttons_small/soundON.png"> <p>Управление звуком.</p> </div> <div> <img src="images/icons/buttons_small/menuButton.png"> <p>Вызов игрового меню.</p> </div> <div> <progress max="10" value="3"></progress> <p>Прогресс на уровне.</p> </div> </div> </body>
Содержимое html после инициализации
<body> <div id="gamefield" style="position: relative;"> <div> <div class="gameInfo"> <!-- Область информации о текущей сессии игры --> <h1>Слова из слова</h1> <div class="userName">Игрок: <span>123</span></div> <div class="currentLevel">Уровень: <span>1</span></div> <div class="menuLevel"> <!-- Переходы по уровням--> <div class="menuLabel">Карта уровней ⇩</div> <div class="levelMap" style="display: none;"> <a class="reached levelButton">1</a> <a class="levelButton">2</a> <a class="levelButton">3</a> <a class="levelButton">4</a> </div> </div> <div class="score">Очки: <span>0</span></div> <progress max="31" value="0" title="Отгадано 0 из 31 слов"></progress> <div class="tips"> <h2>Подсказки:</h2> <img id="wordDefinition" title="Показать определение неотгаданного слова." alt="Показать определение неотгаданного слова." src="images/icons/tips/definition_gray.png"> <img id="holeWord" title="Показать неотгаданное слово целиком." alt="Показать неотгаданное слово целиком." src="images/icons/tips/word_gray.png"></div> </div> <!-- Игровая область--> <div class="gameField"> <div class="missions"> <img src="images/icons/missions/incomplete.png" alt="Первая звезда" title="Отгадайте больше 40% слов"> <img src="images/icons/missions/incomplete.png" alt="Вторая звезда" title="Отгадайте 3 слова на букву "р""> <img src="images/icons/missions/incomplete.png" alt="Третья звезда" title="Отгадайте 100% слов"> </div> <div class="buttonGroup"> <img src="images/icons/buttons_small/soundON.png" alt="Выключить звук" title="Выключить звук"> <img src="images/icons/buttons_small/menuButton.png" alt="Меню" title="Игровое меню"> <img src="images/icons/buttons_small/help.png" title="Помощь" alt="Помощь"> </div> <!-- Отображение вводимого игроком слова --> <div class="userWord"></div> <div class="levelWord"> <!-- Буквы основного слова --> <div class="letter" data-order="0">р</div> <div class="letter" data-order="0">о</div> <div class="letter" data-order="0">д</div> <div class="letter" data-order="0">и</div> <div class="letter" data-order="0">н</div> <div class="letter" data-order="0">а</div></div> <!-- контейнер для найденных слов --> <div class="foundWords"></div> </div> </div> </div> </body>
Все информация о прохождении игроком уровня сохраняется в объекте GAME.model.level
Хранение информации о прохождении
level = { "1":{ "wordForLevel":"родина", "foundWords":["род","анод","аир"], "missions": { "progress":3, "firstStar":true, "secondStar":true, "thirdStar":true } } }
Для того, чтобы как-то сохранять прогресс и не задействовать при этом серверные скрипты и базы данных, был выбран способ сохранения в localStorage браузера. Кроме того, реализовал «таблицу рекордов» для игроков, которые используют это приложение в одном и том же браузере
Метод сохранения
/** * Сохранение результатов. * @method GAME.controller.storeResults * @param {string} name * Имя игрока. */ controller.storeResults = function (name) { var results = { level: GAME.utils.createClone(model.level), score: model.score } results = JSON.stringify(results); window.localStorage.setItem(name, results); }
Таким образом, представляю Вам на обсуждения мой проект. Буду рад выслушать конструктивную критику и предложения как в комментариях, так и в личном общении. Если интересуют подробности, с удовольствием расскажу о процессе написания подробнее.
Ссылка на репозиторий GitHub
UPD! Поиграть можно здесь
