СоХабр закрыт.

С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.

H Публикация iFrame / HTML5 игры во ВКонтакте. Основы в черновиках

Сразу давайте обозначимся: тема API ВК тут рассматриваться не будет, ее я затрону в будущих материалах, так как она довольно обширна и представляет хорошие возможности. В этой статье будет самая основная часть: написание игры и публикация ее в социальной сети, как запускаемое приложение.

Что потребуется для работы:
— Текстовый редактор (на ваш вкус)
— Любой браузер, поддерживающий HTML5
— Немного свободного времени

Часть 1. Игра на HTML
Думал, что можно использовать в качестве примера, пусть это будет та же игра, что и в видеоуроке про «Две шкатулки».
Суть ее проста: перед пользователем есть две шкатулки, кликом по любой из них либо прибавляется, либо отнимается значение «score».

Вся игра изнутри выглядит так:
image

И ее файлы с комментариями:

Файл index.html
<!DOCTYPE html>
<html> 
 <head>
  <script type="text/javascript" src="j2ds/math.js"></script>
  <script type="text/javascript" src="j2ds/input.js"></script>   
  <script type="text/javascript" src="j2ds/dom.js"></script>
  <script type="text/javascript" src="j2ds/j2ds.js"></script>
  <script type="text/javascript" src="j2ds/post.js"></script>  
  <script type="text/javascript" src="menu.js"></script>  
  <script type="text/javascript" src="game.js"></script>    
   
  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
  <meta name="viewport" content="width=device-width,user-scalable=no" />  
  <title>Две шкатулки</title>
 </head>

<body onload="startGame(Menu, 30);">
<canvas id="iCanvas" width="550" height="300"></canvas>

<script type="text/javascript">
// Инициализируем сцену
scene= createScene('iCanvas', '#EED6C6');

// Разворачиваем приложение на весь экран
scene.fullScreen(true);

// Инициализируем устройство ввода
initInput(scene);

// Создаем менеджер постэффектов
post= createPost(scene);

// Создаем меню
createMenu();

// Создаем игру
createGame();
</script>

</body>
</html>



onload=«startGame(Menu, 30)» означает, что игра будет запущена с игрового состояния Menu с частотой кадров в 30.

Файл menu.js
function createMenu() {
 // объявляем глобальные переменные
 selection= 0;
 // Создаем объект, указывающий на выделенный пункт
 menuSelector= createRect(vec2df(50, 50), vec2df(30, 30), '#CD8181');
 // СОздаем два прямоугольника, отвечающие за выбор того или иного пункта
 menuItem1= createRect(vec2df(190, 100), vec2df(300, 50), '#AAA189');
 menuItem2= createRect(vec2df(190, 220), vec2df(300, 50), '#AAA189');
}

// Описываем игровое состояние Menu
function Menu() {
 // Обновляем позицию курсора
 input.upd();
 // Если пользователь кликнул
 if (input.lClick) {
  // Если клик по первому пункту меню
  if (input.onNode(menuItem1))
  {
   // Если он уже был выбран, сменяем игровое состояние, иначе выделяем его
   if (selection == 0)
   { setActivEngine(Game); }
   else { selection= 0; }
  }
  // Аналогично для второго пункта меню
  else if (input.onNode(menuItem2))
  {
   if (selection == 1)
   { setActivEngine(Records); }
   else { selection= 1; }   
  }
  // Отменяем ввод, чтобы срабатывало только на однократные нажатия
  input.cancel();
 }

 // Если выбран первый пункт, то двигаем выделение к нему
 if (selection == 0) 
  menuSelector.moveTo(menuItem1, vec2df(-40, 0));
 // Если второй, то ко второму
 if (selection == 1) 
  menuSelector.moveTo(menuItem2, vec2df(-40, 0));

 // Отрисовываем пункты меню
 menuItem1.draw(scene);
 menuItem2.draw(scene);
 
 // вращаем указатель 
 menuSelector.turn(5);
 // отрисовываем
 menuSelector.draw(scene);

 // теперь выводим текст 
 scene.drawTextOpt( 
                   vec2df(200, 115), // Позиция
                  'Сыграть!', // Текст
                  'bold 20px sans-serif', // Шрифт (аналогично CSS)
                  'white', // Цвет текста
                  'black', // Цвед обводки
                  2 // Толщина обводки
                  ); 

 scene.drawTextOpt( 
                   vec2df(200, 235), // Позиция
                  'Рекорды!', // Текст
                  'bold 20px sans-serif', // Шрифт (аналогично CSS)
                  'white', // Цвет текста
                  'black', // Цвед обводки
                  2 // Толщина обводки
                  ); 
                  
 scene.drawTextOpt( 
                   vec2df(150, 20), // Позиция
                  'Две шкатулки!', // Текст
                  'bold 30px sans-serif', // Шрифт (аналогично CSS)
                  '#478EA4', // Цвет текста
                  'white', // Цвед обводки
                  2 // Толщина обводки
                  ); 
                  
 // добавляем плавности при движении и вращениях
 post.motionBlur(5);
}



// Игровое состояние Records, если пользователь выберет пункт меню "Рекорды"
// Пока это меню нефункционально
function Records() {
 // Если пользователь кликнул в любое место, отправляем его
 // обратно в меню и отменяем ввод
 if (input.lClick)
 {
  setActivEngine(Menu);
  input.cancel();
 } 
 // выводим текст
 scene.drawTextOpt( 
                   vec2df(150, 20), // Позиция
                  'Рекорды', // Текст
                  'bold 30px sans-serif', // Шрифт (аналогично CSS)
                  '#478EA4', // Цвет текста
                  'white', // Цвед обводки
                  2 // Толщина обводки
                  ); 
}



Для справки
vec2df() — это конструктор объекта, хранящий в себе две переменные: x и y в вещественном типе, если нужно использовать только целые, для этого есть vec2di()


Файл game.js
// глобальная переменная для счета 
score= 0;

// создаем игровые объекты
function createGame() {
 // принимает значение 1, 2, 3
 pos= 0;
 
 // "подкладка" под наши шкатулки
 panel= createRect(vec2df(20, 60), vec2df(510, 220), '#4E7B46');
 
 // рисует звездочку
 cell= createLine(
              vec2df(100, 100), // Координаты в игре 
              [                 // масив координат для точек
               [40, 0],
               [0, 24],
               [20, -15],
               [30, 24],
               [0, -1]
              ], 1,             // Масштабирование (1 - оригинальный)
               'white', 2,      // Цвет, толщина
               true, 'yellow'); // Закрашивать цветом 

 // Первая шкатулка
 box1= createRect(vec2df(130, 110), vec2df(100, 100), '#FDF88D');
 
 // вторая шкатулка
 box2= createRect(vec2df(330, 110), vec2df(100, 100), '#FDF88D');
 
 
}

// теперь описываем игровую логику
function Game() { 
 // обновляем позицию курсора / тача
 input.upd();
 
 // Если еще не известно (pos == 0), в какой шкатулке БУДЕТ звездочка, рандомим шкатулку
 if (!pos) pos= Random(0 , 2);
 
 // Если пользователь выбрал любую шкатулку (pos == 3)
 if (pos == 3)
 {
  // ждем пока он не кликнет по полю еще раз
  if (input.lClick) 
  {
   // пересоздаем игру
   createGame();
   // отменяем ввод
   input.cancel();
  }
 } 
 
 // если рандомно выпала первая шкатулка, позиционируем звездочку
 if (pos == 1) {
  cell.setPosition(vec2df(190, 160));
 }
 
 // Аналогично для второй
 if (pos == 2) {
  cell.setPosition(vec2df(390, 160));
 }

 // Если пользователь кликнул по полю
 if (input.lClick) {
  // если это первая шкатулка
  if (input.onNode(box1))
  {
   // и если звезда находится в первой шкатулке
   if (pos == 1)
   { 
    // окрашиваем шкатулку в желтый цвет
    // увеличиваем счет и сдвигаем шкатулку вверх
    box1.color= '#FFEB00'; 
    score+= 1;
    box1.pos= vec2df(130, 50);
   }
   // если не угадал, то шкатулку окрашиваем в красный
   else { 
    box1.color= 'red'; 
    score-= 1;
   }
   // устанавливаем значение 3, независимо от того, какая была выбрана шкатулка
   pos= 3;
  }
  // Аналогично для второй шкатулки
  else if (input.onNode(box2))
  {
   if (pos == 2)
   { 
    box2.color= '#FFEB00'; 
    score+= 1;
    box2.pos= vec2df(330, 50);  
   }
   else {  
    box2.color= 'red'; 
    score-= 1;   
   }   
   pos= 3;
  }
  input.cancel();
 }


 // отрисовываем панель
 panel.draw(scene);
 
 // затем звездочку
 cell.draw(scene);
 
 // и затем шкатулки
 box1.draw(scene);
 box2.draw(scene); 
  
 scene.drawTextOpt( 
                   vec2df(150, 10), // Позиция
                  'Две шкатулки!', // Текст
                  'bold 30px sans-serif', // Шрифт (аналогично CSS)
                  '#478EA4', // Цвет текста
                  'white', // Цвед обводки
                  2 // Толщина обводки
                  ); 

 scene.drawTextOpt( 
                   vec2df(440, 280), // Позиция
                  'Score: '+score, // Текст
                  'bold 20px sans-serif', // Шрифт (аналогично CSS)
                  '#478EA4', // Цвет текста
                  'white', // Цвед обводки
                  2 // Толщина обводки
                  ); 


}



Код игры был написан мной давно на движке j2Ds.

Часть 2. Google Drive
После написания игры, ее отладки, тестирования, встает вопрос, о том, где же разместить игру. Основное правило ВКонтакте: игра должна быть размещена на внешнем ресурсе, и доступ к ней должен осуществляться с SSL (https://).
Бесплатных хостингов, дающих такую возможность, я не нашел. Но есть «Google Диск», который умеет воспроизводить пользовательские JS/HTML файлы. Здорово! Даже если ваша игра и задействует сервер, вы можете воспользоваться AJAX мостом к нему, настроив сервер и приложение должным образом, чтобы они могли нормально взаимодействовать. Из приложения вы можете коннектиться к любым серверам даже по простому http, внутрь iFrame ВК не лезет. Но клиент игры обязан быть доступен только через «https://»

Идем на ГД:
image

Вы можете создать тут любое количество папок и файлов, это не имеет никакого значения, главное — создайте папку, где будет храниться игра.
Если вы посмотрите на первый скриншот, со структурой файлов игры, то поймете, что нужно перенести все файлы в диск. Для этого есть специальная функция загрузки всей папки:
image
После откроется диалог выбора, я выбрал папку www (в которой лежит index.html) просто загрузил ее на сервер:
image

Как не сложно заметить, структура файлов такая же.
Следующее, что нужно сделать — это дать доступ папке, в которой лежит index.html.

В моем случае index.html находится в папке www, поэтому выходим на уровень назад и выделяем папку www и жмем на пиктограмму открытия доступа:
image

Включаем доступ по ссылке (вверху справа) и копируем ссылку для общего доступа:
image

Этим мы открыли доступ к нашей игре всем, кто загестрирован на google. В любом сервисе. Чтобы снять и это ограничение, переходим на вкладку «расширенные», и там активируем доступ для просмотра всем в интернете:
image

Теперь эту ссылку вставьте в любой текстовый редактор, будем ее модифицировать:
Ссылка выглядит так:
https://drive.google.com/folderview?id=0B09c3UoyWG0xfjBYaEtxWlNMdDFEbmUwVjhTb3pqV0l5SUI1NTVmLW1CTGE4Vm4zaHgyYmM&usp=sharing


Теперь жирным я выделю то, что нам нужно, остальное можно удалить:
https://drive.google.com/folderview?id=0B09c3UoyWG0xfjBYaEtxWlNMdDFEbmUwVjhTb3pqV0l5SUI1NTVmLW1CTGE4Vm4zaHgyYmM&usp=sharing

Удалив все НЕжирное, получим ссылку вида:
https://0B09c3UoyWG0xfjBYaEtxWlNMdDFEbmUwVjhTb3pqV0l5SUI1NTVmLW1CTGE4Vm4zaHgyYmM


Дописываем после https:// путь к googledrive.com/host и получаем ссылку вида:
https://googledrive.com/host/0B09c3UoyWG0xfjBYaEtxWlNMdDFEbmUwVjhTb3pqV0l5SUI1NTVmLW1CTGE4Vm4zaHgyYmM


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

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

Часть 3. ВКонтакте

После того, как вы научились открывать вашу игру через Googledrive в браузере, переходим на сайт ВКонтакте в раздел приложения:
image

На этой странице скроллим в самый низ и выбираем «Разработчикам», откроется страница для девелоперов:
image

Тут жмем «Создать приложение» и заполняем вашими данными форму:
image

После заполнения ВК отправит вам смс для подтверждения, введя код подтверждения (бесплатный) вас перебросит в панель управления вашими приложениями. Там будет много разной информации, вы можете походить по вкладкам, по-нажимать, по-проверять:
image

Теперь важный момент: приложение пока доступно для запуска только вам, как создателю, другие его не видят. Чтобы оно стало видимым для всех нужно в графе «Состояние» выбрать соответствующий пункт.

Обратим внимание на строки для ввода iFrame адреса. Тут два поля. Первое поле — адрес http, второе — https. Лучше оба заполнить в формате https, так надежнее. Ту ссылку, что мы получили путем нехитрых модификаций вставляем в адрес и сохраняем данные. После сохранения данных, можно пробовать запустить игру:
image

Теперь, открывая пункт «Управление приложением» вы можете манипулировать вашей игрой, смотреть статистику и т.д.
Управлять же файлами самой игры можно просто: редактируете, их, к примеру, на локальной машине, и, как только все изменения отлажены, заменяете файлы на гугл диске в нужной папке. Повторно выставлять права и доступ не нужно, так как выставлены они для всей папки, ссылки менять тоже не нужно.

Пример получившегося приложения могу дать в ЛС.

На этом у меня всё. Работа с VK API уже есть и доступна в виде видеоуроков, которые тут публиковать не буду. Ранее за публикацию видео аккаунт был заблокирован.

комментарии (12)

0
spanasik ,  
Спасибо за статью! Вопрос: размещение контента с такой целью не противоречит условиям использования drive.google.com?
0
Skaner ,  
Гугл положительно относится к такой возможности, более того, даже у них самих есть инструкция по запуску html файлов в общем доступе. Вырезка из технической поддержки.
Единственное, что если ваша игра/приложение будет иметь большую популярность, и, как следствие — требовать больших мощностей из-за частости запросов, лучше обзавестись собственым сервером с SSL.
0
VDG ,  
Лимит не знаете? И какие последствия при превышении?
0
Skaner ,  
Честно — понятия не имею. не рассматривал это как серьезную площадку. Для крупного проекта все же лучше использовать специализированный для этой цели серв. Вчера вот на демо пример про шкатулки наплыло 4000 человек за первые 2 часа. Ничего не упало — доступ был, со стороны гугла полный штиль.
За все сутки больше 10000 запусков скрипта. Точно так же — полная тишина.
0
Skaner ,  
Из ограничение — отсутствие возможности запуска PHP сценариев. Но это легко решается размещением сервера на каком-нибудь другом хостинге, его правильной настройкой и прокладкой моста на AJAX, к примеру, для взаимодействия сервера и игры. Может этот вариант рассмотрю тоже…
0
stardust_kid ,  
И что только не делают лишь бы бесплатный ssl не получать.
0
Lexx918 ,  
Расскажите, как отлаживать игры в которых требуется авторизация внутри самого ВК?
0
radist2s ,  
Напомните, что там сейчас с правилами попадания в каталог? Деньги просят как раньше?
0
Skaner ,  
10 голосов просят. Но игру можно и без этого разреклаить по пабликам и чтобы у игры была своя группа)
0
ice2heart ,  
Вспомнилась картинка с кружкой «CSS is awesome»
0
lukaville ,  
GitHub Pages: https + удобный доступ через git репозиторий.
Жестких лимитов на трафик судя по всему нет. Ограничение на репозиторий: 1GB максимум общий объем и 100MB максимум на файл.
0
Skaner ,  
О! Спасибо большое, посмотрю обязательно!