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 коротких фраз. Я бы не отказался от бесплатной помощи по переводу ещё на несколько популярных языков (Китайский, Немецкий, ...).

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


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

    Заключение


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

    Ссылки


    Средняя зарплата в IT

    120 000 ₽/мес.
    Средняя зарплата по всем IT-специализациям на основании 7 154 анкет, за 1-ое пол. 2021 года Узнать свою зарплату
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 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 можно здесь не напрягаясь играть бесконечно без ходов назад. В чем фишка то?

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое