Нет ничего лучше, чем вновь почувствовать себя ребенком. Воспоминания с детства зачастую самые яркие и приятные. Случайно попавшаяся на просторах интернет фотография электронной игры «Ну, погоди!» («Электроника ИМ-02») навеяла массу воспоминаний и… породила желание не просто сыграть, а еще и реализовать её (специфика профессии). Собственно, результатом и хотел бы поделиться с аудиторией хабра. Игра «Ну, погоди!»
Полагаю, углубляться в описание логики игры и её игровых механизмов особой необходимости нет, многим она наверняка хорошо знакома еще с детства. Скажу только, что есть «плюшка» по достижении результата в 1000 игровых баллов — эдакий посыл к легендам тех времен. Дерзайте!
Игровой механизм реализован на «чистом» javascript. Исходники игры доступны на GitHub.
P.S. Буду рад, если у вас возникнет желание принять участие в развитии проекта — в формате критики/совета или кода в репозиторий на GitHub.
Обновления
1. Добавлены элементы управления для мобильных устройств. Рекомендованное минимальное разрешение экрана по ширине/высоте, в зависимости от ориентации вашего устройства, 640 пикселей.
2. Добавлены дополнительные элементы навигации для десктопной версии [Q, A, E, D]. Навигация «стрелочками» сохранена, так что теперь можно выбрать предпочтительный формат управления.
Комментарии (48)
chernish2
18.09.2015 06:40+14Это, скорее, не «Игра детства», а вариации на тему, посколько:
— без звука
— до счета 4 яйца в оригинале высыпаются по одному, а у Вас — сразу параллельно
— после 10 небольшое увеличение скорости в оригинале
— максимальное количество очков в оригинальной игре — не 1000, а 999
Ну и ссылку на Nintendo не помешало бы.
Но все равно конечно плюс в карму Вам!priv8v
18.09.2015 10:00+7Цыпленок из разбитого яйца не убегает и при этом (когда одно яйцо «разбивается») остальные яйца продолжают катится и падать, хотя после разбития яйца должен происходить «рестарт» для них.
Ocelot
18.09.2015 13:17+15Там немного хитрее логика была. Заяц наверху — он не просто так, во время игры этот заяц то появляется, то исчезает. Если уронить яйцо без зайца, оно просто разбивается, и получаешь штрафное очко. А если разбить с зайцем — вылупляется (и убегает) цыпленок, и дается всего 1/2 штрафного очка (мигающий символ).
dj_raphael
18.09.2015 23:05+3поэтому ставился будильник на +15 минут, как раз к 800 подбираешся и почти минуту все яйца сыпались только половинками
noder
18.09.2015 08:04+2Было бы не плохо добавить кнопки для игры на планшете/телефоне. Ещё бы больше походило на оригинал.
beaverBox
18.09.2015 08:24+2А для хардварных клав нужно забиндить управление на «1 Q Num* Num9» )) (для стандартных настольных клавиатур).
Aclz
18.09.2015 08:48+3Таких игр в плеймаркете over 9000shtange
18.09.2015 11:54В ближайших планах, добавление модификации для мобильных устройств, где управление будет осуществляться четырьмя навигационными кнопками как в оригинальной игре.
chernish2
18.09.2015 08:33-2Подумал, что можно придумать экшен из игр нашего детства, например, собрал 200 яиц — и вместо обнуления потерь на экран вылазит осьминог (с красивой графикой, конечно), и дальше уже водолаз собирает золото, убегая от щупалец. Ну а после 500 — Автослалом-mode.
yatagarasu
18.09.2015 10:05+3Управление не каноничное.
shtange
18.09.2015 12:02Реализация «каноничного» управления, с четырьмя навигационными кнопками, запланирована в модификации для мобильных устройств.
Dmitry_Zhariy
18.09.2015 10:10+10Очень классно сделано!
Скрипт для прохождения (или тестирования): gist.github.com/dzharii/1fce1ef335d0073c0ded
Откройся!// https://gist.github.com/ejoubaud/7d7c57cda1c10a4fae8c Podium = {}; Podium.keypress = function(k) { var oEvent = document.createEvent('KeyboardEvent'); // Chromium Hack Object.defineProperty(oEvent, 'keyCode', { get : function() { return this.keyCodeVal; } }); Object.defineProperty(oEvent, 'which', { get : function() { return this.keyCodeVal; } }); if (oEvent.initKeyboardEvent) { oEvent.initKeyboardEvent("keydown", true, true, document.defaultView, k, k, "", "", false, ""); } else { oEvent.initKeyEvent("keydown", true, true, document.defaultView, false, false, false, false, k, 0); } oEvent.keyCodeVal = k; if (oEvent.keyCode !== k) { alert("keyCode mismatch " + oEvent.keyCode + "(" + oEvent.which + ")"); } document.body.dispatchEvent(oEvent); }; var keyb = { up:38, // Up right:39, // Right down:40, // Down left:37 // Left }; function Play() { var gameWrap = document.getElementById("game-wrap"); var ds = gameWrap.dataset; var eggs = { downLeft: ds["egg-0"], topLeft: ds["egg-1"], topRight: ds["egg-2"], downRight: ds["egg-3"] }; console.log(eggs); if (eggs.topLeft == 5) { Podium.keypress(keyb.left); Podium.keypress(keyb.up); console.log("topLeft"); } else if (eggs.downLeft == 5) { Podium.keypress(keyb.left); Podium.keypress(keyb.down); console.log("downLeft"); } else if (eggs.downRight == 5) { Podium.keypress(keyb.right); Podium.keypress(keyb.down); console.log("downRight"); } else if (eggs.topRight == 5) { Podium.keypress(keyb.right); Podium.keypress(keyb.up); console.log("topRight"); } } setInterval(Play, 10);
imbeat
18.09.2015 11:49+2Большое спасибо, подняли настроение! Игра — класс!
Позволю себе лишь одно замечание — управление неудобное… чтобы переместить корзину по диагонали, нужно две клавиши нажать. Для меня бы идеальным решением было управление на клавишах типа: [q, a, e, d] или [Num7, Num4, Num9, Num6].
Еще раз большое спасибо! Отправил жене, она тоже в восторге!shtange
18.09.2015 12:36Спасибо на добром слове. Отличная идея насчет добавления дополнительного блока управления, чтобы нивелировать проблему с перемещением по диагонали. Постараюсь в ближайшее время интегрировать дополнительный навигационный блок, скорее всего с привязкой к клавишам [Num7, Num4, Num9, Num6].
Pulik
18.09.2015 13:07+2В оригинале управление было двумя руками, для более полного погружения было бы хорошо если бы управление можно было повесить на разные края клавиатуры, например: [q, a, Num9, Num6]. Тогда можно взять клавиатуру в руки (кроме ноутбуков конечно) и представлять, что держишь настоящую портативку тех времен)
shtange
18.09.2015 15:50Идея интересная, но не уверен что такая реализация будет востребована. Мне ближе вариант реализации модификации с четырьмя навигационными кнопками для мобильных устройств (по примеру оригинальной игры). Тогда, взяв в руки условный планшет, будет возникать гораздо более близкая аналогия с оригинальным устройством.
chernish2
18.09.2015 13:28+2Игра «Ну, погоди!» — это, конечно, символ эпохи. Но это далеко не самая крутая игра из всей серии.
А самая крутая — это конечно «Тайны океана», потому что в ней, в отличие от всех остальных, вместо того, чтобы в нужный момент нажимать заданную кнопку, можно самому выбирать стратегию игры: хочешь — набирай золото из сундука (по одному очку), хочешь — таскай его из сундука в лодку (1 + 3 очка), хочешь — бегай под осьминогом на время, хочешь — вообще в лодке сиди (только когда тебя насильно в море сбрасывают уворачивайся от щупалец, и назад, в лодку).
Даже в «Автослаломе» (который, насколько я помню, едиснтвенная оригинальная отечественная игра) нет такой свободы действий!
Хотя, конечно, и эмуляторов Octopus хватает.shtange
18.09.2015 14:42Присматриваюсь к игре «Тайны океана». Она несколько более сложная в реализации, но в том что интереснее — согласен полностью. Желание реализовать все три игры из этой серии в наличии, но все упирается в свободное время… его не так много.
chernish2
18.09.2015 15:16О, игр там не три, а десятки!
Только советских клонов можно десяток вспомнить, а уж оригинальных Nintendo куда больше, взять хотя бы серию про Donkey Kong (особенно вариант-раскладушку с двумя экранами).
Вот тут далеко не все что было: www.emulator3000.org/hq.htmshtange
18.09.2015 16:01Перешел по вашей ссылке и вспомнил еще одну замечательную игру в которую доводилось играть — «Весёлый повар». Единственное, с точки зрения реализации она не сильно отличается от «Ну, погоди!». В этом смысле разработка игры по мотивам «Тайны океана» более сложная и соответственно более интересная задача.
berman
18.09.2015 21:17Код у вас читабельный и чистенький, вы молодец. Кстати, последнее время избегаю case/switch и вместо него пользуюсь вот таким паттерном
var strategies = { one: breakHead, two: destroyEnemy, three: forgetFriends }, strategyNotFound = function() { throw new Error("Strategy not found"); } var proceedWith = strategies[value] || strategyNotFound; proceedWith();
shtange
18.09.2015 21:52Какие мотивы побудили вас избегать использования case/switch? И если это возможно, подскажите источник, где можно прочесть обоснование. Спасибо
Eltaron
22.09.2015 11:34+1Для нетерпеливых: F12 — консоль — «new GameManager().gameWin()». А то меня хватило лишь на 724, но я и в детстве всю не проходил.
knitevision1
Вау. Дизайн красивый, цвета и всё такое. Круто. А почему не захотели рассказать о том, как реализовывали и все такое? Какие-нибудь интересные места в решениях и прочее?
shtange
Умение сделать и умение рассказать/объяснить другому, к сожалению не всегда идут в одной связке. У меня с последним «не очень»…