Случайны выбор дневника Раскрыть/свернуть полный список возможностей


Найдено 12146 сообщений
Cообщения с меткой

html - Самое интересное в блогах

Следующие 30  »
rss_rss_hh_new

Создание вашей первой игры на Phaser. Часть 1 — Введение

Воскресенье, 26 Марта 2017 г. 23:23 (ссылка)

Phaser



Оглавление



0. Подготовка к работе

1. Введение [Вы тут]

2. (wip) Загрузка ресурсов

3. (wip) Создание игрового мира

4. (wip) Группы

5. (wip) Мир физики

6. (wip) Управление

7. (wip) Добавление целей

8. (wip) Последние штрихи



Добро пожаловать в наш первый урок по созданию игр на Phaser. Здесь я расскажу вам, как создать небольшую игру — платформер, которая познакомит вас с основными функциями данного фремворка и работу с ним в нынешних реалиях (ES6 / TypeScript + WebPack).



Что такое Phaser?



Phaser — это HTML5 (JavaScript / TypeScript) игровой фреймворк, который призван помочь разработчикам создавать крутые, кросс-браузерные HTML5 игры в короткие сроки и, в отличии от других фреймворков, phaser изначально затачивался под мобильные устройства. Единственное требование выдвигаемое данным фреймворком — поддержка тега . Он также много чего унаследовал от Flixel.



Требование



Исходный код данного урока и ресурсы игры лежат в этом Github репозитории с тегом part-1 (каджый тег соответствует номеру урока). Если вы уже склонировали этот репозиторый себе, начните изучение с src/index.ts.



Вам потребуются базовые знания TypeScript'а (или ES6), а также установленный Node.js для сборки проекта (я рекомендую, на момент публикации данной статьи, ставить 6'ую версию).



Когда вы склонируете себе репозиторий, не забудьте установить NPM пакеты:



npm i

# Или через Yarn
npm i -g yarn
yarn
npm rebuild # в некоторых случаях Yarn не собирает C++ пакеты, и нужно их собрать с помощью данной команды


После установки, запустите Webpack Dev Server (сервер будет слушать на http://127.0.0.1:8080):



npm start


Откройте src/index.ts в вашем любимом редакторе, и давайте ознакомимся с кодом.

Каркас приложения выглядит так:



'use strict';
/** Imports */
// Подключение глобальных зависимостей. (Напомню, они будут собраны webpack'ом в отдельный файл).
require('pixi'); // Из-за структуры кода Phaser'а, PIXI и p2 должны быть глобальными объектами
require('p2');
require('phaser'); // Так-же, в моем случае, TypeScript ломается, если подключить эту библиотеку как `import 'phaser';`

import 'styles/style.styl'; // Регистрация стилей для страницы; добавятся автоматически

// Главное состояни ("стейт") нашей игры
export class MainState extends Phaser.State {
preload(): void { }

create(): void { }

update(): void { }
}

// Основной класс нашего приложения
export default class App extends Phaser.Game {
constructor(config: Phaser.IGameConfig) {
super(config);

this.state.add('main', MainState); // Регистрируем "состояние" игры

this.state.start('main'); // Инициализируем и запуск это состояния
}
}

// Аля python'овский `__name__ == "__main__"`, нужен для проверки является ли
// данный модуль частью другой программы или он исполняемый.
if (!module.parent) {
window.onload = () => {
const config: Phaser.IGameConfig = {
width: 800, // Выста canvas'а
height: 600, // Ширина canvas'а
renderer: Phaser.AUTO, // Движок отрисовки, рекомендуется оставить AUTO
parent: '',
resolution: 1,
forceSetTimeOut: false // насильственное использование setTimeout
};

new App(config); // инициализация приложения. Оно автоматически вставит Canvas в корень разметки
};
}


На строках 4-6 мы регистрируем глобальные зависимости для нашего приложения. Как уже было сказано выше, из-за архитектуры Phaser'а (на момент написания статьи v2.6.2), эти 3 библиотеки должны быть именно глобальными (глобальными мы их делаем на этапе сборки, в Webpack). Также TypeScript (v2.2.1) почему-то ломается если их подключить через import, а не через require, ну и черт с ним.



На 22'ой строке, мы наследуем класс Phaser.Game, и регистрируем в его конструкторе состояние main нашей игры.



Сам же конструктор main стейта мы создаем на 12'ой строке, и наследуем его от Phaser.State. У этого класса есть 3 основных публичных метода (на деле гораздо больше, но эти самые часто используемые):




  • preload(): void — нужен для загрузки ресурсов игры: спрайты, звуки, json-данные и т.д.

  • create(): void — в нем инициализируются стартовые (и неизменяемые) параметры игры: установка фона, генерация карты, создание объектов и пр.

  • update(): void — метод, вызываемый при каждом тике игры (т.е. фактически на каждую смену кадра).



В дальнейшем, именно в них мы будем создавать основную логику нашей игры.



И наконец, 36'ая строка, на ней мы создаем объект конфигурации для нашего приложения, и на 45'ой строки запускаем его.



Основные свойства:




  • width — высота игрового мира.

  • height — ширина игрового мира.

  • renderer — движок отрисовки. Выбор метода рендера изображения (Canvas или WebGL), мы же выбрали Phaser.AUTO, что-бы фреймворк сам выбрал доступный движок для браузера. В случае, если браузер не поддерживает WebGL, произойдет fallback до Canvas.

  • parent — HTML элемент или селектор элемента, куда будет вставлен . По умолчанию (при ''), canvas вставится в .

  • resolution — разрешение игры.

  • forceSetTimeOut — заставит Phaser использовать setTimeout вместо requestAnimationFrame. В нашем случае это не нужно.



Остальные свойства вы найдете тут.



Если вы все сделали верно, вы увидите следующее:



Screenshot 1



И судя по данной строке, браузер поддерживает WebGL и WebAudio:



Screenshot 2



Github Repo: https://github.com/SuperPaintman/phaser-typescript-tutorial



К содержанию


Original source: habrahabr.ru.

https://habrahabr.ru/post/324896/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Создание вашей первой игры на Phaser. Часть 0 — Подготовка к работе

Воскресенье, 26 Марта 2017 г. 23:17 (ссылка)

Phaser



Оглавление



0. Подготовка к работе [Вы тут]

1. Введение

2. (wip) Загрузка ресурсов

3. (wip) Создание игрового мира

4. (wip) Группы

5. (wip) Мир физики

6. (wip) Управление

7. (wip) Добавление целей

8. (wip) Последние штрихи



Эта серия статей научит вас основам и "хорошему тону" игрового фремворка Phaser. За данный курс, я постараюсь объяснить вам основные идеи и возможности фреймворка, а также покажу как его грамотно использовать в связке с TypeScript и Webpack.



Основной ход обучения взят из официального руководства, но это не дословный перевод, а адаптация руководства, с переписанными примерами с ES5 на TypeScript и измененной структурой проекта. Я также раскрыл некоторые темы более развернуто.

Думаю стоит оговориться, что на момент написания данной статьи, я использую Phaser v2.6.2 и TypeScript v2.2.1.



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




  • part-0 — состояние проекта на момент текущей статьи

  • part-1 — на момент статьи #1 Введение



и так далее.



В двух словах о Phaser



Phaser — бесплатный (MIT), кросс-браузерные HTML5 фреймворк для создания браузерных игр с использованием WebGL и Canvas. В отличии от других фреймворков, Phaser в первую очередь целится на мобильные платформы и оптимизирован под них.



Инструменты



Прежде всего вам потребуется склонировать репозиторий с проектом себе:



git clone https://github.com/SuperPaintman/phaser-typescript-tutorial.git


И установить Node.js для запуска сборщика и других NPM скриптов.



Структура проекта



Прежде чем перейти непосредственно к самому фремворку, рассмотрим структуру будущего приложения.



В качестве основы для нашего проекта, я взял данный Phaser TypeScript шаблон, который использует Webpack в качестве сборщика.



Давайте рассмотрим основные его файлы (внимание на комментарии):



webpack.config.js



Конфигурация для сборщика Webpack. В зависимости от переменной окружения NODE_ENV соберет билд для разработки, или оптимизированный билд для продакшена.



webpack.config.js
'use strict';
/** Requires */
const path = require('path');

const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const ImageminPlugin = require('imagemin-webpack-plugin').default;

const p = require('./package.json');

/** Constants */
const IS_PRODUCTION = process.env.NODE_ENV === 'production';

const assetsPath = path.join(__dirname, 'assets/'); // папка с ресурсами игры
const stylesPath = path.join(__dirname, 'styles/'); // папка с css стилями

// Путь до папки с собранными билдами phaser. Из-за того, что phaser собирается
// по-старинке, его (а также его зависимости) придётся подключать как
// глобальный объект.
const phaserRoot = path.join(__dirname, 'node_modules/phaser/build/custom/');

// Пути до библиотек phaser'а
const phaserPath = path.join(phaserRoot, 'phaser-split.js');
const pixiPath = path.join(phaserRoot, 'pixi.js');
const p2Path = path.join(phaserRoot, 'p2.js');

// Папка, в которую у будет собран наш билд
const outputPath = path.join(__dirname, 'dist');

// Путь до шаблона `index.html` файле
const templatePath = path.join(__dirname, 'templates/index.ejs');

/** Helpers */
/**
* Проверяет, содержит ли массив данный элемент
* @param {T[]} array
* @param {T} searchElement
*
* @return {boolean}
*/
function includes(array, searchElement) {
return !!~array.indexOf(searchElement);
}

/**
* Создает правила для `expose-loader`, который добавляет модуль к глобальному
* объекту window по переданному имени
* @param {string} modulePath
* @param {string} name]
*
* @return {Object}
*/
function exposeRules(modulePath, name) {
return {
test: (path) => modulePath === path,
loader: 'expose-loader',
options: name
};
}

/**
* Удаляет из массива все элементы равные `null`
* @param {T[]} array
*
* @return {T[]}
*/
function filterNull(array) {
return array.filter((item) => item !== null);
}

/**
* Вызывает функцию `fn`, если `isIt` равет `true`, в противном случае будет
* вызвана функция `fail`.
*
* @param {boolean} isIt
* @param {function} fn
* @param {function} fail
*
* @return {any}
*/
function only(isIt, fn, fail) {
if (!isIt) {
return fail !== undefined ? fail() : null;
}

return fn();
}

/**
* Хелпер на основе `only`. Вызывает первую функцию, если
* `NODE_ENV` === 'production', т.е. если сборка производится для продакшена.
* @param {function} fn
* @param {function} fail
*
* @return {any}
*/
const onlyProd = (fn, fail) => only(IS_PRODUCTION, fn, fail);
/**
* Хелпер на основе `only`. Вызывает первую функцию, если
* `NODE_ENV` !== 'production', т.е. если сборка производится для разработки.
* @param {function} fn
* @param {function} fail
*
* @return {any}
*/
const onlyDev = (fn, fail) => only(!IS_PRODUCTION, fn, fail);

module.exports = {
entry: {
main: path.join(__dirname, 'src/index.ts')
},
output: {
path: outputPath,
// На продакшене также добавим к именам файлов их хещ, чтобы обойти
// проблему с кешированием версий
filename: `js/[name]${onlyProd(() => '.[chunkhash]', () => '')}.js`,
chunkFilename: `js/[name]${onlyProd(() => '.[chunkhash]', () => '')}.chunk.js`,
sourceMapFilename: '[file].map',
publicPath: '/'
},
devtool: onlyDev(() => 'source-map', () => ''), // Отключим sourcemap'ы на проде.
resolve: {
extensions: ['.ts', '.js'],
alias: {
pixi: pixiPath, // сделаем возможным подключить 'pixi' библиотеку как обычный NPM пакет
phaser: phaserPath, // сделаем возможным подключить 'phaser' библиотеку как обычный NPM пакет
p2: p2Path, // сделаем возможным подключить 'p2' библиотеку как обычный NPM пакет
assets: assetsPath, // алиас до папки `assets/`
styles: stylesPath // алиас до папки `styles/`
}
},
plugins: filterNull([
/** DefinePlugin */
// Глобальные переменные, будт полезны для отключения каких-либо функций на
// проде, или напротив включения оптимизаторов и пр.
new webpack.DefinePlugin({
IS_PRODUCTION: JSON.stringify(IS_PRODUCTION),
VERSION: JSON.stringify(p.version)
}),

/** JavaScript */
// Минимизирует JS для продовой сборки
onlyProd(() => new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
comments: false
})),

/** Clean */
// Удалит `dist` папку перед каждой сборкой
new CleanWebpackPlugin([outputPath]),

/** TypeScript */
new CheckerPlugin(),

/** Images */
// Оптимизирует изображения и svg'хи
onlyProd(() => new ImageminPlugin({
test: /\.(jpe?g|png|gif|svg)$/
})),

/** Template */
// Данный плагин автоматически сгенерирует для нас `index.html` файл
// на основе `templatePath`, а также сам вставит в этот шаблон все
// сгенерированные скрипты и стили
new HtmlWebpackPlugin({
title: 'Phaser TypeScript boilerplate project',
template: templatePath
}),

/** CSS */
// Экспортирует CSS import'ы в отдельный `.css` файл (по-умолчанию Webpack
// вставляет CSS прямо в JS файлы).
new ExtractTextPlugin({
filename: `css/[name]${onlyProd(() => '.[chunkhash]', () => '')}.css`
}),

/** Chunks */
// Разобьем нашу сборку на несколько файлов (т.к. вендорные файлы и файлы
// самого phaser'а вряд ли будут меняться в процессе разработки, нет нужды
// заставлять наших клиентов тянуть каждый раз эти данные заново. Чанки как
// раз помогут в этом, браузер сможет доставать из кеша файлы, которые не
// поменялись):
// * Чанк для прочих модулей
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: (module) => /node_modules/.test(module.resource)
}),
// * Чанк для phaser модулей (p2, PIXI, phaser)
new webpack.optimize.CommonsChunkPlugin({
name: 'phaser',
minChunks: (module) => includes([p2Path, pixiPath, phaserPath], module.resource)
}),
// * Чанк для инициализационных функций webpack'а
new webpack.optimize.CommonsChunkPlugin({
name: 'commons'
})
]),
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 8080,
inline: true,
watchOptions: {
aggregateTimeout: 300,
poll: true,
ignored: /node_modules/
}
},
module: {
rules: [
/** Assets */
// Скопирует файлы из asset'ов
{
test: (path) => path.indexOf(assetsPath) === 0,
loader: 'file-loader',
options: {
name: `[path][name]${onlyProd(() => '.[sha256:hash]', () => '')}.[ext]`
}
},

/** CSS */
{
test: /\.styl$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'stylus-loader'
]
})
},

/** JavaScript */
exposeRules(pixiPath, 'PIXI'), // добавит `PIXI` модуль в глобальный объект `window`
exposeRules(p2Path, 'p2'), // добавит `p2` модуль в глобальный объект `window`
exposeRules(phaserPath, 'Phaser'), // добавит `Phaser` модуль в глобальный объект `window`
{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'awesome-typescript-loader'
}
]
}
};


assets/



В эту директорию мы будем складывать все ресурсы нашего приложения: изображения, музыку, JSON и прочее.



styles/style.styl



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



body
margin: 0px


templates/index.ejs



EJS шаблон для страницы игры (Webpack сам добавит в него загрузку всех скриптов и стилей):













tsconfig.json



Конфиг для TypeScript:



{
"compilerOptions": {
"target": "es5", // Для большей поддержки браузерами
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"removeComments": false,
"noImplicitAny": false,
"pretty": true
},
"files": [
// Нужно указать откуда тайпинги Phaser'а явно, т.к. в данной папке
// содержатся несколько разных их версий, которые будут конфликтовать между
// собой.
"./node_modules/phaser/typescript/box2d.d.ts",
"./node_modules/phaser/typescript/p2.d.ts",
"./node_modules/phaser/typescript/phaser.comments.d.ts",
"./node_modules/phaser/typescript/pixi.comments.d.ts"
],
"include": [
// А так-же укажем откуда брать тайпинги по glob'у
"./src/**/*.ts",
"./node_modules/@types/**/*.ts"
]
}


src/typings.d.ts



В данном файле мы должны объявить все глобальные переменные, которые создали в webpack.DefinePlugin:



declare const IS_PRODUCTION: boolean;
declare const VERSION: string;


src/index.ts



Это основной файл нашего приложение, он будет входной точной в него:



'use strict';


На этой основе мы будем создавать платформер.



Github Repo: https://github.com/SuperPaintman/phaser-typescript-tutorial



К содержанию


Original source: habrahabr.ru.

https://habrahabr.ru/post/324894/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Дайджест свежих материалов из мира фронтенда за последнюю неделю №255 (20 — 26 марта 2017)

Воскресенье, 26 Марта 2017 г. 22:39 (ссылка)

Предлагаем вашему вниманию подборку с ссылками на полезные ресурсы и интересные материалы из области фронтенда.























Веб-разработка
CSS
Javascript
Браузеры
Занимательное


Веб-разработка





CSS





JavaScript





Браузеры





Занимательное





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





Дайджест за прошлую неделю.

Материал подготовили dersmoll и alekskorovin.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/324888/

Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Выравнивание в Bootsrap

Суббота, 25 Марта 2017 г. 21:33 (ссылка)

При работе с фреймворком Bootstrap обычно сталкиваются с тремя основными проблемами:




  1. Как поместить контент внизу колонки?

  2. Как создать многорядную галерею колонок одинаковой высоты в одном .row?

  3. Как центрировать горизонтально несколько колонок, если их суммарная ширина меньше 12 единиц и оставшаяся ширина нечетна?



Для решения первых двух проблем, необходимо скачать небольшой плагин https://github.com/codekipple/conformity



Решение третьей проблемы подсмотрено здесь http://www.minimit.com/articles/solutions-tutorials/bootstrap-3-responsive-centered-columns



Общий код










1. Как поместить контент внизу колонки?





Я
самая
высокая
колонка



Я прижат книзу




2. Многорядная галерея колонок одинаковой высоты в одном .row




...

...

...

...

...

...



3. Горизонтальное центрирование нескольких колонок, если их суммарная ширина меньше 12 единиц и оставшаяся ширина нечетна




...

...



Оба класса могут работать вместе




...

Original source: habrahabr.ru.

https://habrahabr.ru/post/324858/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Выравнивание в Bootsrap

Суббота, 25 Марта 2017 г. 21:33 (ссылка)

При работе с фреймворком Bootstrap обычно сталкиваются с тремя основными проблемами:




  1. Как поместить контент внизу колонки?

  2. Как создать многорядную галерею колонок одинаковой высоты в одном .row?

  3. Как центрировать горизонтально несколько колонок, если их суммарная ширина меньше 12 единиц и оставшаяся ширина нечетна?



Для решения первых двух проблем, необходимо скачать небольшой плагин https://github.com/codekipple/conformity



Решение третьей проблемы подсмотрено здесь http://www.minimit.com/articles/solutions-tutorials/bootstrap-3-responsive-centered-columns



Общий код










1. Как поместить контент внизу колонки?





Я
самая
высокая
колонка



Я прижат книзу




2. Многорядная галерея колонок одинаковой высоты в одном .row




...

...

...

...

...

...



3. Горизонтальное центрирование нескольких колонок, если их суммарная ширина меньше 12 единиц и оставшаяся ширина нечетна




...

...



Оба класса могут работать вместе




...

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/324858/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество

Следующие 30  »

<html - Самое интересное в блогах

Страницы: [1] 2 3 ..
.. 10

LiveInternet.Ru Ссылки: на главную|почта|знакомства|одноклассники|фото|открытки|тесты|чат
О проекте: помощь|контакты|разместить рекламу|версия для pda