Нет ничего лучше, чем вновь почувствовать себя ребенком. Воспоминания с детства зачастую самые яркие и приятные. Случайно попавшаяся на просторах интернет фотография электронной игры «Ну, погоди!» («Электроника ИМ-02») навеяла массу воспоминаний и… породила желание не просто сыграть, а еще и реализовать её (специфика профессии). Собственно, результатом и хотел бы поделиться с аудиторией хабра. Игра «Ну, погоди!»

Полагаю, углубляться в описание логики игры и её игровых механизмов особой необходимости нет, многим она наверняка хорошо знакома еще с детства. Скажу только, что есть «плюшка» по достижении результата в 1000 игровых баллов — эдакий посыл к легендам тех времен. Дерзайте!

Игровой механизм реализован на «чистом» javascript. Исходники игры доступны на GitHub.

P.S. Буду рад, если у вас возникнет желание принять участие в развитии проекта — в формате критики/совета или кода в репозиторий на GitHub.

Обновления


1. Добавлены элементы управления для мобильных устройств. Рекомендованное минимальное разрешение экрана по ширине/высоте, в зависимости от ориентации вашего устройства, 640 пикселей.
скриншот


2. Добавлены дополнительные элементы навигации для десктопной версии [Q, A, E, D]. Навигация «стрелочками» сохранена, так что теперь можно выбрать предпочтительный формат управления.

Комментарии (48)


  1. knitevision1
    18.09.2015 03:16
    +4

    Вау. Дизайн красивый, цвета и всё такое. Круто. А почему не захотели рассказать о том, как реализовывали и все такое? Какие-нибудь интересные места в решениях и прочее?


    1. shtange
      18.09.2015 11:17

      Умение сделать и умение рассказать/объяснить другому, к сожалению не всегда идут в одной связке. У меня с последним «не очень»…


  1. ZoomLS
    18.09.2015 03:19
    +12

    Жаль, что звука нет :)


    1. shtange
      18.09.2015 11:23

      Согласен, без звука немного «пресно» получается. Озвучивание — первый номер в списке доработок.


  1. brainick
    18.09.2015 04:05
    +11

    Ну у вас то хоть мультик, когда 999 очков наберешь показывается? )
    UPD. Увидел, что есть сюрприз.


    1. orcy
      18.09.2015 11:07
      +3

      multik is a lie


  1. chernish2
    18.09.2015 06:40
    +14

    Это, скорее, не «Игра детства», а вариации на тему, посколько:
    — без звука
    — до счета 4 яйца в оригинале высыпаются по одному, а у Вас — сразу параллельно
    — после 10 небольшое увеличение скорости в оригинале
    — максимальное количество очков в оригинальной игре — не 1000, а 999
    Ну и ссылку на Nintendo не помешало бы.
    Но все равно конечно плюс в карму Вам!


    1. chernish2
      18.09.2015 08:35
      +15

      И самое ключевое — ИГРА А / ИГРА Б обязательно должны присутствовать! Бог с ним, с будильником, но это святое!


      1. medvoodoo
        18.09.2015 14:09
        +1

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


    1. priv8v
      18.09.2015 10:00
      +7

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


      1. Ocelot
        18.09.2015 13:17
        +15

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


        1. dj_raphael
          18.09.2015 23:05
          +3

          поэтому ставился будильник на +15 минут, как раз к 800 подбираешся и почти минуту все яйца сыпались только половинками


  1. tyderh
    18.09.2015 07:45
    +3

    «Замечательная» типографика: Catch the Ecc


  1. vc54
    18.09.2015 07:51
    +12

    Лайк, если мысленно воспроизводил звуки :-)


  1. noder
    18.09.2015 08:04
    +2

    Было бы не плохо добавить кнопки для игры на планшете/телефоне. Ещё бы больше походило на оригинал.


    1. beaverBox
      18.09.2015 08:24
      +2

      А для хардварных клав нужно забиндить управление на «1 Q Num* Num9» )) (для стандартных настольных клавиатур).


    1. Aclz
      18.09.2015 08:48
      +3

      Таких игр в плеймаркете over 9000
      image


      1. shtange
        18.09.2015 11:54

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


  1. chernish2
    18.09.2015 08:33
    -2

    Подумал, что можно придумать экшен из игр нашего детства, например, собрал 200 яиц — и вместо обнуления потерь на экран вылазит осьминог (с красивой графикой, конечно), и дальше уже водолаз собирает золото, убегая от щупалец. Ну а после 500 — Автослалом-mode.


  1. rafuck
    18.09.2015 08:45
    +9

    Если нужно переместиться по диагонали, приходится жать две кнопки, а не одну, как в оригинале.


    1. shtange
      22.09.2015 18:05

      Добавлен альтернативный блок управления, подробнее в списке обновлений.


  1. uglock
    18.09.2015 08:52
    -6

    Cool. Nice and clean code.


  1. savostin
    18.09.2015 09:26

    Чето сложность не увеличивается…


    1. shtange
      18.09.2015 11:42

      Увеличивается, но достаточно плавно. Ближе к заветной 1000 баллов будет ощутимо сложнее успевать ловить яйца


      1. savostin
        18.09.2015 11:44

        Мне нужно больше усидчивости…


      1. maxlips
        22.09.2015 13:20

        Мне показалось, что в оригинале было хардкорнее.


  1. Lopar
    18.09.2015 09:32

    Волк настолько хорошо прорисован, что не верится, что это та игра. :)


  1. yatagarasu
    18.09.2015 10:05
    +3

    Управление не каноничное.


    1. shtange
      18.09.2015 12:02

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


  1. 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);
    


    1. shtange
      18.09.2015 12:24
      +1

      Спасибо, возьму на заметку.


  1. imbeat
    18.09.2015 11:49
    +2

    Большое спасибо, подняли настроение! Игра — класс!
    Позволю себе лишь одно замечание — управление неудобное… чтобы переместить корзину по диагонали, нужно две клавиши нажать. Для меня бы идеальным решением было управление на клавишах типа: [q, a, e, d] или [Num7, Num4, Num9, Num6].
    Еще раз большое спасибо! Отправил жене, она тоже в восторге!


    1. shtange
      18.09.2015 12:36

      Спасибо на добром слове. Отличная идея насчет добавления дополнительного блока управления, чтобы нивелировать проблему с перемещением по диагонали. Постараюсь в ближайшее время интегрировать дополнительный навигационный блок, скорее всего с привязкой к клавишам [Num7, Num4, Num9, Num6].


      1. n43jl
        18.09.2015 12:58

        На некоторых ноутбуках num-keypad может быть проблемой)


      1. Pulik
        18.09.2015 13:07
        +2

        В оригинале управление было двумя руками, для более полного погружения было бы хорошо если бы управление можно было повесить на разные края клавиатуры, например: [q, a, Num9, Num6]. Тогда можно взять клавиатуру в руки (кроме ноутбуков конечно) и представлять, что держишь настоящую портативку тех времен)


        1. shtange
          18.09.2015 15:50

          Идея интересная, но не уверен что такая реализация будет востребована. Мне ближе вариант реализации модификации с четырьмя навигационными кнопками для мобильных устройств (по примеру оригинальной игры). Тогда, взяв в руки условный планшет, будет возникать гораздо более близкая аналогия с оригинальным устройством.


        1. RolexStrider
          18.09.2015 22:19
          +1

          Да, например как вариант — QAPL.


    1. shtange
      22.09.2015 18:00

      Добавлен дополнительный блок управления клавишами [Q, A, E, D].


  1. chernish2
    18.09.2015 13:28
    +2

    Игра «Ну, погоди!» — это, конечно, символ эпохи. Но это далеко не самая крутая игра из всей серии.
    А самая крутая — это конечно «Тайны океана», потому что в ней, в отличие от всех остальных, вместо того, чтобы в нужный момент нажимать заданную кнопку, можно самому выбирать стратегию игры: хочешь — набирай золото из сундука (по одному очку), хочешь — таскай его из сундука в лодку (1 + 3 очка), хочешь — бегай под осьминогом на время, хочешь — вообще в лодке сиди (только когда тебя насильно в море сбрасывают уворачивайся от щупалец, и назад, в лодку).
    Даже в «Автослаломе» (который, насколько я помню, едиснтвенная оригинальная отечественная игра) нет такой свободы действий!
    Хотя, конечно, и эмуляторов Octopus хватает.


    1. shtange
      18.09.2015 14:42

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


      1. chernish2
        18.09.2015 15:16

        О, игр там не три, а десятки!
        Только советских клонов можно десяток вспомнить, а уж оригинальных Nintendo куда больше, взять хотя бы серию про Donkey Kong (особенно вариант-раскладушку с двумя экранами).
        Вот тут далеко не все что было: www.emulator3000.org/hq.htm


        1. shtange
          18.09.2015 16:01

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



  1. 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();
    



    1. shtange
      18.09.2015 21:52

      Какие мотивы побудили вас избегать использования case/switch? И если это возможно, подскажите источник, где можно прочесть обоснование. Спасибо


      1. berman
        18.09.2015 23:32

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


  1. maxatwork
    20.09.2015 03:16
    +3

    О, наконец-то мультик в конце игры!


  1. Eltaron
    22.09.2015 11:34
    +1

    Для нетерпеливых: F12 — консоль — «new GameManager().gameWin()». А то меня хватило лишь на 724, но я и в детстве всю не проходил.