Lines 9753: День Сурка

                Если долго играть в кубики,
                то они превращаются в шарики

    Глядя на название игры Lines 9753, можно подумать, что этот рассказ про 9753-ий клон известной игры Color Lines, в которой надо составлять по 5 шариков в ряд одного цвета. Да, так и есть, клон. Ну что ещё может быть нового? Я поделюсь своими идеями и некоторыми тонкостями реализации на HTML+CSS+JavaScript. Расскажу что значат цифры 9753. Предложу способ найти другую комбинацию цифр и посмотреть, как изменится игра. Станет она интереснее или скучнее — решать вам. Ещё не догадались, что значит 9753? Тогда, прошу под кат.

    Многообразие вариантов игры


    Никогда не задумывались, откуда в оригинальной игре взялась размерность поля 9x9? Удивительно, насколько хорошо подобраны не только размерность игры, но и другие параметры, так что играть интересно: количество цветов — 7, количество шариков в ряд — 5 и количество появляющихся шаров за ход — 3. Эти 4 параметра поставлены в название игры — Lines 9753. Именно эта четвёрка по-большому счёту определяет сложность игры, которая скорее всего, подходит не всем.


    Возможно, кому-то придётся по душе другой набор. Например:

    • 3333 — легкотня типа пасьянса, можно не бояться зайти в тупик и постараться схлопывать как можно больше шариков за раз (5 ещё легко, 6 уже сложнее, 7 и 8 практически нереально), подойдёт в случае, когда совсем не хочется думать;
    • 5643 — на доске 5x5 клетки не такие мелкие как 9x9, поэтому удобно играть на телефоне, однако сложность, кажется чуть выше, чем в 9753;
    • 5543 — несколько более лёгкий вариант чем 5643, потому что количество различных цветов меньше, а значит больше вероятность составить ряд шаров одного цвета;
    • 4443 — по сложности сравнима с 5643, но шарики ещё крупнее — всего 4 шара по короткой стороне экрана.



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

    Ход назад


    Разрешается делать ходы назад. Давным-давно, когда деревья были высокими, а я был ещё студентом довелось, мне поиграть в Color Lines. Игра очень понравилась. Один раз, проиграв в неё полдня и, набрав несколько тысяч очков, я зашел в тупик. Пришло осознание того, что это была случайность, что шары выпадали удачно, и что в ближайшее время так далеко я пройти не смогу. Чтобы побить свой же рекорд, мне надо будет убить раз в десять больше времени, и то если повезёт. С тех пор я долго не играл в эту игру. Ощущение вселенской несправедливости засело глубоко в душе. И сидело оно там до тех пор, пока не выкристаллизовался коварный план мести — сделать такую же игру, но с возможностью отматывать ходы назад хоть до самого начала. Именно эта опция стала для меня главной мотивирующей причиной написать игру по-своему.

    Фиксированная случайность


    Некоторые игроки говорили, что иногда машина специально ставит шары в неудобные места, чтобы усложнить прохождение. Особенно, когда остаётся совсем мало свободных клеток, невозможно дождаться нужного шара в нужном месте. Другими, словами, случайность в игре совсем не случайна. С новой возможностью отматывать ходы назад, было бы не логично предлагать каждый раз новое место для новых шаров. Так можно было бы ходить вперёд и назад до тех пор, пока не появится нужный шар в нужном месте. Поэтому в игре все ходы машины детерминированы и зависят случайным образом от номера хода и расположения шаров на поле. Мало того, все играют одну и туже игру. То есть, игра начинается с одной и той же расстановки (первый ход машины), и далее ходы машины зависят от того, как сходит игрок: если игроки ходят одинаково, то и на поле у них будет одинаковая расстановка шаров. Это позволяет объективно и независимо от случайности сравнивать разные решения. Некоторые любят меряться кто дальше, кто быстрее,… Решения в виде последовательности ходов игрока отправляются на сервер. Ходы машины вычисляются всё по тому же случайному алгоритму. Обмануть сервер не получится, вся последовательность проверяется на корректность, и только потом результат заносится в таблицу. Все рекорды сохраняются вместе с последовательностью ходов игрока. Потом проанализируем и опубликуем лучшие решения тех кто наберет 9999 очков. Нужно будет придумать, по какому критерию выбирать лучших.


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

    Подсказка


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

    Подсчёт очков


    Подсчёт очков сделан по классической формуле N * (1 + N — DIMENSION), где N — количество шаров в линии, DIMENSION — размерность игрового поля. То есть 5, 6, 7, 8 собранных вместе шаров дают соответственно 5, 12, 21 и 32 очка. Для варианта игры 3333 при схлопывании 3, 4, 5 и 6 шаров получается 3, 8, 15, 24.

    Графика


    Графика только векторная — не люблю артефакты масштабирования, особенно нечёткие границы. Основные анимированные графические элементы: винтажный магнитофонный счётчик и прыгающие шарики с бликами и градиентным освещением. Они выполнены с использованием CSS и приправлены кусочками JavaScript. Изначально была сделана тёмная цветовая схема. Её можно попробовать, включив в настройках. Однако всё выглядит мрачновато. Светлая мне больше нравится.

    Трёхмерный шарик


    Как ни парадоксально звучит, но из 3-х вложенных друг в друга прямоугольников получается трёхмерный шарик:


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

    С контейнером всё просто. Его CSS атрибуты position, left и top задают координаты шарика на поле, а font-size задаёт размер, относительно которого масштабируются два других квадрата. Круглый квадрат, это, как подавляющее большинство кругляшков, на наших web страницах, просто квадрат с максимально закруглёнными углами. Когда на него нажимаем мышкой, его плющит, сжимая сверху и расширяя бока. А если нажатие оказывается быстрым как мышиный клик, то шарик аж подпрыгивать начинает.


    @keyframes flat {
                0%   {height: 1.0em; width: 1.0em; top: 0; left: 0em;}
                100% {height: 0.9em; width: 1.05em; top: 0.1em; left: -0.025em;}
            }
    
    @keyframes jumping {
                0%   {height: 0.9em;   width: 1.025em; top: 0.1em;   left: -0.0125em;}
                10%  {height: 1.02em;  width: 1.0em;   top: -0.02em; left: 0em;}
                40%  {height: 1.008em; width: 1.0em;   top: -0.18em; left: 0em;}
                50%  {height: 1.01em;  width: 1.0em;   top: -0.2em;  left: 0em;}
                60%  {height: 1.0em;   width: 1.0em;   top: -0.18em; left: 0em;}
                70%  {height: 1.0em;   width: 1.0em;   top: -0.1em;  left: 0em;}
                90%  {height: 1.0em;   width: 1.0em;   top: 0em;     left: 0em;}
                100% {height: 0.9em;   width: 1.025em; top: 0.1em;   left: -0.0125em;}
            }
    

    Максимальное количество цветов 15.


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

    Счётчик


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


    Звук


    Звуки (взрыв и прыжки) синтетические. Они генерируются по незамысловатым математическим формулам. Это создаёт некоторый привкус 80-х, когда большинство звуков в играх генерировалось с использованием одноголосного частотного генератора. К плюсам можно отнести компактность программы: простенький генератор таких звуковых эффектов, написанный на JavaScript, оказывается значительно меньше по размеру, чем mp3 файл. Для каждого шарика выбираем свою пару нот lowFreq и highFreq (см. wikipedia) и заполняем аудиобуфер примерно вот так:

        var soundUpBuffer = audioCtx.createBuffer(1, frameCount, sampleRate);
        for (var i = 0; i < frameCount; i++) {
          var x = i / frameCount; // from 0.0 to 1.0
          var time = duration * x;
          var volume = Math.sin(x * Math.PI);
          var freq = lowFreq + Math.sqrt(x) * (highFreq - lowFreq);
          buffer[i] = volume * Math.sin(2 * Math.PI * freq * time);
        }
    

    Здесь частота изменяется от lowFreq до highFreq по кривой x½, а громкость sin(π x).

    У взрыва громкость затухает по формуле 1/(1+10*x+1000*x*x), а частота выбирается случайно с первой по пятую октаву.

    Адаптивный размер диалогового окна


    Реализован алгоритм подбора размера диалогового окна, так чтобы оно занимало как можно больше пространства и не выходило за границы видимой области. Проблема заключается в том, что на разных устройствах размер диалогов разный — иногда получается слишком мелко, а иногда не входит в экран. Я сделал размер диалогов зависимым от размера шрифта (CSS единицы em). Далее, перебираю размер шрифта, чтобы диалог занимал не более 95% любой из размерностей экрана. Так не пришлось городить кейсы для адаптивного CSS.


    Небольшой размер программы


    Вся игра умещается в одном html файле около 150Кб. Около 3000 строк исходного кода (конечно без серверной части). Никакие JavaScript библиотеки и фреймворки не использовались — всё натурально, как в каменном веке. Иногда просто не хочется разбираться со сторонним API, а иногда полезно понять, насколько сильно фреймворки упрощают жизнь изобретателя велосипедов и испытателя новых граблей. Полезно бывает сначала придумать самому как можно реализовать ту или иную идею, а уж потом сравнить с тем как это сделали другие. Например, версия под Андроид занимает всего 250Кб. Она состоит из тонкой WebView обёртки и пачки png-шек под разные разрешения телефонов. Кстати, png-шки можно было бы заменить одной векторной xml-кой. Получилось бы точно в духе минимализма.

    Форум


    Форум работает на phpBB. Эккаунт позволяет:

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

    i18n и l10n


    Интернационализация и локализация. Игра переведена на русский и английский. Всего 35 коротких фраз. Я бы не отказался от бесплатной помощи по переводу ещё на несколько популярных языков (Китайский, Немецкий, ...).

    Никакой рекламы


    Часто можно услышать мнение, что если программа бесплатная и без рекламы, то значит троян, бэкдор, вирус, … Другими словами, бесплатный сыр только в мышеловке. Иначе зачем? Почему кто-то готов делать что-то для других безвозмездно? Я общего ответа не знаю. Мало того, не знаю точно, почему сам это делаю. Мне просто интересно. Если что-то нравится, то я часто задумываюсь, как автору это удалось. Хочется попробовать сделать так же или даже лучше. Иногда всё нравится, за исключением каких-то деталей, и возникает желание сделать подобное, но со своим блэк джеком и финтифлюшками.

    Заключение


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

    Ссылки


    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 13

      +1
      Только не смейтесь, но мне хотелось бы иметь эту игруху на десктопе. У меня на Рабочем столе уже много лет висит значок от Lines99 (это та версия, где шарики отличаются не только цветом, но и текстурами, один из «цветов» даже бесцветный, в виде прозрачных кристаллов). Конечно, в описываемой версии текстур нет, зато автор добавил кучу интересных (и непривычных для меня) опций, которые я с удовольствием опробовал бы не на мобиле.
        0
        Могу предложить свой вариант. Если смущает запуск из Интернета, можно сделать локальную версию, а можно просто скачать полный архив (он правда большой) и найти там Lines. Фич конечно меньше чем у автора поста.
          0

          У меня есть десктоп-вариант: https://github.com/emorozov/gtkballs.
          Работает без интернета, никакой телеметрии (когда писал в 98 году, еще и слова такого не было).
          Входит почти во все дистрибутивы Linux и FreeBSD.


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

            0

            Входит почти во все дистрибутивы Linux и FreeBSD
            Прикольно! :) Что-то не отвечает сайт http://gtkballs.antex.ru
            Мне не очень нравится привязка к платформе Gtk. Всё-таки HTML+CSS+JavaScript кажется более универсальной, потому что может работать в любом чайнике и даже на Windows.

              0
              Что-то не отвечает сайт http://gtkballs.antex.ru

              У меня отвечает, только что открылся сразу же.


              Мне не очень нравится привязка к платформе Gtk. Всё-таки HTML+CSS+JavaScript кажется более

              В 98-м, когда сделал первую версию, никакой альтернативы в принципе не было (разве что Java, но Java была просто ужасной тогда, да и сейчас ее не люблю, и не для десктоп-приложений она).


              И у меня противоположные чувства, я как раз активно не люблю современный веб, все эти реакты-электроны, переизобретение велосипедов 100 раз на дню, 10^6 уровней абстракции из-за которых все адски тормозит, и так далее.

          0

          nehrung эта игруха вся содержится в одном 100кб файле https://www.quadpuzzle.ru/lines/lines.html. Скачайне его, положите себе на десктоп и запускайте как обычный html.

          0
          Color Lines с разными степенями сложности тут: keda.su/colorlines
          сайт легкий, весит мало, реализация не типичная какая-то.
            0
            Шарики медленно перемещаются. Можно задавать скорость в настройках?
              0

              в настройках нет, но в исходнике есть возможность изменять скорость всей анимации целиком. Надо пару вызовов setTimeScale(0.7) заменить на setTimeScale(0.3).

                0
                При этом шарик и на месте стал прыгать быстрее.
              0
              В результатах игры на сайте хорошо бы, если бы указывалось, сколько было ходов назад в игре, чтобы увидеть тех, кто играет «в один проход».
                0

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

                0
                Да, но тогда появится боязнь сделать неправильный ход. Этого, как раз, хотелось избежать. К тому же, появилась бы возможность для читов: сначала можно было бы играть как попало, а потом, зная правильные ходы, можно было бы сыграть начисто.

                Немного странная логика как по мне.

                Эти 4 параметра поставлены в название игры — Lines 9753. Именно эта четвёрка по-большому счёту определяет сложность игры, которая скорее всего, подходит не всем.

                При этой сложности 9753 можно здесь не напрягаясь играть бесконечно без ходов назад. В чем фишка то?

                Only users with full accounts can post comments. Log in, please.