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

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

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

Что ж, недавно вышел видеоурок о том, как разработать приложение на JavaScript и разместить его в социальной сети ВКонтакте. Воспринят он был неоднозначно, на одних ресурсах (Включая youtube) к нему отнеслись положительно, на других — отрицательно в силу того, что подобную инфу лучше преподносить в текстовом варианте.
Статья на эту тему готова, кому интересно, прошу под кат.

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

Наверное, кто-то заметит сходство с другой статьей, и не зря, в общем подход аналогичен. Единственное отличие в том, что разрабатывать на HTML5 для браузеров более оправдано, чем для смартфонов.

Что потребуется для работы:
— Текстовый редактор (на ваш вкус)
— Любой браузер, поддерживающий 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 // Толщина обводки
                  ); 


}



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

Часть 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

Если вы хотите, чтобы работало вообще у всех, а не только у тех, у кого есть аккаунт гугл, нужно открыть вкладку «рассширенные» и изменить уровень доступа к папке:
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 и получаем ссылку вида:
googledrive.com/host/0B09c3UoyWG0xfjBYaEtxWlNMdDFEbmUwVjhTb3pqV0l5SUI1NTVmLW1CTGE4Vm4zaHgyYmM

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

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

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

После того, как вы научились открывать вашу игру через Googledrive в браузере, переходим на сайт ВКонтакте в раздел приложения:
image
На этой странице скроллим в самый низ и выбираем «Разработчикам», откроется страница для девелоперов:
image
Тут жмем «Создать приложение» и заполняем вашими данными форму:
image

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

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

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

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

Пример получившегося приложения: Две шкатулки

На этом у меня все, в будущем думаю рассмотреть работу с 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 ,  
О! Спасибо большое, посмотрю обязательно!