Forgotten enchantjs + new 1C-Bitrix = Game for customer motivation
Stocks in online stores can be different, but how to make them visually interesting for a client is always a question, we tried to turn a common stock in which there are regular client statistics into a game in Dendy styles.
Here we will talk about how marketing ideas to motivate customers can be visualized in a small game for the browser.
Stage 1. From idea to understanding what is needed
One fine day (before the start of summer), the idea of organizing a motivating campaign for the wholesale direction of customers matured in the marketing department. From the source data, as usual, we had the following:
- Some customer id
- Customer metrics
- What is the total amount the client purchased for a certain period of time
- What brands were acquired by the client during this period of time?
- How “honestly” and responsibly the client fulfills his obligations to us as to suppliers of products
- What “special” price conditions does the client have based on his work with us
- Some set of motivation tools.
- The list of “gifts” that we can offer the client for his cooperation and performance
- “Improvers” of his current price offers
- Some “Super prize” to the most ... the most ... the most responsible and active client.
- The point of customer concentration is a personal account with an online ordering system where we can offer something and report something important.
- Accounting program (“Yellow”) - where there is general information for each client identifier and its indicators.
With this data set, you could organize on the go in your account:
- Banner + “Buy this and get this”
- Or a table with client parameters, where once a day you can upload data from an accounting program
- Since the site is on 1C-Bitrix, you can make complex “Basket Rules” to apply some discounts if certain conditions are met depending on the client’s identifier or make your own logic within the API with some statistics displayed.
All this we have done and are doing to inform customers. But in this case I wanted to try something else - to create a game - where the indicators will be visualized in abstract quantities.
Stage 2. So, we make the game and now TK will sound like this
Our topic is spare parts and for the most part - wholesale sales of auto parts, according to this, the following structure of game logic was determined:
- In the spotlight - the track along which the car should move
- The route starts somewhere and ends somewhere (start and finish), i.e. the route has a given length in km.
- Start is a reference point of an indicator - “the passed way”
- The finish line is the endpoint upon reaching which we can provide the client with a special privilege or a very valuable prize.
- There should be stopping points on the highway (this could be an obstacle, a stop for a decision).
- The decision point (checkpoint) - should give the client a “bun” and return to the start or rejection of the “bun” and move on.
- Obstacle - should change some indicators.
- For the movement of the car will be used fuel.
- Fuel is an abstraction, liters of which the client receives for observing the terms of sales + for completing tasks / quests.
- Fuel consumption per 100 km. in a car - this is also an abstraction which depends on the indicators of “honesty” and “responsibility” of the client, in compliance with their obligations to us as suppliers.
- Fuel consumption should be in some sort of gradation and within reasonable limits.
With the help of the “great and mighty” it turned out to be a big task to divide into small subtasks and come to an understanding of the choice of implementation tool. In order not to create a “two-wheeled” vehicle for organizing the mechanics of car movement, a choice was made in favor of using a JavaScript framework.
The requirements for the game framework that we determined for ourselves are as follows:
- 2D map
- Map sprites
- Event model
- "Fast start"
- Documentation
In total, 3-5 well-known solutions (including the little-known PointJS) were reviewed and tested. All that was considered, really great engines for creating games, but you needed something easy and enchantjs was chosen.
Enchantjs is a simple engine with the necessary set of tools for creating a simple 2D game.
Stage 3. Technical design
After we’ve played enough with Enchantjs, it’s time to outline a small application structure.
- Tables and data to be saved (talking about MySQL)
- A summary table of the current player data (data that affect the current game settings). Partly this table is modified during the game, partly from the accounting program.
- Changes in liters of gasoline. These are the abstractions that the client can fill in his virtual car. This data should come only from the accounting program.
- History of mileage changes. Where the client got to in his car, where he ran out of gas, where he took the checkpoint.
- Fuel consumption changes. For example, today a customer consumes a car of 9 liters. 100km, and tomorrow there were comments to the client and his car increased consumption to 11 liters. per 100 km.
- Infoblock in 1C-Bitrix, where marketing specialists will enter tasks for customers. (Do it ... then ... here it is ..., confirm with a photo or link and you will get candy or reduced consumption)
- A table with completed customer assignments.
- Checkpoint table. (Required to draw sprites with flags on the game map)
- A table of gifts that we can provide to the client at checkpoint.
- Table of collected checkpoints. (the client reached the checkpoint, chose a gift and we wrote it down)
- History of the consumption / arrival of liters of gasoline. That is, when driving there is an expense, when refueling a canister - there is a fuel arrival. This data is needed to inform the client.
- Component 1C - Bitrix
- Common component template
- Processing user requests during the game
- Processing events occurring on the game field
- Processing actions performed by the user in the game management interface
- Module 1C - Bitrix
- ORM of all required tables
- Some service operations
- Agents
- API for exchange with an accounting program
Processing requests for obtaining data about a game with an accounting program.
Processing requests for the provision of data on players accounting software.
Stage 4. Implementation of the game scene
In the implementation, I will give an example of only what concerns enchantjs and the scene with the game.
First we need to create a scene and form a map for the game.
The map is built from an array of arrays, where each nested array characterizes the cell number from the original sprite of the map material.
Parts of the map that will be used in building the scene of the game
Map Sprite Source
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();
Got the basic syntax for creating a game scene and launching the game.
The bottom line is that we draw a rectangle on HTML pages on which we will manipulate sprites.
I must make a reservation right away that when implementing the game, I had to abandon the event model enchant and the concept that all actions occur as part of a scene change under the influence of the fps value.
Define the main scene of the game, draw a map, place the flags and set the machine to the start.
/**
* Главная сцена с картой
* @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]);
}
});
Map image
As a result, we get a scene with a map on which there is a road. In the screenshot, the flags are not indicated and the car is not installed at the start (lower left corner).
Each sprite object in enchantjs at least constantly contains information about the position in the coordinate system, about the angle of rotation of the sprite.
Map sketch
Those. in order to carry out the movement of the car on a drawn map, it took:
- Describe its actions in space when reaching a bend of the track
- Describe the actions of the car and the direction of movement depending on the angle of rotation of the sprite.
That is, if we have a rotation angle of 0 and since our car’s sprite starts starting from the bottom up, then we move to the zeros of the coordinate axis along the Y axis. Next we encounter the bend of track No. 1 and must rotate the car’s sprite 90 degrees. Further, knowing that we are located at an angle of 90 degrees, we move along the X axis until the bend of track No. 2, etc.
So we taught the car to move along the drawn coordinate system.
In order to bring the interaction of the car with the road to the values we are familiar with - in the distance in km traveled, it was necessary to write an additional function that takes the number of km. from 0 to 3000 and returns the coordinates of the point on the road section.
For car movement, we used setInterval which increases x or y values while the car is moving
//Авто движение
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);
Map, typewriter, flags
During movement, events occur on the game scene:
- Hitting Flags
- Fuel end
- Reaching the finish line
Upon reaching these events, events are created that are processed in the control script of the 1C-Bitrix component.
More ... more
The following steps to complete the game system were:
- Creating an interface with control buttons
- Reaction to events on the field with the game
- Changes to game parameters depending on user actions
- Checking vehicle parameters on the back end
The result is such a game in LC
Screen LK
And a little video