Забытый enchantjs + новый 1С-Битрикс = Игра для мотивации клиентов

в 17:26, , рубрики: 1c-bitrix, 1С-Битрикс, javascript

image

Акции в интернет-магазинах бывают разные, а вот как их сделать визуально интересными для клиента — всегда вопрос, мы попробовали превратить обычную акцию в которой есть обычные статистические показатели клиента в игру в стили Dendy.

Здесь пойдёт речь о том как идеи маркетинга по мотивации клиентов можно визуализировать в небольшую игру для браузера.

Этап 1. От идеи к пониманию того что нужно

В один прекрасный день(перед началом лета), в отделе маркетинга созрела идея об организации мотивирующей акции для оптового направления клиентов. Из исходных данных как обычно у нас имелось следующее:

  1. Некоторый идентификатор клиента
  2. Показатели клиента
    • На какую общую сумму клиент приобрёл за некоторый промежуток времени
    • Какие бренды приобретались клиентом за этот промежуток времени
    • Как “честно” и ответственно клиент выполняет свои обязанности перед нами как перед поставщиками продукции
    • Какие “особые” ценовые условия клиент имеет на основании своей работы с нами
  3. Некоторый набор инструментов мотивации
    • Список “подарков” которые мы можем предложить клиенту за его сотрудничество и показатели
    • “Улучшители” его текущих ценовых предложений
    • Некоторый “Супер приз” самому… самому… самому ответственному и активному клиенту.

  4. Точка сосредоточения клиентов — личный кабинет с системой Онлайн-заказа, где мы можем что либо предлагать и о чём то важном сообщать.
  5. Учётная программа (“Жёлтая”) — где есть общая информация по каждому идентификатору клиента и его показателям.

С таким набором данных можно было бы организовать с ходу в личном кабинете:

  1. Баннер + “Купите вот это и получите вот это”
  2. Или таблицу с параметрами клиента, куда раз в сутки можно выгружать данные из учётной программы
  3. Так как сайт на 1С-Битрикс — можно сделать сложные “Правила корзины” для применения каких то скидок при соблюдении некоторых условий в зависимости от идентификатора клиента или сделать свою логику в рамках API с выводом некоторой статистики.

Всё это мы делали и делаем для информирования клиентов. Но в этом случаем захотелось попробовать что-то иное — создать игру — где показатели будут визуализироваться в абстрактные величины.

Этап 2. Итак, мы делаем игру и теперь ТЗ будет звучать так

Наша тематика это запчасти и по большей части — оптовые продажи автозапчастей, по этому была определена следующая структура игровой логики:

  1. В центре внимания — трасса по которой должен двигаться автомобиль
  2. Трасса где-то начинается и где-то заканчивается(старт и финиш), т.е трасса имеет заданную протяжённость в км.
  3. Старт — это точка отсчёта показателя — “пройденный путь”
  4. Финиш — это конечная точка по достижению которой мы можем предоставить клиенту особую привилегию или очень ценный приз.
  5. На трассе должны встречаться точки остановки(это может быть препятствие, остановка для принятия решения).
  6. Точка принятия решения (чекпоинт) — должна дать клиенту “плюшку” и возврат на старт либо отказ от “плюшки” и движение дальше.
  7. Препятствие — должно менять какие-то показатели.
  8. Для движения автомобиля будет использоваться топливо.
  9. Топливо это абстракция, литры которого получает клиент за соблюдение условия продаж + за выполнение задания/квестов.
  10. Расход топлива на 100 км. у автомобиля — это тоже абстракция которая зависит от показателей “честности” и “ответственности” клиента при соблюдении своих обязательств перед нами как перед поставщиками.
  11. Расход топлива должен быть в какой то градации и в разумных пределах.

При помощи “великого и могучего” получилось большую задачу разделить на мелкие подзадачи и подойти к пониманию выбора инструмента реализации. Что-бы не создавать “двухколёсного” для организации механики движения автомобиля был сделан выбор в пользу использования JavaScript каркаса.

Требования к игровому framework-у которые мы определили для себя стали следующие:

  1. 2D — карта
  2. Наложение спрайтов на карту
  3. Событийная модель
  4. “Быстрый старт”
  5. Документация

Всего было рассмотрено и опробовано 3-5 известных решений(в том числе малоизвестный PointJS). Всё что рассматривалось, действительно отличные движки для создания игр, но нужно было что-то лёгкое и был выбран enchantjs.

Enchantjs — простой движок с необходимым набором инструментов для создания несложной 2D игры.

Этап 3. Техническое проектирование

После того как мы наигрались с Enchantjs — пришло время набросать небольшую структура приложения.

— Таблицы и данные которые нужно сохранять (речь об MySQL)

  1. Сводная таблица текущих данных игрока( данные которые влияют на текущие параметры игры). Частично эта таблица модифицируется в процессе игры, частично из учётной программы.
  2. Изменения литров бензина. Это те абстракции которые клиент может заправить в свой виртуальный автомобиль. Сюда данные должны поступать только из учётной программы.
  3. История изменения километража. До куда добрался клиент на своём автомобиле, где у него закончился бензин, где он взял чекпоинт.
  4. Изменения расхода топлива. Например, сегодня у клиента автомобиль потребляет 9 л. на 100км, а завтра к клиенту появились замечания и его автомобиль увеличил расход до 11 л. на 100 км.
  5. Инфоблок в 1С-Битрикс, куда специалисты маркетинга будут заносить задания для клиентов.(сделай это… то … вот ещё это..., подтверди фоткой или ссылкой и получишь конфету или пониженный расход)
  6. Таблица с выполненными заданиями клиентов.
  7. Таблица чекпоинтов.(потребуется для отрисовки спрайтов с флажками на карте игры)
  8. Таблица подарков которые мы можем предоставить клиенту на чекпоинте.
  9. Таблица собранных чекпоинтов. (доехал клиент до чекпоинта, выбрал подарок и мы это записали)
  10. История расхода/прихода литров бензина. Т.е при движении есть расход, при заправке канистры — есть приход топлива. Эти данные нужны для информирования клиента.

— Компонент 1С — Битрикс

  1. Общий шаблон компонента
  2. Обработка запросов пользователя во время игры
  3. Обработка событий происходящих на поле игры
  4. Обработка действий совершаемых пользователем в интерфейсе управления игры

— Модуль 1С — Битрикс

  1. ORM всех требуемых таблиц
  2. Некоторые сервисные операции
  3. Агенты

— API для обмена с учётной программой
Обработка запросов на получение данных об игре учётной программой.
Обработка запросов на предоставление данных по игрокам учётной программой.

Этап 4. Реализация игровой сцены

В реализации приведу пример только того что касаемо enchantjs и сцены с игрой.

Для начала нам нужно создать сцену и сформировать карту для игры.

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

Части карты которые будут использованы в построении сцены игры

Исходник спрайта карты

image

enchant();//Подключаем библиотеку игры

var game = new Game(800,700);//Создание поля игры с шириной 800 и высотой 700

game.fps = 28; //Частота обновления кадров

game.scale = 1; //Увеличение карты

//Предзагрузка медиа(спрайты, картинки)
game.preload(‘red_car.gif’);
game.preload(‘airport.gif’);
game.preload(‘flag.gif’);

//Начало игры
game.onload = function() {

 var scene=new SceneGame();//Главная сцена игры

  game.pushScene(scene);
};

game.start();

Получили базовый синтаксис для создания сцены с игрой и запуска игры.

Суть в том что мы на HTML страницы отрисовываем прямоугольник на котором у нас будут происходить манипуляции с спрайтами.

Сразу оговорюсь, что при реализации игры, пришлось отказаться от событийной модели enchant и от концепции что все действия происходят в рамках изменения сцены под влиянием величины fps.

Определим главную сцену игры, отрисуем карту, расставим флажки и установим машинку на старт.

/**
* Главная сцена с картой
* @type {Scene}
*/
var SceneGame=Class.create(Scene,{

   initialize:function(){

       Scene.apply(this);

       game = Game.instance;

       var label=new Label('ООО Рога и Копыта');//Текстовый объект для карты

       var map = new Map(32,32);//Размер части map.gif на которой умещается 1-н элемент карты

       var car =new Car();//Объект характеризующий автомобиль

       var points_list=[];

       //Набор чекпоинтов для расстановке по маршруту
	//Как раз это те данные из таблицы которые мы берём по флажкам чекпоинтов
       for(var point_km in app_user.check_point){

           var flag_position=curent_odometr_to_coordinat(point_km);//Наша спец функция, которая киллометры превращает в координаты x и y - для точной установки спрайта на карту.

           var red_flag=new Redflag();//Объект описывающий 1-н чекпоинт флаг

           red_flag.x=flag_position.x;//Позиция 1-ого флага по x

           red_flag.y=flag_position.y;//Позиция 1-ого флага по y

           red_flag.rotation=0;//Градус на который повёрнут спрайт

           points_list.push(red_flag);

           delete red_flag;

       }

       this.red_flag=red_flag;

       this.car=car;

       map.image = game.assets[‘map.gif’];//Предзагрузка исходного материала карты
//Это наша карта, которая строится из квадратиков исходной map.gif
       var baseMap = [
   [24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24],
   [ 4,  1,  1,  1,  5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,  4,  1,  1,  1,  1,  5, 24, 24, 24, 24],
   [12, 24, 24, 24,  0, 24, 51, 47,  5, 24, 24, 24, 24, 24, 24, 24, 24,  0, 24, 24, 24, 24, 12, 24, 24, 24, 24],
   [12, 24, 24, 24,  0, 24, 24, 24,  0, 24, 24, 24, 24, 24, 24, 24, 24,  0, 24, 24, 24, 24, 12, 24, 24, 24, 24],
   [12, 24, 24, 24,  0, 24, 24, 25,  0, 24, 24, 24, 24, 24, 24, 24, 24,  0, 24, 24, 24, 24, 12, 24, 24, 24, 24],
   [12, 24, 24, 24,  0, 24, 24, 25,  0, 24, 24, 24, 24, 24, 24, 24, 24,  0, 24, 24, 24, 24, 12, 24, 24, 24, 24],
   [12, 24, 24, 24,  0, 24, 24, 25, 24, 24, 24, 24, 24, 24, 24, 24, 24,  0, 24, 24, 24, 24,  0, 24, 24, 24, 24],
   [12, 24, 24, 24,  8,  1,  1,  1,  5, 47, 22, 44,  4,  1,  1,  1,  5,  0, 24, 24, 24, 24, 11, 24, 24, 24, 24],
   [12, 24, 24, 24, 24, 24, 24, 24,  0, 24, 24, 24,  0, 24, 24, 24,  0,  0, 24, 24, 24, 24,  0, 24, 24, 24, 24],
   [12, 24, 24, 24, 24, 24, 24, 24,  0, 24, 24, 24,  0, 24, 24, 24,  0,  0, 24, 24, 24, 24,  0, 24, 24, 24, 24],
   [12, 24, 24, 24, 24, 24, 24, 24,  0, 24, 24, 24,  0, 24, 24, 24,  0,  0, 24, 24, 24, 24,  0, 24, 24, 24, 24],
   [12, 24, 24, 24, 24, 24, 24, 24,  8,  1,  1,  1,  9, 24, 24, 24, 12,  0, 24, 24, 24, 24,  8,  1,  1,  1,  8],
   [12, 24, 24, 24, 24, 24, 24,  4,  9, 57, 57, 24, 24, 24, 12, 24, 12,  8,  1,  1,  1,  1,  5, 24, 24, 24, 24],
   [12, 24, 24, 24, 24, 24, 24,  0, 49, 24, 24, 24, 24, 24, 12, 24, 12, 24, 24, 24, 24, 24,  0, 24, 24, 24, 24],
   [12, 24, 24, 24, 24, 24, 24,  0, 59, 50, 50, 50, 24, 24, 12, 24, 12, 24, 24, 24, 24, 24,  0, 24, 24, 24, 24],
   [12, 24, 24, 24, 24, 24, 24,  8,  1,  1,  1,  1,  5, 24, 12, 24, 12, 24, 24, 24, 24, 24,  0, 24, 24, 24, 24],
   [12, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,  8,  1,  9, 24, 12, 51, 51, 51, 51, 24,  0, 24, 24, 24, 24],
   [11, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,  8,  1,  1,  1,  1,  1,  9, 24, 24, 24, 24]
];
      }
        map.loadData(baseMap);

       this.addChild(map);//Добавляем карту на сцену

       this.addChild(car);

       for(var index_flag in points_list){//Расстановка созданных флажков - чекпоинтов
             this.addChild(points_list[index_flag]);
       }
     
});

Изображение карты

image

В результате получаем сцену с картой на которой есть дорога. На скриншоте флажки не указаны и не установлен автомобиль на старт(левый нижний угол).

Каждый объект спрайта в enchantjs как минимум постоянно содержит информацию о положении в системе координат, об угле поворота спрайта.

Набросок карты

image

Т.е. что-бы осуществить движение автомобиля по нарисованной карте, потребовалось:

  1. Описать его действий в пространстве при достижении изгиба трассы
  2. Описать действия автомобиля и направление движение в зависимости от угла поворота спрайта.

Т.е если у нас угол поворота 0 и так как у нас спрайт автомобиля начинает старт снизу вверх, то мы двигаемся к нулей точки координат по оси Y. Дальше мы встречаем изгиб трассы №1 и должны повернуть спрайт автомобиля на 90 градусов. Далее зная что мы расположены под углом 90 градусов — движемся по оси X до изгиба трассы № 2 и т.д.

Так мы научили автомобиль двигаться по нарисованной системе координат.

Для того что-бы привести взаимодействию автомобиля с дорогой в привычные нам величины — в дистанцию в пройденных км, потребовалось написать дополнительную функцию, которая принимает количество км. от 0 до 3000 и возвращает координаты точки на участке дороги.

Для движения автомобиля мы использовали setInterval который увеличивает значения x или у во время движения автомобиля

//Авто движение
var start=setInterval(function(){

   var position=car.getElementMap(car.x,car.y);

   position.map_num=map.checkTile(car.x,car.y);

  var move_result=car.move_car(position);

   //Жгём топливо и следим за баком
   var fuel_one_km=fuel_consumption(app_user.fuel_road);//расход на 1Км

   app_storage.fuel -=fuel_one_km;

   app_storage.fuel=parseFloat((app_storage.fuel).toFixed(2));

   if(app_storage.fuel<=0){
       //Обновить данные пользователя
       clearInterval(start);
       console.log('Бенз закончился!');
//Здесь создаём своё событие, которое дальше обработаем в компоненте Битрикс
         }
 
   var check_point_km=check_car_checkpoint(app_storage.km)

   //Обнаружение чекпоинта
   if(typeof check_point_km.point_km!=='undefined') {
       console.log('Флажок!');
	//Здесь создаём своё событие, которое дальше обработаем в компоненте Битрикс


   }
 
   if(position.car_x>780) {
       clearInterval(start);
   }

},app_conf().game.move_car_fps);

Карта, машинка, флажки

image

Во время движения, на игровой сцене происходят события:

  1. Наезд на флажки
  2. Окончание топлива
  3. Достижение финиша

По достижению этих событиях создаются события которые обрабатываются в управляющем скрипте компонента 1С-Битрикс.

Далее … далее

Следующими этапами для завершения игровой системы было:

  1. Создание интерфейса с кнопками управления
  2. Реакция на события на поле с игрой
  3. Изменения параметров игры в зависимости от действий пользователя
  4. Проверка параметров автомобиля на back end

В результате получилась вот такая игра в ЛК

Скрин ЛК

image

И немного видео

Автор: Евгений

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js