Пишем игру для Samsung SmartTV на JS

в 15:01, , рубрики: javascript, Samsung, SmartTV, Веб-разработка, метки: , ,

Всем привет. Я по долгу службы занимаюсь разработкой для Samsung SmartTV. В силу того, что на хабре мало статей на эту тему, я решил это исправить. Кому интересна пошаговая инструкция как сделать свой пинг-понг на «умный телик» с распознованием жестов — милости прошу под кат.

Подготовка ящика с инструментами

  • Для начала нам понадобится компьютер с Windows (cам тестировал на виртуальной машине на Маке).
  • Теперь идем на samsungdforum.com и скачиваем SDK
    я качал версии 2.5.1 с целью покрыть как можно больше моделей.
  • К сожалению, для коммерческой разработки сам телевизор просто необходим, потому что по факту эмулятор и реальное устройство порой сильно отличаются по поведению (ну и распознование жестов на эмуляторе не оттестировать). Я использовал модель 2012 года.
  • В качестве JS движка для разработки игр я выбрал для себя 2 альтернативы это Ivank Lib и  CraftyJS. Результаты тестов на fps показали что crafty в два раза быстрее, поэтому я остановился на ней. Связанно это с тем, что Ivank использует canvas, который аппаратно не ускоряется на SmartTV. Чуть-чуть инсайда: коллеги сказали что скоро предстоит много работы в связи с переписыванием всего на HTML5 т.к. скорее всего в моделе 2013 года весь HTML5 будет сделан «с преферансом и поэтессами».

Дебаг

В целом, процесс дебага достаточно точно описан на samsungdforum.com.
(Guide->Topic->Getting started->Testing Your Application on a TV) В двух словах: для запуска на эмуляторе достаточно нажать одну кнопку в ИДЕ, для запуска на ТВ нужно сделать пакет, залить его на веб сервер (все делается в ИДЕ) и синхронизировать приложения со SmartTV (несколько нажатий кнопок на пульте).

Разработка

  • Итак мы скачали SDK и dev версию CraftyJS. Ну что ж, поехали.
  • Запускаем ИДЕ в поставке SDK, так называемый, Samsung SDK TV Editor. Создаем дефолтный JavaScript проект.
  • При создании проекта редактируем свойство «widgetname» и добавляем свойство по имени «mouse» со значением «y» (это свойство позволит нам использовать фишку SmartTV — управление жестами). Все остальные свойства можно оставить «по умолчанию».
  • IDE создаст для нас дефолтный проект. Он, в целом, не нужен и его можно полностью очистить и оставить только 2 файла widget.info и config.xml.

Файл index.html

Добавляем в проект index.html следующего содержания:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>PongTv</title>

</head>
<body style="margin:0px;padding:0px;">


<script type="text/javascript" src="crafty.js"></script>
<script type="text/javascript" src="pong.js"></script>


</body>
</html>

Комментировать особо нечего, тут все понятно.
Соответственно нам нужно добавить еще 2 файла: сама библиотека CraftyJS и код игры.

Код игры pong.js

if (window.curWidget) {
    curWidget.setPreference('ready', 'true');
}

var wdth = 960;
var hght = 540;

var margin = 20;

var back_color = 'rgb(0,0,0)';
var act_color = 'rgb(255,255,255)';

var ppdl_w = 20;
var ppdl_h = 100;

var ball_s = 10;

Crafty.init(wdth, hght);
Crafty.background(back_color);

//Paddles
Crafty.e("Paddle, 2D, DOM, Color, Multiway, Mouse")
    .color(act_color)
    .attr({ x:margin, y:(hght-ppdl_h)/2, w:ppdl_w, h:ppdl_h })
    .multiway(4, { W:-90, S:90, REMOTE_UP:-90, REMOTE_DOWN:90 });
	
Crafty.e("Paddle, 2D, DOM, Color, Multiway, Mouse")
    .color(act_color)
    .attr({ x:wdth-margin-ppdl_w, y:(hght-ppdl_h)/2, w:ppdl_w, h:ppdl_h })
    .multiway(4, { UP_ARROW:-90, DOWN_ARROW:90})
    .bind('MouseMove', function (e) {
        this.y = e.y-ppdl_h/2;
    });

//Ball
Crafty.e("2D, DOM, Color, Collision")
    .color(act_color)
    .attr({ x:wdth/2, y:hght/2, w:ball_s, h:ball_s,
        dX:Crafty.math.randomInt(2, 5),
        dY:Crafty.math.randomInt(2, 5) })
    .bind('EnterFrame', function () {
        //hit floor or roof
        if (this.y <= 0 || this.y >= hght)
            this.dY *= -1;

        if (this.x > wdth-margin) {
            this.x = wdth/2;
            Crafty("LeftPoints").each(function () {
                this.text(++this.points + " Points")
            });
        }
        if (this.x < margin) {
            this.x = wdth/2;
            Crafty("RightPoints").each(function () {
                this.text(++this.points + " Points")
            });
        }

        this.x += this.dX;
        this.y += this.dY;
    })
    .onHit('Paddle', function () {
        this.dX *= -1;
    });

//Score boards
Crafty.e("LeftPoints, DOM, 2D, Text")
    .attr({ x:margin, y:margin, w:100, h:20, points:0 })
	.textColor('#FFFFFF')
    .text("0 Points");
Crafty.e("RightPoints, DOM, 2D, Text")
    .attr({ x:wdth -100, y:margin, w:100, h:20, points:0 })
	.textColor('#FFFFFF')
    .text("0 Points");

Первые несколько строк кода сообщают телевизору, что приложение готово и его можно показать на экран.
Далее вполне себе стандартный код на Crafty. Сразу можно задать вопрос: «Ну а где же жесты?». Отвечаю: жесты в Samsung SmartTV ни что иное как обычная мышка. Соответственно, если в браузере ваш код реагирует на мышь, то телевезор будет ловить жесты (вы, как бы, будете управлять курсором с помощью руки, а кликать жестом)

Запуск

Запускаем все на эмуляторе и ничего не работает. Почему? Все просто: CraftyJS знать не знает ни о каких пультах.
Находим в коде CraftyJS массив кодов клавиатуры(«keys: {») и добавляем следующее:

...
'REMOTE_UP': 29460, 
'REMOTE_DOWN':29461, 

Я отправил pull-реквест авторам craftyJS и его приняли, поэтому есть вероятность что в вашей версии CraftyJS это уже будет присутствовать.

Поменяли, запускаем на эмуляторе и снова ничего не работает. Тут опять все просто: эмулятор в моей версии мышку не поддерживает, а для клавиш ждет специального JS блока, который для работы на реальном телевизоре не нужен, поэтому я его опустил. В целом, его можно подглядеть в дефолтном проекте, который создает ИДЕ.
Для тестов игру можно запустить в Chrome, если там все работает, значит и на телевизоре заведется.
Устанавливаем приложение на телевизор, берем пиво и товарища, и режемся в казуальный пинг-понг на огромном экране с использованием жестов. Красота.

Заключение

Как вы уже догадались я работаю в компании Samsung и сейчас нахожусь в Южной Корее. Если кому интересно как я сюда попал, пишите комменты — подготовлю еще один пост.
Это мой первый пост, поэтому любая конструктивная критика приветствуется,

Автор: viru0

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


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