Мне, вероятно, не нужно много говорить о Firefox OS, так как многие из вас уже много знают об этом. Если нет, у нас есть несколько отличных статей на тему SitePoint, это хорошая отправная точка.
Все, что вам нужно знать для этого урока, это то, что приложения Firefox OS — это просто веб- приложения, которые программируются на HTML5, CSS и JavaScript.
Я собираюсь создать простую игру под названием YALG , Another Another Logo Game .
Что нам нужно?
Во-первых, браузер Mozilla Firefox . У большинства из нас нет устройства с ОС Firefox, эмулятор ОС Firefox представляет собой плагин Firefox, вы можете узнать, как его установить здесь .
Я решил использовать фреймворк под названием Ionic для этого проекта.
Почему ионный?
- Это просто и имеет отличную документацию
- Это позволяет для кроссплатформенной разработки, используя ее основанный на Cordova CLI
- Он основан на AngularJS, одной из лучших платформ Javascript
- Ориентирован на мобильные устройства
Начиная проект
Сначала установите Ionic, вы можете сделать это, следуя нашему руководству по Ionic . Затем с помощью инструмента Ionic CLI выполните:
ionic start YALG blank
cd YALG
ionic platform add firefoxos
# You can add more platforms as required
Это создаст новый пустой Ionic Project с поддержкой Firefox OS (вы можете захотеть изменить некоторые вещи в файле config.xml
Теперь выполните:
cordova prepare firefoxos
Это делает ваше приложение готовым к развертыванию в Firefox OS.
Чтобы запустить новое приложение в эмуляторе, добавьте products/firefox/www
Вы должны увидеть что-то подобное в эмуляторе:
Теперь мы внесем некоторые изменения в исходный код в папке www
Во-первых, откройте файл index.html
Измените его содержание на это:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>YALG</title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="yalg">
<ion-nav-view>
<!-- View Goes Here -->
</ion-nav-view>
</body>
</html>
Если вы не знакомы с AngularJS, вы можете заметить пару странных вещей. Одним из них является ng-app="yalg"
Это способ сообщить HTML-странице, что она должна работать как угловой проект, управляемый угловым модулем под названием yalg
Еще один — ion -nav-view
Это директива HTML, созданная Ionic Framework и используемая для загрузки различных представлений, так как AngularJS является платформой MVC. Эти представления определены в файле app.js
var app = angular.module('yalg',['ionic']);
app.config(function($stateProvider, $urlRouterProvider, $compileProvider) {
$stateProvider.
state('main', {
url : '/',
templateUrl : 'templates/main.html',
controller : 'MainCtrl'
}).
state('levels', {
url : '/levels',
templateUrl : 'templates/levels.html',
controller : 'LevelsCtrl'
}).
state('level', {
url : '/level/:levelId',
templateUrl : 'templates/level.html',
controller : 'LevelCtrl'
}).
state('logo', {
url : '/level/:levelId/logo/:logoId',
templateUrl : 'templates/logo.html',
controller : 'LogoCtrl'
}).
state('about', {
url : '/about',
templateUrl : 'templates/about.html',
controller : 'MainCtrl'
});
$urlRouterProvider.otherwise('/');
/**
* Firefox OS only
* @see http://goo.gl/cKJyRm
*/
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|app):/);
});
Используя angular.module
yalg
Далее мы определяем различные представления и то, как каждое из них будет достигнуто приложением. Мы делаем это путем создания различных состояний приложения.
Для каждого отдельного представления мы добавляем состояние, определенное с помощью имени состояния, и объект, содержащий URL-адрес состояния, шаблон ( т.е. представление) и контроллер, который мы создадим позже.
Если мы перейдем к #/
templates/main.html
ion -nav-view>
Если мы перейдем к #/about
templates/about.html
Если мы перейдем к неизвестному URL-адресу, будет загружено содержимое templates/main.html
$urlRouterProvider.otherwise('/');
,
Последняя строка кода — это способ исправить проблему с Firefox OS с маршрутами AngularJS. Если вы планируете протестировать это приложение на любой другой платформе, удалите последнюю строку кода.
Если вы перезагрузите это приложение в симуляторе, вы увидите только пустую страницу. Это потому что между
Папка www
|---- css
| |---- style.css
|
|---- img
|---- js
| |---- app.js
|
|---- lib
|---- templates
|---- about.html
|---- level.hmtl
|---- levels.html
|---- logo.html
|---- main.html
Добавьте это в файл lib
templates/main.html
Если вы не распознаете какие-либо теги HTML, найдите их в документации Ionic Framework . Ionic добавляет много полезных тегов / угловых директив.
Теперь давайте добавим немного стиля к этому представлению, отредактировав файл <ion-pane>
<ion-header-bar class="bar-positive">
<h1 class="title">{{appname}}</h1>
</ion-header-bar>
<ion-content class="content">
<div class="main-view">
<ul>
<li>
<a target="_blank" href="#/levels">
<button class="button button-positive main-button">Start Game</button>
</a>
<br>
</li>
<li>
<a target="_blank" href="#/about">
<button class="button button-positive main-button">About</button>
</a>
</li>
</ul>
</div>
</ion-content>
</ion-pane>
css/style.css
Возможно, вы заметили, что заголовок представления .content {
text-align: center;
padding-top: 8%;
}
.button.main-button {
border-radius: 10px;
width: 300px;
}
ul li {
padding: 8px;
} Мы не хотим этого, мы хотим, чтобы название было {{appname}}
Поскольку это Angular-проект, он использует Angular-шаблоны, а все, что находится между YALG
{{
Мы добавили контроллер с именем }}
Теперь мы создаем этот контроллер. Добавьте это в файл MainCtrl
js/app.js
Поскольку app.controller('MainCtrl', ['$scope',
function($scope) {
$scope.appname = "YALG";
$scope.descr = "Yet Another Logo Game";
}]);main.html
{{appname}}
Бегать:
$scope.appname
Запустите обновленное приложение в эмуляторе. Вот так все должно выглядеть:
Нажатие на кнопки ничего не изменит, так как мы не добавили их представления. Добавьте это в cordova prepare firefoxos
templates/about.html
Здесь мы добавили кнопку возврата с Ionicon . Вот что вы должны увидеть в симуляторе после перезагрузки приложения:
После нажатия кнопки « <ion-pane>
<ion-header-bar class="bar-positive">
<a target="_blank" href="#/">
<button class="button icon-left ion-chevron-left button-clear button-white">
</button></a>
<h1 class="title">About</h1>
</ion-header-bar>
<ion-content class="content">
<div class="about-view">
{{appname}} <br>
{{descr}}
</div>
</ion-content>
</ion-pane> Поэтому мы сначала создаем список всех уровней, создавая файл Start Game
data/levels.json
Я только создал два уровня с двумя логотипами на уровень, но вы можете добавить больше, следуя той же логике. Причина, по которой мы создаем этот [
{
"id" : 1,
"name" : "Level 1",
"content" : {
"logo_num" : 2,
"logos" : [
{
"id" : "sitepoint",
"name" : "Sitepoint",
"img" : "img/lvl1/sitepoint.jpg"
},
{
"id" : "fb",
"name" : "Facebook",
"img" : "img/lvl1/fb.png"
}
]
}
},
{
"id" : 2,
"name" : "Level 2",
"content" : {
"logo_num" : 2,
"logos" : [
{
"id" : "twitter",
"name" : "Twitter",
"img" :"img/lvl2/twitter.jpg"
},
{
"id" : "android",
"name" : "Android",
"img" : "img/lvl2/android.jpg"
}
]
}
}
]JSON
Все, что нам нужно, это получить содержимое ng-repeat
Итак, начнем с реализации data/levels.json
Добавьте это в файл LevelsCtrl
js/app.js
Это так просто. Вы заметили здесь внедрение зависимости от Angular, когда сервис app.controller('LevelsCtrl', ['$scope','$http',
function($scope,$http) {
//getting list of levels
$http.get('data/levels.json').success(function(data) {
$scope.levels = data;
});
}]);
Теперь, чтобы создать представление, добавьте этот код в ваш $http
template/levels.html
Просто для удовольствия, добавьте это в файл <ion-pane>
<ion-header-bar class="bar-positive">
<a target="_blank" href="#/">
<button class="button icon-left ion-chevron-left button-clear button-white">
</button></a>
<h1 class="title">Levels</h1>
</ion-header-bar>
<ion-content class="content">
<ul class="level-list">
<li ng-repeat="lvl in levels" class="level-card">
<a target="_blank" href="#/level/{{lvl.id}}">
<button class="button button-positive level-button">{{lvl.name}}</button><br>
</a>
</li>
</ul>
</ion-content>
</ion-pane>
css/style.css
И это вид, который вы получите, нажав кнопку « .level-button {
height: 150px;
width: 150px;
border-radius: 8px;
}
Нажатие на них не сработает … пока!
Теперь мы реализуем другое представление, Start Game
Этот файл покажет все логотипы для одного уровня (в данном случае 2 логотипа).
Сначала создайте файлы изображений, как они показаны в templates/level.html
Добавьте это дерево каталогов в папку data/levels.json
www
Теперь добавьте это в ваш файл img
|---- lvl1
| |---- fb.png
| |---- sitepoint.jpg
|
|---- lvl2
|---- twitter.jpg
|---- android.jpg
template/level.html
Если вы разрабатываете для другой платформы, все, что вам нужно сделать, это поместить этот код между тегами <ion-pane>
<ion-header-bar class="bar-positive">
<a target="_blank" href="#/levels">
<button class="button icon-left ion-chevron-left button-clear button-white">
</button></a>
<h1 class="title">{{lvl.name}}</h1>
</ion-header-bar>
<ion-content class="content">
<ul id="logo-list">
</ul>
</ion-content>
</ion-pane>
ul
К сожалению, <li ng-repeat="logo in lvl.content.logos">
<a target="_blank" href="#/level/{{levelId}}/logo/{{logo.id}}">
<img ng-src="{{logo.img}}" class="logo-img">
</a>
</li>ng-src
js/app.js
Здесь вы можете увидеть еще одно внедрение зависимостей app.controller('LevelCtrl', ['$scope', '$stateParams', '$http',
function($scope,$stateParams,$http){
$scope.levelId = $stateParams.levelId;
//getting list of levels
$http.get('data/levels.json').success(function(data) {
$scope.levels = data;
for (var i=0;i<$scope.levels.length;i++) {
if($scope.levels[i].id == $scope.levelId) {
// lvl is the clicked level
$scope.lvl = $scope.levels[i];
break;
}
}
var logoList = angular.element(document.querySelector('#logo-list'));
var cnt = ""; //content of logoList
for (var i=0;i<$scope.lvl.content.logos.length;i++) {
var currLogo = $scope.lvl.content.logos[i];
cnt += '<li>'+
'<a target="_blank" href="#/level/'+$scope.levelId+'/logo/'+currLogo.id+'">' +
'<img src="'+currLogo.img+'" class="logo-img">'+
'</a>'+
'</li>';
}
//set the desired content
logoList.html(cnt);
});
}]);$stateParams
Этот сервис Angular используется для доступа к параметрам в URL. Когда мы создали состояние для этого представления, мы определили URL как /level/:levelId
Здесь :levelId
$stateParams
Как вы можете видеть, используя это
angular.element(document.querySelector('#logo-list'));
мы выбрали элемент DOM, так же, как с помощью
$('#logo-list')
в jQuery.
AngularJS поставляется с небольшим подмножеством jQuery, называемым jqLite . Используя это подмножество, мы можем поместить желаемый контент между тегами ul
Это представление, которое вы получите после перезагрузки симулятора:
В настоящее время ничего не произойдет, когда вы нажмете логотипы. Нам все еще нужно добавить другое представление, последнее представление, templates/logo.html
Добавьте этот код к нему:
<ion-pane>
<ion-header-bar class="bar-positive">
<a ng-href="#/level/{{lvl.id}}">
<button class="button icon-left ion-chevron-left button-clear button-white">
</button></a>
</ion-header-bar>
<ion-content class="content">
<div class="logo">
<img src="" alt="{{logo.img}}" id="logo-img">
</div>
<div class="item item-input">
<input type="text" name="logoName" ng-model="logo_name">
<button class="button button-small button-royal" ng-click="check(logo_name)">
Check
</button>
</div>
</ion-content>
</ion-pane>
Также добавьте этот контроллер в js/app.js
app.controller('LogoCtrl', ['$scope','$stateParams','$http',
function($scope,$stateParams,$http){
$scope.levelId = $stateParams.levelId;
$scope.logoId = $stateParams.logoId;
//getting list of levels
$http.get('data/levels.json').success(function(data) {
$scope.levels = data;
for (var i=0;i<$scope.levels.length;i++) {
//level found
if($scope.levels[i].id == $scope.levelId) {
$scope.lvl = $scope.levels[i];
break;
}
}
for (var i=0;i<$scope.lvl.content.logos.length;i++) {
//getting the clicked logo as $scope.logo
if($scope.lvl.content.logos[i].id == $scope.logoId) {
$scope.logo = $scope.lvl.content.logos[i];
break;
}
}
var img = angular.element(document.querySelector('#logo-img'));
img.attr('src',$scope.logo.img); //loading the image
});
}]);
Используя ту же технику, что и в последнем контроллере, мы загружаем изображение нажатого логотипа. Теперь последнее, что нужно сделать, это добавить немного CSS:
.logo-img {
height: 70px;
width: auto;
}
.logo {
padding-bottom: 20px;
}
.button.button-small {
padding: 5px 20px;
}
Последняя перезагрузка, и ваше приложение должно выглядеть так:
Вывод
У нас пока нет работающей игры, но у нас есть ее структура и работающий пользовательский интерфейс. В следующей части этого урока мы добавим функциональность, чтобы превратить это в настоящую игру!