Growing Crystals vol 4. картинка на клиенте и запросы к серверу

Сегодня мы продолжим наши эпические разработки игры Growing Crystals.

Вчера весь день я слушал лекции по JavaScript из курса Hexlet что не плохо помогло разобраться с азами программирования в JavaScript, всё это я закрепил просмотрев objectplayground.com. Также дополнительно удалось прочесть несколько статей про AJAX, JSON и JQuery.

Самое главное — удалось получить ценные советы и разъяснения от товарища. Общение и взгляд со стороны очень важны в таких проектах, особенно когда их ведёт человек с 0м опытом. Товарищ дал много полезной информации и объективную критику уже проведенной работы.

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

Какие ключевые фразы были услышаны от товарища:

  • В данном проекте необходима реализация протокола обмена при котором сервер может обратиться к клиенту
  • Нужно прочесть опыт других в habrahabr
  • Для обмена использовать JSON
  • Использовать IDE, например WebStorm
  • Использовать библиотеку jQuery считается не очень хорошим тоном

Ответы на вопросы которые были заданы:
— Почему если задача проверить игровую механику, ты взялся за графику а не просто сделал модель?
— Т.к. гораздо труднее привлечь пользователей к проекту, у которого нет графики. А количество добровольцев на тестирование для этого проекта играет ключевую роль.

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

— Дать краткое пояснение о том, что за игра Crystal Rain?
— Игра Crystal Rain представляет собой free-to-play ММО аркаду дополненной реальности. Подробнее.

— Дать больше информации и планах и первом релизе.
— Первый релиз Growing Crystal должен произойти через неделю после начала работ, т.е. в пятницу 02 мая 2014. В пером релизе должно быть реализовано перемещение игрока по игровому миру, а также выполнение определенного простого задания, например, сбор 1000 кристаллов на скорость. Исходя из успешности первого релиза и будет принято решение о дальнейшем развитии проекта.

Всё таки HTML5+Canvas

Ознакомившись с достаточным объёмом документации было принято решение использовать Canvas, а не громоздить кучу div-ов с gif-ами, как было популярно в 2007 году. Хорошие статьи по Canvas. Оказалось не так сложно инициализировать канву и расположить на ней игровое поле, построенное из клеток.
Далее пример кода JavaScript.

// ============================================================= 
// ===== CANVAS =====
// ===== simple Growing Crystals screen output ====
// script written by Petukhovsky - 2014.04.29
// http://petukhovsky.com
// =============================================================

"use strict"; //All my JavaScript written in Strict Mode http://ecma262-5.com/ELS5_HTML.htm#Annex_C

(function () {
// ======== private vars ========
var map;
var img;
var container, ctx;

var offsx = 200; //Смещение X к макушке ромба игрого поля
var offsy = 20; //Смещение y к макушке ромба игрого поля

var cellsizex = 62;
var cellsizexhalf = 31; //Деление в ручную сделано чтобы избежать дробных результатов и antialising
var cellsizey = 31;
var cellsizeyhalf = 15; //Деление в ручную сделано чтобы избежать дробных результатов и antialising

var mapsizex = 5; //Размер X отображаемого игрового поля
var mapsizey = 5; //Размер Y отображаемого игрового поля

// --- functions ---
var init;

////////////////////////////////////////////////////////////////////////////
var init = function () {
// ---- init script ----
container = document.getElementById("canvas-gc-0");
container.width = 400;
container.height = 200;
ctx = container.getContext("2d");

img = new Image(); // Создание нового объекта изображения
img.src = 'cell.png'; // Путь к изображению клетки
img.onload = function() { // Событие onLoad, ждём момента пока загрузится изображение


for (var x = 0; x < mapsizex; x ++)
for (var y = 0; y < mapsizey; y ++) {
ctx.drawImage(img, offsx - cellsizexhalf - cellsizexhalf*y + cellsizexhalf*x -x+y,
offsy + y*cellsizeyhalf + cellsizeyhalf*x); // Рисуем сетку из клеток
}

}

};

return {
////////////////////////////////////////////////////////////////////////////
// ---- onload event ----
load : function () {
window.addEventListener('load', function () {
init();
}, false);
}
}
})().load();

Описанный выше код JavaScript обращается к canvas по id. Далее, для избавления от нагромождения кода в статье, код JavaScript будет представлен ссылками.

<canvas id="canvas-gc-0" class="canvasdemo"> 
HTML5 CANVAS
</canvas>

В результате выполнения кода JavaScript получаем


HTML5 CANVAS

Ось X расположена вдоль прямой WS, и ось Y вдоль NE соответственно.
Когда нам удалось построить сетку (игровое поле), перейдём к отображению на ней массива объектов. Для удобства загрузки и использования, все изображения объектов были сохранены в один файл формата png.

objects.png - объекты игрового мира

objects.png — объекты игрового мира

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

        map = [
            [0, 1, 2, 3, 4],
            [0, 0, 0, 0, 0],
            [4, 0, 1, 3, 0],
            [5, 3, 3, 3, 0],
            [5, 0, 0, 5, 0]
        ];

Числа обозначают номер объекта в файле формата png, 0 — клетка, 1 — персонаж и так далее.

В результате выполнения кода JavaScript получаем:



HTML5 CANVAS

Теперь, когда мы умеем выводить матрицу игрового поля на клиенте, нам нужно научиться запрашивать данные о состоянии игрового мира у сервера без перезагрузки страницы. Для этого будет применена технология AJAX с передачей данных в формате JSON.

Долго выбирать технологию для сервера и СУБД не пришлось, хотя и стоял вопрос выбора между PHP и Node.js и между MySQL и PostgreSQL, но т.к. у меня уже имеется хостинг для WordPress на PHP и MySQL, то в качестве серверного и СУБД ПО было принято решение использовать именно их. В случае необходимости расширения проекта, аренда сервера и перенос небольшого проекта, даже смена СУБД решается за несколько дней.

Я написал простой php-скрипт ask.php, генерирующий карту игрового мира размером 5×5. Также он сохраняет в файле количество обращений к серверу и передаёт информацию на клиент в формате JSON.

<?php
$count = 0;
$msg = "";
$map = null;

//Если файл количества обращений уже есть
if(file_exists("askcounter.txt")){
$file = fopen("askcounter.txt","r");
if(!file)
$msg = "Ошибка открытия файла";
else
{
$str = fgets($file); //Считывание строки с числом
$int = (int) $str; //Преобразование в число
$count = $int+1;
}
}

$file = fopen("askcounter.txt","w");
fputs($file, $count."\r\n"); //Сохраняем значение счётчика
fclose($file);


function generate_random_map(&$_map, $_map_size_x=5, $_map_size_y=5, $_max_val=5){ //& перед массивом обязательно
for ($i=0; $i<$_map_size_x; $i++){
for ($j=0; $j<$_map_size_y; $j++){
$_map[$i][$j] = rand(0,$_max_val); //Заполняем карту случайными числами от 0 до 5
}

//var_dump($_map);
}
}

function output_map(&$_map){
for ($i=0; $i<count($_map); $i++){
echo "[";
for ($j=0; $j<count($_map[$i])-1; $j++){
echo $_map[$i][$j].", ";
}
echo $_map[$i][count($_map[$i])-1]."]";
if($i != count($_map)-1) echo ",";
}
}


if($msg == "") $msg = "Количество обращений к серверу: ".$count; //Если ошибок не найдено, формируем сообщение
?>
{
cggame:
{
map:
[
<?php
generate_random_map($map);
output_map($map);
?>
],
msg:"<?=$msg?>"
}
}

В результате код JavaScript на клиенте и php код на сервере реализуют технологию клиент-сервер, в которой клиент запрашивает у сервера карту игрового мира и затем выводит её, также на клиенте выводится и количество обращений к серверу за всё время. Нажмите клавишу GET FROM SERVER, и вы увидите что каждый раз перед вами предстанет случайная игровая ситуация. Чёрный фон используется для разнообразия.



HTML5 CANVAS

Количество обращений к серверу пока не известно.

Инструменты которые нужно запомнить

jsfiddle.net — сервис он-лайн просмотра и эмуляции JavaScript.

Play Canvas — платформа разработки и публикации игр при помощи Canvas, также выполняет роль комьюнити для разработчиков.

Советы друга

Что из советов друга было применено (зачёркнуто):

  • В данном проекте необходима реализация протокола обмена при котором сервер может обратиться к клиенту
  • Нужно прочесть опыт других в habrahabr
  • Для обмена использовать JSON
  • Использовать IDE, например WebStorm
  • Использовать библиотеку jQuery считается не очень хорошим тоном

Идеи в goods box

  • После первого релиза завести аккаунт на habrahabr.

Идеи в trash box

  • На всех объектах принадлежащих игроку горит дополнительная голубая лампочка;
  • Если у игрока нету топлива, что его авиасёрф перестаёт работать и садится на землю, а в обычном режиме он слегка покачивается в воздухе и работают 4 реактивных двигателя по краям авиасёрфа;
  • Если на складе что-то есть, то у него мигает индикатор;
  • Апгрейды защитных башень;
  • Взрывающиеся при разрушении склады;
  • Артефакт увеличивающий скорость перемещения игрока;
  • Артефакт увеличивающий радиус действия игрока;
  • Предмет, который можно бросить на несколько экранов, чтобы посмотреть что там происходит;
  • Мины;
  • Кузница опыта, производящая специальное вещество, получаемое из сжигания кристаллов и необходимое для получения звания;
  • Звание — это предмет в инвентаре.
  • Объект карты — ограждение;
  • Объекты, расползающиеся по карте;
  • Декоративные мегаобъекты;
  • Наличие сверхдорогих объектов с особыми свойствами;
  • Список друзей, чтобы на них не действовала защитная башня;
  • Общие склады для друзей;
  • Шаринг в социальных сетях.

Краткий итог: В качестве технологии реализации клиента выбран HTML+CSS+JavaScript, canvas оказался простым понятным и удобным. Реализовано отображение матрицы игрового мира в окне браузера. Отработан простой запрос к серверу, получая ответ на который мы выводим полученную карту игрового мира.

Сводка

Начало: 25 апреля 2014 года.
Команда: 1 человек.
Израсходовано: 18+6+10 = 34 чч.
Средняя производительность: 34/5 = 6,8 чч/день

Описание игрового процесса

30/100

Расчет баланса

5/100

Игровая графика

10/100

Веб-клиент

8/100

Игровой сервер

8/100

ИТОГО

61/500

Продолжение: Growing Crystals vol 5. сервер и место случайности в игровом процессе