Babylon.js фреймворк с открытым исходным кодом позволяющий создавать полноценные 3D-приложения и игры работающие в браузере без каких-то дополнительных плагинов, что звучит очень здорово. Сегодня мы окунемся в краткое введение этого фреймворка и языка TypeScript на котором и был написан Babylon.js. Babylon.js включает в себя все необходимые инструменты для разработки 3D-приложений. Он позволяет загружать и использовать 3D-объекты, управлять ими, создавать и управлять специальными эффектами, воспроизводить и управлять звуками, создавать геймплей и многое другое. Babylon.js прост в применении и мы это увидим на примерах.
Babylon.js создан с использованием языка TypeScript. TypeScript компилируемый и мультиплатформенный язык генерирующий чистый JavaScript код.
Сегодня мы рассмотрим следующие темы:
- Введение в Babylon.js
- Почему он был разработан с использованием TypeScript
- Введение в TypeScript
Создатели
Babylon.js был создан David Catuhe, Devid Rousset, Pierre Lagarde и Michel Rousseau. Это проект с открытым исходным кодом посмотреть на него можно на GitHab https://github.com/BabylonJS/Babylon.js, а так же у него есть свой собственный сайт http://www.babylonjs.com со множеством примеров и отличной документацией.
Инструменты вам в помощь для работы с Babylon.js
Babylon.js предоставляет насколько интерактивных инструментов в помощь разработчика и художникам:
- Для разработчиков, площадка для экспериментов (http://www.babylonjs-playground.com). Она включает в себя редактор кода и холст для вывода результата. В нем также есть некоторые примеры кода, с которыми можно очень интересно побаловаться.
- Для художников, Sandbox (http://www.babylonjs.com/sandbox/) позволяет перетаскивать в нее результат экспорта из 3D студий таких как Blender и 3ds Max, чтобы увидеть, как сцена будет выглядеть в браузере. Sandbox предоставляет вам средства отладки и дополнительные инструменты для оптимизации.
- CYOS http://www.babylonjs.com/cyos/acpr/ позволяет разработчикам создавать свои собственные шейдеры в реальном времени. Также есть несколько шейдеров уже доступных в качестве примера для обучения и экспериментов.
Почему Babylon.js разработан с использованием TypeScript?
Babylon.js достаточно большой проект, с момента его появления на GitHab он активно развивается по сей день. В нем создано большое количество функций с большим количеством параметров для большей гибкости. Язык TypeScript помогает разрабатывать более надежные и простые в сопровождении приложения, за счет типизации и ООП.
TypeScript
TypeScript — это проект с открытым исходным кодом разработанный в Microsoft. Он компилируется в JavaScript и предоставляет статическую типизацию, которая не является обязательной. Система типизации позволяет получить более чистый и понятный код. Это означает, что если функция имеет множество параметров с описанием типов, их проще понять и запомнить вместо тогда чтобы каждый раз обращаться к документации. Кроме того TypeScript позволяет объявлять классы (как это заведено в спецификации ECMAAcript 6) и интерфейсы для более понятной архитектуры и структуры кода.
Особенности TypeScript
Система типирования позволяет разработчикам создавать интерфейсы, перечисляемые типы, классы, дженерики и использовать простые типы. В целом разработчики используют типы данных для лучшего понимания и надежности кода приложения.
Язык TS поддерживает наследование (классов), а также ограничения доступа (private / public / protected) для членов класса, что очень хорошо для разделения публичного интерфейса и внутреннего.
Введение в TypeScript
Давайте рассмотрим основные моменты, такие как компиляция ts в js, работу с классами, типами, функциями, наследованием и интерфейсами.
Компиляция с помощью Gulp
Gulp — это библиотека автоматизации задач, доступная из npm. Так же имеется специальный плагин для компиляции ts в js. Единственно нам осталось все это добро настроить.
Для начало надо установить Node.js (https://nodejs.org) если у вас его еще нет, вместе с ним мы получим среду выполнения нашего скрипта gulp + доступ к NPM пакетам.
1. Используя командную строку установим gulp
npm i gulp
2. Так же используя командную строку установим модуль для компиляции ts
npm i gulp-typescript
3. Создадим файл gulpfile.js со следующим кодом
/* Gulp file that trans-compiles the TypeScript files. Usage: - "gulp" to trans-compile - "gulp watch" to automatically trans-compile when a TS file changes */ var gulp = require('gulp'); var ts = require('gulp-typescript'); var files = [ "types.ts", "classes.ts" // Other files here ]; gulp.task("default", function() { var result = gulp.src(files) .pipe(ts({ // Transcompile out: "output.js" // Merge into one output file })); return result.js.pipe(gulp.dest("./")); // output file destination }); // Automatically call the "default" task when a TS file changes gulp.task("watch", function() { gulp.watch(files, ["default"]); });
4. Чтобы запустить достаточно набрать в командной строке gulp
Типизированные переменные
В ts есть следующие типы:
- String
- Number
- Boolean
- Any
- Void
- Enum
- Array
На js мы можно написать так:
var my = 1.1; //или var my = "привет!";
И на ts мы тоже так можем написать, компилятор ts постарается угадать тип при инициализации. Но лучше это делать явно! Для этого ts предлагает следующий синтаксис:
var my: type = value;
То есть предыдущий пример можно написать так:
var my: number = 1.1; //или var my: string = "привет!";
В ts после объявления переменной уже нельзя будет присвоить значение другого типа, даже если тип не указан явно:
var my = 1.1; my = "привет!"; // Forbidden - запрещено "привет!" это строка, а не число.
Для того чтобы получить гибкость переменных js с возможность менять тип переменной на ходу в ts есть специальный тип any. Если переменная объявлена с типом any она может принимать значение любого типа:
var my: any = 1.1; // число, но можно присвоить любое другое my = 'привет!'; // тут не будет ошибки, все хорошо!
В умных IDE например в WebStorm объявление переменных с типом помогает найти ошибки еще до компиляции:
Разговаривать про типы String, Number, Boolean смысла нет, так как они ни чем не отличаются в работе в js.
Перечисления
Синтаксис объявление перечисления выглядит так:
enum FileAccess {Read, Write};
Этот код на ts порождает следующий код на js:
var FileAccess; (function (FileAccess) { FileAccess[FileAccess["Read"] = 0] = "Read"; FileAccess[FileAccess["Write"] = 1] = "Write"; })(FileAccess || (FileAccess = {}));
А объявление переменной с использованием перечисления выглядит так:
var my: FileAccess = FileAccess.Read; // Эквивалентно 0
Массивы
Объявление массивов в ts и js похожи, вот пример:
var my = []; // or var my = new Array();
В ts мы можем объявить тип элементов массива, например:
var my = new Array<number>();
в ts объявление массива без указания типа эквивалентно new Array<any>();
Классы и интерфейсы
Классы и интерфейсы позволяют создавать типы, такой же как например класс Array. После объявления класса, можно создавать экземпляры с помощью ключевого слова new.
Синтаксис объявления класса в ts следующий:
class Writer { constructor () { // инициализация происходить тут } }
Это порождает следующий код на js:
var Writer = (function () { function Writer() { // инициализация происходить тут } return Writer; }());
Теперь можно создать объект данного типа:
var myInstance = new Writer();
Можно также использовать модули, которые работают в качестве пространства имен:
module MY_MODULE { class Writer { ... } }
var myInstance = new MY_MODULE.Writer();
Создание членов класса
По конвенции в js доступ к членам класса мы можем объявить так:
function Writer () { this.myPublic = 9; // публичный this._myPrivate = 1; // приватный }
В TS мы можем явно указать спецификатор доступа (public, private и protected):
class Writer { public message: string|string[]; private _privateMessage: string = 'private message'; protected _protectedMessage: string; constructor (message: string|string[]) { this.message = message; this._protectedMessage = 'Protected message!'; } public write(): void { console.log(this.message); console.log(this._privateMessage); console.log(this._protectedMessage); } } var writer = new Writer("My public Message!"); console.log(writer.message); // доступно console.log(writer._privateMessage); // недоступно console.log(writer._protectedMessage); // недоступно
Наследование
Давайте рассмотрим наследование на примере, для это создадим новый класс:
class BetterWriter extends Writer { constructor(message: string|string[]) { super(message); } // можно переопределить методы родительского класса public write(): void { if (typeof this.message === 'string') { // вызов родительского метода super.write(); } else { for (var i = 0; i < this.message.length; i++) { console.log(this.message[i]); // доступно console.log(this._privateMessage[i]); // недоступно console.log(this._protectedMessage); // доступно } } } }
Интерфейсы
Интерфейсы используются для создания контрактов. Это означает, что если класс реализует интерфейс, класс должен обеспечить реализацию всех функций и элементов определенных в интерфейсе. Если класс не реализует контракт полностью, произойдет ошибка компиляции.
Объявленные в интерфейсе члены являются публичными (public).
interface IWriter { message: string|string[]; resetMessages(): void; } class Writer implements IWriter{ ... constructor(message: string|string[]) { ... } public write(): void { ... } public resetMessages(): void { this.message = this._privateMessage = this._protectedMessage = ''; } }
Итоги
Мы вкратце узнали что такое Babylon.js и TypeScript, разобрали особенности TypeScript и разобрались чем он нам может быть полезен и почему на нем и был написан Babylon.js. Следующим этапом мы наконец займемся знакомством с самим Babylon.js. До новых встреч!