diff --git a/README.md b/README.md index 0f950bd..b0909c0 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ # docs.superpowers-html5.com -This is the repository for the official documentation of Superpowers at [docs.superpowers-html5.com](http://docs.superpowers-html5.com). +Это хранилище для официальной документации Superpowers at [docs.superpowers-html5.com](http://docs.superpowers-html5.com). -(This website will be turned into a Superpowers Web project in the future.) +(Этот сайт будет превращен в Superpowers Web project в будущем.) -## How to run the website locally +## Как запустить сайт локально -Make sure you have [Node.js](https://nodejs.org) installed. Clone the repository, open it in a terminal and run: +Убедитесь, что у вас установлен [Node.js](https://nodejs.org). Клонируйте репозиторий, откройте его в терминале и запустите: npm install npm run build -To start the server, run: +Чтобы запустить сервер, запустите: npm start -And go to http://localhost:9051 +И перейдите на http://localhost:9051 diff --git a/package.json b/package.json index 421a9a4..245c059 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "jade": "~1.11.0", "marked": "~0.3.5", "nib": "~1.1.0", + "pug": "^2.0.4", "stylus": "~0.53.0" } } diff --git a/pages/ru/1_getting-started/10_publishing-your-game.md b/pages/ru/1_getting-started/10_publishing-your-game.md new file mode 100644 index 0000000..35de861 --- /dev/null +++ b/pages/ru/1_getting-started/10_publishing-your-game.md @@ -0,0 +1,129 @@ +# Публикация вашей игры + +Superpowers поставляется с публикацией в один клик по кнопке `Publish project`, расположенной в верхнем левом углу. + +![Кнопка "Publish project"](/images/publishing-your-game/publish-project-button.png) + +
+

**Экспорт доступен только из приложения**, не при доступе Superpowers через браузер, + потому что браузеры не позволяют веб-приложениям обращаться к файловой системе напрямую из соображений безопасности. +

+ +## Публикация вашей игры для Интернета + +Вы можете загрузить экспортированную папку на любой веб-хостинг или заархивировать ее и загрузить как HTML5 на портал онлайн-игр. +лайк itch.io или Game Jolt. + +## Упаковка для desktop + +
+

**Дважды проверьте название вашего проекта**, он появится в строке заголовка отдельных сборок вашей игры. +

+ +
+

Мы надеемся автоматизировать все эти этапы упаковки в будущей версии. +

+ +Если вы хотите создавать автономные загружаемые версии вашей игры, вы можете использовать Electron. +Electron - это в основном браузерный движок Chrome, предназначенный для запуска автономных приложений и игр HTML5, а не полноценного веб-браузера. + +
+

Загрузите соответствующие сборки Electron. + Мы рекомендуем вам поддерживать Windows как в 64-битной, так и в 32-битной версиях, но, вероятно, вам подойдут только 64-битные версии. +  для Linux и OS X (Apple несколько лет не поставляла 32-битное оборудование). +

+ +Electron требует, чтобы вы создали два файла, чтобы запустить вашу игру: + +### package.json + +``` +{ + "name": "my-game", + "version": "1.0.0", + "main": "main.js" +} +``` + +Не забудьте заменить `my-game` с названием вашей игры, используя строчные слова, разделенные тире. + +### main.js + +``` +"use strict"; + +const electron = require("electron"); +var mainWindow = null; + +electron.app.on("window-all-closed", () => { + if (process.platform != "darwin") electron.app.quit(); +}); + +electron.app.on("ready", () => { + mainWindow = new electron.BrowserWindow({ + width: 1280, height: 720, + useContentSize: true, + // NOTE: Вы можете включить их, если хотите + // resizable: false, + // icon: `${__dirname}/icon.png` + }); + mainWindow.setMenuBarVisibility(false); + mainWindow.loadURL(`file://${__dirname}/index.html`); + mainWindow.on("closed", () => { mainWindow = null; }); +}); +``` + +### Упаковка для окон (32-bit и 64-bit) + +
+

Распакуйте ZIP-архив Electron для каждой архитектуры и переименуйте папки в «my-game-win-ia32» (32-разрядная версия) и «my-game-win-x64» (64-разрядная версия). + +

Для обеих этих папок: + +

+ +

Вот и все, упакуйте все это в ZIP-архив и загрузите. +

+ +### Упаковка для Linux + +
+

Распакуйте ZIP-архив Electron и переименуйте папку в нечто вроде `my-game-linux-x64`. + +

+ +

That's it, pack it all up into a ZIP archive and upload. +

+ +### Packaging for OS X + +
+

Unpack the Electron ZIP archive and rename the folder to something like `my-game-osx-x64`. + +

+ +

That's it, pack it all up into a ZIP archive and upload. +

+ +## Packaging for mobile + +Регулярно экспортируйте и используйте [Intel XDK](https://software.intel.com/en-us/intel-xdk) +создать приложение для конкретной платформы, которое вы можете отправить в магазин. + +На Android кажется, что минимальная версия, необходимая для поддержки WebGL - 4.4. +Соответственно, вы должны настроить `Projects/Build Settings/Minimum Android Version` на `19` в Intel XDK. diff --git a/pages/ru/1_getting-started/11_source-control.md b/pages/ru/1_getting-started/11_source-control.md new file mode 100644 index 0000000..5ba9984 --- /dev/null +++ b/pages/ru/1_getting-started/11_source-control.md @@ -0,0 +1,20 @@ +# Using source control + +Source control lets you create checkpoints in your project, compare old revisions with newer ones and back things up to a remote host like [GitHub](https://github.com/) or [Bitbucket](https://bitbucket.org/). + +Superpowers projects can easily be kept under [source control](https://en.wikipedia.org/wiki/Revision_control). While there is no built-in support at the moment, existing tools like Git and Mercurial work great. + +## Delay when making changes + +In order to minimize its performance footprint, the Superpowers server doesn't write every change you make to a project to the disk immediately. Saving to disk might be delayed for up to 60 seconds. + +When creating a new revision for your project, either wait 60s or stop your server altogether to make sure everything has been flushed out to the disk. (We'll probably have a button to flush changes in the app at some point). + +## Что не надо помещать под систему контроля версий + +Есть пара папок, которые вы, вероятно, не хотите фиксировать в своем хранилище.: + + * Папка `rooms/` содержит историю вашего недавнего журнала чата + * Папка `trashedAssets/` содержит удаленные активы + +Вы можете использовать `.gitignore` или файл `.hgignore`. diff --git a/pages/ru/1_getting-started/1_about-superpowers.md b/pages/ru/1_getting-started/1_about-superpowers.md new file mode 100644 index 0000000..ad9dd10 --- /dev/null +++ b/pages/ru/1_getting-started/1_about-superpowers.md @@ -0,0 +1,34 @@ +# About Superpowers + +Superpowers - это среда разработки HTML5 для создания 2D и 3D игр.. +Он может быть расширен с помощью плагинов и позволяет вам сотрудничать в режиме реального времени. + +[Смотрите вступительное видео на YouTube](https://www.youtube.com/watch?v=T7XoWWvGPd4) + +Superpowers был в разработке более года. +Это уже отличная IDE, но она все еще быстро развивается. + +Мы решили сделать это бесплатно и open source. +Если вам это нравится, вы можете поддержать нашу работу +в patreon.com/SparklinLabs. + + + Superpowers IDE + Superpowers demo + + +Вы можете [внести свой вклад в эту документацию по GitHub](https://github.com/superpowers/docs.superpowers-html5.com). + +## Условные обозначения + +В этом руководстве всякий раз, когда вы должны что-то делать, это будет выглядеть так: + +
+

Это действие, которое вы должны предпринять. +

+ +Важные примечания и информация об устранении неполадок будут отображаться в таких полях: + +
+

Это может быть важным примечанием, не пропустите! +

diff --git a/pages/ru/1_getting-started/2_setting-up-superpowers.md b/pages/ru/1_getting-started/2_setting-up-superpowers.md new file mode 100644 index 0000000..eaf7a83 --- /dev/null +++ b/pages/ru/1_getting-started/2_setting-up-superpowers.md @@ -0,0 +1,65 @@ +# Setting up Superpowers + +
+

Загрузите правильный ZIP для вашей платформы с страница загрузки. + Разархивируйте его в удобном месте и дважды щелкните «Superpowers». +  Приложение запустится. +

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

**Superpowers использует TCP-порты 4237 (для обслуживания клиента) и 4238 (для обслуживания сборок) ** по умолчанию, поскольку порт 80 требует специальных привилегий в Linux & OS X. Кроме того, такие программы, как Skype, возможно, уже прослушивают его. Вы можете изменить порты, используемые Superpowers, на вкладке настроек сервера приложения. + +

Если вы это сделаете, обязательно измените адрес записи «Мой сервер» в списке серверов, чтобы использовать правильный порт. +

+ +Double-click в "My Server" и откроется вкладка. Вам будет предложено выбрать имя пользователя. + +## Где хранятся мои данные? + +По умолчанию конфигурация вашего сервера и проекты хранятся в следующих местах, в зависимости от вашей операционной системы: + + * В Windows: `%APPDATA%\Superpowers` + * В OS X: `~/Library/Application Support/Superpowers` (Используйте пункт меню «Перейти в папку» в Finder) + * В Linux: `~/.local/share/Superpowers` + +Чтобы сделать Superpowers автономный (например, если вы хотите носить Superpowers на USB-накопителе), вы можете переместить `config.json` файл и `projects` папка для Superpowers's `app` папку, и он автоматически начнет использовать их. Будьте осторожны при обновлении, вам нужно вручную переместить эти файлы из старой версии в новую. + +## Позволить другим присоединиться к вашему серверу + +По умолчанию ваш сервер будет принимать соединения только с того компьютера, на котором он работает. + +
+

Чтобы открыть свой сервер для других, установите пароль в Настройках и остановите / запустите сервер. +

+ +
+

**Вам, вероятно, понадобится настройте свой домашний маршрутизатор** и/или firewall + разрешить (или переслать) входящие TCP-соединения на номера портов, которые прослушивает ваш сервер (по умолчанию 4237 и 4238). +

+ +Когда ваш сервер открыт, получить ваш публичный IP-адрес и вы можете отправить ссылку на форму `ip:port` людям, с которыми вы хотите работать (e.g. `1.2.3.4:4237`). Они могут либо вставить эту ссылку в адресную строку своего браузера, чтобы присоединиться без установки чего-либо, либо добавить ее в свой список серверов Superpowers из приложения. + +
+

**Убедитесь, что вы указали свой публичный IP-адрес** с теми, с кем вы хотите сотрудничать. `127.0.0.1` это специальный адрес, который всегда указывает на компьютер, на котором вы его используете, поэтому другие не смогут подключиться к нему с вашего сервера. + +

Самый простой способ получить ваш публичный IP-адрес - это спросить Google. +

+ +## Запуск сервера Superpowers из командной строки + +Может быть полезно запускать Superpowers на автономном сервере, чтобы вам не приходилось постоянно включать настольный компьютер. +Это должно работать на любом сервере Linux, включая Raspberry Pi. + + * Установите последнюю версию Node.js. + * Скачайте [последний выпуск Superpowers Core](https://github.com/superpowers/superpowers-core/releases) и "распакуйте" его. + * Запустите `node server start` в корне. + +По умолчанию Superpowers будет хранить файлы конфигурации и проектов в `$XDG_DATA_HOME/Superpowers` (или `~/.local/share/Superpowers` если `$XGD_DATA_HOME` is undefined). Вы можете использовать опцию `--data-path=` чтобы переопределить это поведение. + +
+ После первого запуска вашего сервера вам необходимо остановить его (с помощью `Ctrl + C`) +  и отредактировать сгенерированный файл `config.json`, чтобы установить пароль, затем снова запустите сервер. +  Вы также можете настроить порты, которые он будет прослушивать. +
diff --git a/pages/ru/1_getting-started/3_first-project.md b/pages/ru/1_getting-started/3_first-project.md new file mode 100644 index 0000000..e00b065 --- /dev/null +++ b/pages/ru/1_getting-started/3_first-project.md @@ -0,0 +1,14 @@ +# Создание вашего первого проекта + +
+

Нажмите на `New Project`, введите имя и описание. + Дважды щелкните по названию вашего проекта, чтобы открыть его. +

+ +Superpowers поставляется с набором плагинов для импорта спрайтов, 3D-моделей, звуков, создания сцен, написания сценариев и многого другого. + +Проект состоит из дерева папок и активов. +Актив - это общее имя для любой базовой части проекта, такой как спрайт, сцена или скрипт. + +Вы можете изменить порядок ресурсов вашего проекта, перетаскивая их. +Дважды щелкните актив, чтобы открыть его редактор на вкладке, или используйте вместо него значок «Открыть в новом окне». diff --git a/pages/ru/1_getting-started/4_first-game.md b/pages/ru/1_getting-started/4_first-game.md new file mode 100644 index 0000000..0bf4dea --- /dev/null +++ b/pages/ru/1_getting-started/4_first-game.md @@ -0,0 +1,51 @@ +# Ваша первая (почти) игра + +
+

**Создайте актив Sprite**, назовите его `Leonard`, откройте его двойным щелчком и загрузите маленькое изображение. + Можете использовать [например Leonard, Superpowers's mascott](http://superpowers-html5.com/images/superpowers-logo.png)).

+
+ +Убедитесь, что размер сетки соответствует размеру вашего изображения, чтобы все изображение было видно на панели предварительного просмотра (внизу). + +
+

**Создайте актив Script** назовите его `Game` и откройте. +

+ +Скрипты используют чтобы сообщить Superpowers что делать с вашими активами. +Когда вы запускаете свою игру, **Superpowers читает каждый скрипт по порядку сверху вниз** +и выполняет инструкции в них. +Superpowers поставляется с TypeScript в качестве своего скриптового языка. + +Метафорически, ваша игра - это съемочная площадка, а вы режиссер. Своими скриптами, вы будете привлекать актеров, надевать их костюмы и рассказывать им, как себя вести. Если у вас нет скриптов, никто не появится и экран останется черным. + +
+

В редакторе скриптов, очистите дефолтный текст и введите следующее (или скопировать / вставить, но вы научитесь быстрее, если наберете это самостоятельно): +

+ +``` +// Призвать нашего первого актера, он сыграет главного героя +let mainCharacterActor = new Sup.Actor("Main Character"); +// Скажи нашему актеру облачиться в костюм "Леонарда" (sprite) +new Sup.SpriteRenderer(mainCharacterActor, "Leonard"); + +// Вызовите второго актера на сцену, он будет оператором +let cameraManActor = new Sup.Actor("Camera Man"); +// Дайте ему камеру! +new Sup.Camera(cameraManActor); + +// Разместите наших актеров. Главный герой находится в центре сцены +mainCharacterActor.setPosition(0, 0, 0); + +// Оператор будет смотреть на главного актера на расстоянии +cameraManActor.setPosition(0, 0, 5); +``` + +Строки, начинающиеся с `//`, являются комментариями. Superpowers игнорирует их, я просто поместил их сюда, чтобы объяснить, что происходит. + +
+

ВАЖНО: Обязательно нажмите `Ctrl+S` чтобы применить изменения, внесенные в ваш скрипт. Вы заметите что `draft` индикатор в дереве ресурсов исчезнет при сохранении вашего скрипта.

+
+ +Superpowers может обнаружить некоторые ошибки скриптинга (syntax, reference and type errors) на лету, так что если вы увидите некоторые слова красным, когда вы закончите, вы будете знать, что вам нужно проверить эту строку и соседние строки. Подробные сообщения об ошибках отображаются внизу редактора. + +Когда вы закончите, запустите игру кнопкой `Run game` и вы должны увидеть нашего маленького актера! diff --git a/pages/ru/1_getting-started/5_scripted-behaviors.md b/pages/ru/1_getting-started/5_scripted-behaviors.md new file mode 100644 index 0000000..0fe3a9a --- /dev/null +++ b/pages/ru/1_getting-started/5_scripted-behaviors.md @@ -0,0 +1,60 @@ +# Сценарий поведения + +Поведение многократного использования может быть определено так, чтобы вы могли поместить их в нескольких актеров. +Вот как может выглядеть определение поведения: + +``` +class MyBehavior extends Sup.Behavior { + // Объявите свойства здесь + + awake() { + // Поместите логику инициализации здесь + // this актер представляет собой актера, к которому привязано поведение + } + + update() { + // Поместите логику, которая должна выполняться здесь 60 раз в секунду + } + +} +// Не забудьте зарегистрировать свой класс поведения +Sup.registerBehavior(MyBehavior); +``` + +Внутри методов поведения (`awake`, `update` и другие, которые вы можете определить сами), Вы можете ссылаться на текущий компонент поведения с `this` и actor котоорый с ним связан это `this.actor`. + +Давайте добавим поведение к нашему главному герою из предыдущей главы. + +
+

Вернитесь к вашему скрипту `Game` и добавьте следующий код в низ: +

+ +``` +class CharacterBehavior extends Sup.Behavior { + + update() { + if (Sup.Input.isKeyDown("LEFT")) { + // Переместить актера текущего поведения на небольшое отрицательное смещение по оси X + this.actor.move(-0.1, 0, 0); + } + + if (Sup.Input.isKeyDown("RIGHT")) { + // То же, но положительным значением, чтобы идти направо + this.actor.move(0.1, 0, 0); + } + } + +} +Sup.registerBehavior(CharacterBehavior); + +// Как только класс поведения определен, +// нам нужно прикрепить его к нашему персонажу +mainCharacterActor.addBehavior(CharacterBehavior); +``` + +`Sup.Input.isKeyDown(...)` возвращает `true` только когда указанная клавиша нажата. + +
+ **Есть много других функций** доступных для чтения ввода от игрока и реакции на него. + Все они перечислены в **TypeScript API browser** доступном изнутри Superpowers. +
diff --git a/pages/ru/1_getting-started/6_scenes.md b/pages/ru/1_getting-started/6_scenes.md new file mode 100644 index 0000000..776d9f3 --- /dev/null +++ b/pages/ru/1_getting-started/6_scenes.md @@ -0,0 +1,61 @@ +# Работа со сценами +Сцены позволяют визуально построить конфигурацию актеров и их компонентов (renderers, behaviors, etc.). + +Мы собираемся восстановить наш фильм раньше, но использовать сцену вместо того, чтобы записывать их. + +
+

Создайте новый ресурс сцены с именем `Main Scene` и откройте его. +

+ +
+

**В редакторе сцены, используйте `WASD`** чтобы двигаться вперед, назад, влево и вправо, «пробел», чтобы подняться, и «Shift», чтобы спуститься. +

+ +
+

Создайте actor с именем `Main Character` и разместите его в (0, 0, 0). + Добавьте ему компонент `Sprite Renderer` и задайте `Leonard` кв качестве используемого спрайта. + И еще один компонент, теперь уже типа `Behavior` и выберите `CharacterBehavior` как используемый класс. +

+ +
+

Нажмите в любом месте дерева сцены, чтобы отменить выбор актера, которого вы только что создали. +  Создайте другого актера с именем `Camera Man` и поместите его в (0, 0, 5). +  Добавьте компонент камеры на него. +

+ +
+

**Убедитесь что `Camera Man` actor не является родителем для `Main Character` actor** в дереве сцены. + Если это так, просто используйте drag'n'drop, чтобы очистить родительство. +

+ +Теперь, когда наша сцена готова, давайте вернемся к нашему скрипту. Мы можем избавиться от всего кода, который создали наши актеры, и вместо этого заменить его одной инструкцией для загрузки нашей сцены. Нам все еще нужно объявить `CharacterBehavior`. + +
+

Замените содержимое скрипта `Game` следующим текстом: +

+ +``` +class CharacterBehavior extends Sup.Behavior { + update() { + if (Sup.Input.isKeyDown("LEFT")) this.actor.move(-0.1, 0, 0); + if (Sup.Input.isKeyDown("RIGHT")) this.actor.move(0.1, 0, 0); + } +} +Sup.registerBehavior(CharacterBehavior); + +Sup.loadScene("Main Scene"); +``` + +
+

**Важно, чтобы вы объявили класс `CharacterBehavior` до того как загрузите сцену с помощью `Sup.loadScene`** (то есть выше, в сценарии), или Superpowers будет жаловаться, что он не знает (пока), каково поведение. +

+ +При работе с несколькими классами поведения для организационных целей обычно каждый из них помещается в отдельный сценарий. Поскольку сценарии будут читаться по порядку, убедитесь, что вы загружаете свою сцену в сценарий, размещенный под всеми сценариями поведения, которые он использует. + +## Загрузка сцены при запуске игры без кода + +Вы можете определить сцену, которая будет автоматически загружаться Superpowers после прочтения всех ваших сценариев в разделе «Игра» инструмента «Настройки». + +![](http://i.imgur.com/DaWYJqS.png) + +Это полностью эквивалентно вставке вызова в Sup.loadScene в конце вашего последнего скрипта, но это более удобно, так как вы всегда будете знать, где его изменить, если вам нужно. \ No newline at end of file diff --git a/pages/ru/1_getting-started/7_variables.md b/pages/ru/1_getting-started/7_variables.md new file mode 100644 index 0000000..fffe9ef --- /dev/null +++ b/pages/ru/1_getting-started/7_variables.md @@ -0,0 +1,95 @@ +# управление состоянием + +Переменные позволяют хранить, читать и изменять состояние во время игры. Они могут быть использованы для хранения того, на каком уровне находится игрок, сколько здоровья у монстра, скорость объекта, какие объекты находятся в инвентаре персонажа или что-то еще, на самом деле. + +Вы можете объявить и инициализировать глобальную переменную в корне скрипта: +``` +let currentLevel = 1; +``` + +Когда происходит какое-то событие, вы можете увеличить значение: + +``` +// ... Когда игрок достигает выхода ... +currentLevel++; +Sup.loadScene(`Level ${currentLevel}`); +``` + +Когда вы объявляете переменную внутри функции, она существует только во время выполнения этой функции: + +``` +function doSomething() { + let i = 0; + i++; + // `i` теперь равняется 1 +} +``` + +Независимо от того, сколько раз вы вызываете `doSomething()`, `i` будет сброшен в `0` а потом `1` но не пойдет выше. + +Точно так же, поскольку переменная, объявленная внутри метода, существует только во время выполнения этого метода, вы не можете ссылаться на нее из другого метода: + +``` +class MyClass { + doSomething() { + let i = 0; + } + + doSomethingElse() { + // Попытка использовать здесь `i` приведет к ошибке. + // В контексте doSomethingElse () `переменная` i` отсутствует. + } +} +``` + +Чтобы поддерживать состояние, связанное с определенным компонентом поведения (например, здоровье персонажа), вы можете использовать переменные-члены: +``` +class MyBehavior extends Sup.Behavior { + + // Переменные-члены должны быть объявлены без ключевого слова let + // прямо внутри тела класса: + health = 100; + + takeDamage(amount) { + // Переменные-члены инициализируются при создании компонента поведения. + // Вы можете получить доступ к самому поведению и его переменным-членам через `this`. + this.health -= amount; + if (this.health <= 0) { + // Смерть! + this.actor.destroy(); + } + } + +} +Sup.registerBehavior(MyBehavior); +``` + +## Настройка свойств поведения + +При добавлении компонента поведения к актеру в сцене вы можете настроить начальные значения для его переменных-членов, что позволит вам иметь мобов с разной начальной скоростью, состоянием здоровья и т. Д. + +Вы можете сделать то же самое в скрипте, передав объект в качестве второго параметра `Sup.Actor.addBehavior`: + +``` +let collectedPoints = 0; + +class BonusBehavior extends Sup.Behavior { + + // 10 бонусных очков по-умолчанию. + points = 10; + + pickUp() { + // Этот метод может быть вызван вашим игроком, когда он встречает бонус + collectedPoints += this.points; + this.actor.destroy(); + } + +} +Sup.registerBehavior(BonusBehavior); + +let bigBonusActor = new Sup.Actor("Big Bonus"); +// ... возможно настроить спрайт или рендерер модели ... + +// Это большой бонус, поэтому мы переопределяем его значение в 50. +bigBonusActor.addBehavior(BonusBehavior, { points: 50 }); +``` diff --git a/pages/ru/1_getting-started/8_components.md b/pages/ru/1_getting-started/8_components.md new file mode 100644 index 0000000..26b3c13 --- /dev/null +++ b/pages/ru/1_getting-started/8_components.md @@ -0,0 +1,23 @@ +# Компоненты доступа + +Большинство типов компонентов предоставляют свойство аксессора, чтобы вы могли изменить их состояние. + +Например, средства отображения спрайтов отображаются на актерах как свойство `spriteRenderer`: + +``` +class MyBehavior extends Sup.Behavior { + + update() { + // Когда клавиша пробела только что была нажата + if (Sup.Input.wasKeyJustPressed("SPACE")) { + // Воспроизвести анимацию на рендере спрайтов + // актера к которому это поведение прилагается. + this.actor.spriteRenderer.setAnimation("Wave"); + } + } + +} +Sup.registerBehavior(MyBehavior); +``` + +Вы можете найти список всех аксессоров в API браузере внутри Superpowers, в разделе `Sup.Actor`. \ No newline at end of file diff --git a/pages/ru/1_getting-started/9_debugging-your-game.md b/pages/ru/1_getting-started/9_debugging-your-game.md new file mode 100644 index 0000000..60ff6c3 --- /dev/null +++ b/pages/ru/1_getting-started/9_debugging-your-game.md @@ -0,0 +1,25 @@ +# Отладка вашей игры + +При использовании Superpowers из приложения, Вы можете открыть инструменты отладки, нажав на кнопку `Debug game` (или нажав `F6`). Большинство браузеров позволяют открывать похожие инструменты отладки, по клавише `F12` при запущенной игре. + +Поскольку Superpowers app построен на NW.js, который основан на Chrome рантайм, встроенные средства отладки тоже есть в Chrome. + +Две основные вкладки, которые вам понадобятся при запуске:: + + * Вкладка `Console` , который предоставляет отчеты об ошибках во время выполнения и будет содержать результат любого вызова `Sup.log`. + + * Вкладка `Sources` , где вы найдете свои скрипты, а также весь движок, приводящий в действие вашу игру. + +## Отладка и проверка состояния вашей игры + +
+

Проверьте [этот обзор Chrome DevTools](https://developer.chrome.com/devtools) а также [это введение в отладку JavaScript](https://developer.chrome.com/devtools/docs/javascript-debugging). Не смотря на то что Superpowers на самом деле использует TypeScript, это надмножество JavaScript поэтому большая часть информации там должна применяться. +

+ +С открытым отладчиком вы можете использовать `Ctrl+P` и введите имя одного из ваших активов скрипта, чтобы перейти непосредственно к нему. [Поместите точку останова](https://developer.chrome.com/devtools/docs/javascript-debugging#add-remove-breakpoints) в методе `update` поведения, например, и ваша игра остановится, как только она снова достигнет этой строки. + +При достижении точки останова на правой панели отобразится `Call Stack` (показывающий, как ваша игра достигла текущей функции / метода, например бредкрамбс) так же как `Scope Variables`, позволяя вам проверить содержимое всех доступных в настоящее время переменных. + +`F10` позволяет сделать шаг вперед по одной инструкции за раз (полезно, если вы хотите проверить детали функции по одному шагу за раз), пока `F8` возобновит выполнение игры. + +Вы можете захотеть [включить "Pause on uncaught exceptions"](https://developer.chrome.com/devtools/docs/javascript-debugging#pause-on-uncaught-exceptions) так что ваша игра автоматически остановится на определенной строке, возникнет ошибка во время выполнения и позволит вам проверить стек вызовов и состояние программы. Это действует только тогда, когда отладчик открыт. diff --git a/pages/ru/1_getting-started/index.md b/pages/ru/1_getting-started/index.md new file mode 100644 index 0000000..69a5d54 --- /dev/null +++ b/pages/ru/1_getting-started/index.md @@ -0,0 +1 @@ +# Getting started diff --git a/pages/ru/2_tutorials/10_dom-apis.md b/pages/ru/2_tutorials/10_dom-apis.md new file mode 100644 index 0000000..5863ebc --- /dev/null +++ b/pages/ru/2_tutorials/10_dom-apis.md @@ -0,0 +1,24 @@ +# Используем DOM APIs + +## Почему Superpowers не выставляет DOM API по умолчанию? + +DOM API - это стандартные функции и объекты, доступные для сценариев в веб-браузере. +Они включают в себя такие вещи, как объекты `window` или `document` , `XMLHttpRequest` и т.п. + +Мы решили защитить игры Superpowers от всего этого по умолчанию по двум причинам.: + + * First, because Superpowers often provides higher-level alternatives that are simpler to use and work great together. + For instance, Superpowers provides the `Sup.Storage` API to replace the DOM's `window.localStorage` API. + + * Second, because it leaves the door open to one day provide an alternative runtime that doesn't involve a Web browser context. + There could be an optimized native player, for instance. It's not something we're actively pursuing though. + +## Как их использовать в любом случае + +The good news is, you can still choose to access the DOM anyway. +You could just do a one-off `declare var window;` at the top of your first script +and then use the APIs untyped with `new window.XMLHttpRequest(...);` for instance. + +If you use it a lot though, having proper type checks would be useful. +Thankfully, Florent Poujol has written a [Superpowers DOM plugin](https://github.com/florentpoujol/superpowers-dom-plugin) +that will expose all the typed APIs for you. diff --git a/pages/ru/2_tutorials/1_typescript-primer.md b/pages/ru/2_tutorials/1_typescript-primer.md new file mode 100644 index 0000000..6bac030 --- /dev/null +++ b/pages/ru/2_tutorials/1_typescript-primer.md @@ -0,0 +1,164 @@ +# TypeScript primer + +Superpowers scripts пишут на TypeScript. +Это удобный, мощный язык с запутанной историей. + +Вот некоторая предыстория и введение, чтобы вы начали. + +## От JavaScript к TypeScript + +JavaScript это [причудливый, некорректный язык](https://www.destroyallsoftware.com/talks/wat) это недавно становилось намного лучше. +Это на самом деле стандартизировано под названием ECMAScript, по сложным причинам. +Последняя версия JavaScript, ECMAScript 2015 (ранее известный как ECMAScript 6), исправляет многие разочарования, которые были у людей, и добавляет множество новых функций. + +Это [собирается занять год или два](https://kangax.github.io/compat-table/es6/) для всех этих улучшений, чтобы пробиться в браузеры. +В это время, Web разработчики создали различные инструменты, такие как [Babel.js](https://babeljs.io/) +или такие языки, как [TypeScript](http://www.typescriptlang.org/), [Flow](http://flowtype.org/) и [CoffeeScript](http://coffeescript.org/) +это позволяет вам прямо сейчас использовать новые языковые функции и автоматически переписывает («переносит») ваши скрипты до ECMAScript 5, версии JavaScript, поддерживаемой в настоящее время браузерами. + +## почему TypeScript? + +Мы специально выбрали TypeScript, потому что это типизированное надмножество последней версии JavaScript. Это означает две вещи: + + * При создании игр в Superpowers, миллионы Web разработчиков могут повторно использовать свои с трудом заработанные знания JavaScript. + * TypeScript's мощная и быстрая система типов позволяет Superpowers предоставлять отчеты об ошибках в реальном времени и отличное автозаполнение. + +![](http://i.imgur.com/vnJU8Tt.gif) + +В качестве дополнительного бонуса разработчики TypeScript работают со стандартным комитетом, чтобы сообщить дизайн будущих версий JavaScript, +так что это отличное вложение. + +## Блочные переменные + +
+ Если вы не знаете слишком много о переменных или функциях, вам, вероятно, следует [познакомиться с JavaScript](http://www.codecademy.com/en/tracks/javascript). +
+ +ES2015 позволяет объявлять блочные переменные с помощью нового ключевого слова let. +Как правило, вам больше не следует использовать старое ключевое слово `var`, которое имеет менее удобную семантику в функциональной области. + +``` +// myVariable не существует здесь + +if (someCondition) { + // myVariable здесь нельзя получить доступ (до его объявления) + let myVariable = 10; + // myVariable живет до закрытия блока +} + +// myVariable здесь тоже не существует +// Все эти комментарии были бы ложными, если бы вы использовали вместо этого `var`. +``` + +## Типизированные переменные и функции + +При объявлении переменной TypeScript может определить ее тип по значению, которое вы ей присваиваете.: + +``` +let myVariable = 10; // myVariable's type is `number` + +// TypeScript вернет ошибку, если вы сделаете неправильные вещи, такие как добавление числа и строки +myVariable += "a string"; +``` + +Вы можете явно определить тип переменной, даже если вы не инициализируете ее сразу: + +``` +let myVariable: string; // Тип myVariable это `string`, с` undefined` в качестве начального значения +``` + +При объявлении функции вы можете аннотировать ее параметры и возвращать тип: + +``` +function repeat(what: string, times: number): string { + let result = ""; + for (let i = 0; i < times; i++) result += what; + return result; +} + +let coolThrice = repeat("cool", 3); // This will return "coolcoolcool" +repeat(3, "cool"); // Error, because of the incorrect argument types +``` + +Во многих случаях TypeScript также может выводить тип возвращаемого значения функции на основе возвращаемого значения. + +Superpowers сможет даже автозаполнение `repeat` для вас и отображать свою сигнатуру (параметры и тип возвращаемого значения). + +[Узнайте больше о типах](http://www.typescriptlang.org/Handbook#basic-types). + +## Классы + +ES5 имелось только наследование на основе прототипов, которое довольно гибкое, но трудное как для записи, так и для чтения. +ES2015 приносит классы для более традиционной объектно-ориентированной парадигмы, а TypeScript еще раз дополняет их мощной проверкой типов. + +Вот посмотрите на синтаксис: + +``` +class Lift { + + // TypeScript позволяет вам объявить членов и их тип + floor: number; + + // Вы можете использовать значения параметров по умолчанию + constructor(initialFloor=1) { + this.floor = initialFloor; + } + + goUp() { + if (this.floor < 10) this.floor++; + } + + goDown() { + if (this.floor > 0) this.floor--; + } +} + +let myLift = new Lift(); +myLift.goUp(); // myLift.floor is now 2 +``` + +[Узнайте больше о TypeScript классах](http://www.typescriptlang.org/Handbook#classes). + +## Лучшие анонимные функции + +В ECMAScript 5 при передаче функции в качестве обратного вызова другой функции вам приходилось немного танцевать +задействуя `Function.bind`, чтобы убедиться, что значение` this` было сохранено. + +В ECMAScript 2015, Теперь вы можете использовать новый синтаксис жирной стрелки `() =>` ("lambdas") +это сохранит `this` автоматически. + +``` +// Предполагая, что мы находимся в некотором контексте, где `this` имеет свойство` save`. +this.saving = true; + +// В этом примере `saveToDisk` будет длительной асинхронной функцией +saveToDisk(() => { + // `this` все тот же. С `function() { ... }`, у тебя нет гарантии + this.saving = false; +}); +``` + +C классами ECMAScript 2015, методы также сохраняют значение `this` для вас. + +[Узнайте больше о лямбдах и `this`](http://www.typescriptlang.org/Handbook#functions-lambdas-and-using-39this39). + +## Перебор массивов + +Другая давняя проблема JavaScript заключается в переборе массивов. + +``` +let myArray = [ 100, 10, 1 ]; + +// С ECMAScript 2015's новое ключевое слово `of`, это просто +for (let value of myArray) console.log(value); + +// Ранее вы бы написали: +// for (var i = 0; i < myArray.length; i++) console.log(myArray[i]); +``` + +## Learning more + + * [Codecademy's JavaScript course](http://www.codecademy.com/en/tracks/javascript) + * [Learning ES6](https://github.com/ericdouglas/ES6-Learning) + * [es6-features.org](http://es6-features.org/) + * [TypeScript Handbook](http://www.typescriptlang.org/Handbook) diff --git a/pages/ru/2_tutorials/2_input.md b/pages/ru/2_tutorials/2_input.md new file mode 100644 index 0000000..a8987db --- /dev/null +++ b/pages/ru/2_tutorials/2_input.md @@ -0,0 +1,100 @@ +# Клавиши, мышки, геймпады... + +Все входные функции можно найти в `Sup.Input` namespace. + +## Проверка, была ли нажата какая-либо клавиша + +Вы можете передать специальные значения `"ANY"` и `"NONE"` в `Sup.Input.wasKeyJustPressed()` (и другие подобные функции) выяснить, была ли нажата какая-либо клавиша в течение последнего кадра. + +Полный список имен клавиш можно найти в браузере TypeScript API внутри Superpowers. + +## Работа с геймпадами + +The Web APIs have some quirks stemming from the fact that the browser must not +give too much control or information to random websites. For instance, +to avoid user fingerprinting, the Web doesn't let you list all connected gamepads. +You'll need to ask the user to press a button to use their gamepad. + +You can use [HTML5gamepad.com's test tool](http://html5gamepad.com/) +to find out how gamepad buttons are mapped to indices. + +## Mouse coordinates + +`Sup.Input.getMousePosition()` возвращет нормалитзованные `x` и `y` координаты (в диапазоне `-1` to `1`), где `y` увеличивается при движении мыши вверх. + +Если вам нужны пиксельные координаты, вы можете использовать следующий фрагмент для преобразования: + +``` +let { x, y } = Sup.Input.getMousePosition(); + +x = (x + 1) / 2 * Sup.Input.getScreenSize().x; +y = (1 - (y + 1) / 2) * Sup.Input.getScreenSize().y; +``` + +Скачайие [пример проекта](https://bitbucket.org/sparklinlabs/superpowers-mouse-pixels/) для демо. + +## Блокировка мыши и переход в полноэкранный режим + +`Sup.Input.lockMouse()` позволяет отключить указатель мыши. Отлично подходит для игр от первого лица с мышью. + +`Sup.Input.goFullscreen()` можно использовать для перехода в полноэкранный режим. + +Как и в случае с геймпадами, по соображениям безопасности веб-игра не может блокировать указатель мыши или работать в полноэкранном режиме по желанию, а только как часть обратного вызова события щелчка мышью или аналогичного пользовательского ввода. Superpowers абстрагирует эти ограничения от вашей игры, позволяя вам вызвать `.lockMouse` и `.goFullscreen` в любой момент времени, но знайте, что фактическое действие будет отложено до следующего нажатия или отпускания кнопки мыши. + +Полезный шаблон - установить блокировку мыши или полноэкранный режим, когда кнопка мыши только что была нажата, и Superpowers будет эффективно применять это действие в своем обработчике события, выпущенного внутренней кнопкой мыши: + +``` +if (Sup.Input.wasMouseButtonJustPressed(0)) { + Sup.Input.lockMouse(); +} +``` + +В браузере игрок также может выйти из полноэкранного режима или разблокировать указатель мыши в любой момент времени, нажав клавишу «Escape». Superpowers автоматически повторно заблокирует мышь и / или переключится обратно в полноэкранный режим, как только пользователь вернется в игру, пока вы явно не вызовете `Sup.unlockMouse ()` и / или `Sup.exitFullscreen ()`. + +Возможно, вы захотите приостановить игру, когда блокировка мыши или полноэкранный режим были приостановлены. +Для этого вы можете использовать обработчик событий следующим образом: + +``` +class MyBehavior extends Sup.Behavior { + + awake() { + Sup.Input.on("mouseLockStateChange", this.onLockChange); + // Для монитора в полноэкранном режиме событие должно быть «fullscreenStateChange» + } + + onDestroy() { + // Важно, чтобы вы очистили свои обработчики событий + // когда поведение разрушается (что происходит + // например, при переключении на другую сцену), + // в противном случае это может привести к утечке памяти или ошибкам + Sup.Input.off("mouseLockStateChange", this.onLockChange); + } + + onLockChange(state) { + if (state === "suspended") { + // Блокировка была приостановлена + // ... игра на апаузе ... + } else { + // Блокировка была возобновлена (state is "active") + // ... возобновление игры ... + } + } + +} +Sup.registerBehavior(MyBehavior); +``` + +## Ввод текста + +Вы можете получить текст, введенный в течение последнего обновления с `Sup.Input.getTextEntered()`. Вы можете зациклить это так: + +``` +for (let character of Sup.Input.getTextEntered()) { + if (character === "\b") { /* Backspace был нажат, возможно стереть последний символ */ } + else { /* Введен другой символ, добавьте его в свой текст */ } +} +``` + +![](http://i.imgur.com/MWG8yPe.gif) + +See the [демонстрационный проект ввода текста](https://bitbucket.org/sparklinlabs/superpowers-text-input-demo/src). diff --git a/pages/ru/2_tutorials/3_cameras.md b/pages/ru/2_tutorials/3_cameras.md new file mode 100644 index 0000000..795ab97 --- /dev/null +++ b/pages/ru/2_tutorials/3_cameras.md @@ -0,0 +1,52 @@ +# Камеры, вьюпорты и UI + +## Перспектива против Орфографии + +Камера может находиться в режиме перспективного или ортографического проецирования.. + +![](/images/cameras/camera-modes.png) + +При использовании перспективной проекции объекты, находящиеся дальше от камеры, будут выглядеть меньше, как в реальной жизни. +Это отлично подходит для большинства 3D-игр. И наоборот, ортографическая проекция лучше всего подходит для 2D или 3D-изометрических игр, +а также 2D пользовательские интерфейсы в 3D играх. + +### Настройка перспективной камеры + +![](/images/cameras/perspective-settings.png) + + `Field of view` (FOV) определяет, насколько широко угол зрения ваша камера будет видеть вертикально. +Результирующее горизонтальное поле зрения будет зависеть от соотношения окна игры (Вы можете установить фиксированное соотношение, например, 16: 9, в настройках своего проекта на панели настроек `Game`). + +### Настройка орфографической камеры + +![](/images/cameras/orthographic-settings.png) + +The `Orthographic Scale` controls the vertical extent of what your camera will look at, in scene units. +Just like for the field of view, the horizontal extent will depend on the game window's ratio. + +### Other settings + +The `Near` and `Far plane` control the extent of the camera's [viewing frustum](https://en.wikipedia.org/wiki/Viewing_frustum). +When rendering a 3D object, your GPU stores and compares the depth of any previously rendered object for each of the pixels +occupied on screen to determine whether the object is occluded or not. + +## Рендеринг с несколькими камерами + +You can set up a camera's `Viewport` so that it renders only to an area of the game's window. This is useful for split-screen multiplayer games, for instance. +The values should be in the 0-1 range. + +The `Depth` setting is used to order cameras when multiple viewports are overlapping. Cameras with higher depth values will appear in front. + +## Слои + +Render layers позволяет рендерить только некоторых актеров для данной камеры. +Вы можете настроить слои своей игры на панели `Game` в `Settings`. +Затем вы можете выбрать, какой слой (слои) должна отображать камера.. + +Это может быть использовано для создания орфографической камеры, которая воспроизводит только актеров, связанных с пользовательским интерфейсом, +в то время как основная камера делает все остальное. + +
+ **Настройка слоев камеры еще не реализована** as of Superpowers v0.12. + До тех пор, пока это не так, рекомендуемый (и хакерский) способ создания пользовательского интерфейса - это перемещение камеры пользовательского интерфейса и ее актеров далеко на одной оси. +
diff --git a/pages/ru/2_tutorials/4_3d-models.md b/pages/ru/2_tutorials/4_3d-models.md new file mode 100644 index 0000000..d9dff3d --- /dev/null +++ b/pages/ru/2_tutorials/4_3d-models.md @@ -0,0 +1,76 @@ +# Работа с 3D моделями + +## Importing models + +Superpowers поддерживает пока подмножество OBJ (static) и glTF (анимированный) форматы файлов. + +
+ На данный момент для каждой модели поддерживается только одна диффузная карта.. + Material and shader support is coming soon. +
+ +### Анимированные glTF модели + +glTF это новый формат поддерживаемый Khronos Group (люди стоящие за OpenGL и Vulkan). +Большинство инструментов сейчас не имеют встроенной поддержки, так что вам нужно будет экспортировать COLLADA а затем использовать [конвертер COLLADA2glTF](https://github.com/KhronosGroup/glTF/wiki/Converter-builds). + +Следующие инструкции предполагают, что вы используете Blender, но другие инструменты должны работать аналогично. + +
+

Убедитесь, что у вас есть одна сетка и один материал. Ваша сетка должна быть связана с арматурой и находиться в начале координат (0,0,0). +

+ +
+

Убедитесь, что ваша модель находится в позе привязки без активных действий.
+ Из меню `File` , выберите `Export > Collada (Default) (.dae)`.
+ Отметьте `Triangulate`. + +

Перетащите получившийся `.dae` файл в [COLLADA2glTF конвертер](https://github.com/KhronosGroup/glTF/releases)'s executable.
+ Вы получите несколько файлов, мы заботимся только о `.gltf` и `.bin` . + +

Повторите процесс для каждого действия, которое вы хотите экспортировать, предварительно сделав его активным.. +

+ +Теперь давайте импортируем модель в Superpowers. Вы можете найти пример модели в [Superpowers asset packs](https://github.com/sparklinlabs/superpowers-asset-packs/tree/master/3d-character/character/animation/bind-pose). + +
+

Создайте 3D Model asset и кликните `Upload` .
+ Выделите оба файла и `.gltf` и `.bin` сразу в диалоге выбора файла (удерживая `Ctrl` можно выделить несколько файлов Windows). + +

Используйте кнопку `New` для создания анимации и загрузки ее по кнопке `Upload` . +

+ +![](http://i.imgur.com/niveyoP.gif) + +## Прикрепление предмета к руке персонажа + +Довольно просто прикрепить объект к анимированной кости, будь то оружие, +шляпа или рюкзак. + +Просто используйте `Sup.ModelRenderer.getBoneTransform` чтобы получить текущую глобальную позицию и ориентацию кости и применить ее к актору который вы хотите присоединить. + +``` +class CharacterHandBehavior extends Sup.Behavior { + + itemActor: Sup.Actor; + + awake() { + // настраивайте `this.itemActor` здесь + // или при создании CharacterHandBehavior + } + + update() { + let handTransform = this.actor.modelRenderer.getBoneTransform("Left Hand"); + + this.itemActor.setPosition(handTransform.position); + this.itemActor.setOrientation(handTransform.orientation); + } +} +Sup.registerBehavior(CharacterHandBehavior); +``` + +Вот небольшая демонстрация. Вы можете скачать [the source project](https://bitbucket.org/sparklinlabs/superpowers-model-demo/) и запустить его для себя. + +![](http://i.imgur.com/gep1b6u.gif) + +Если элемент не подходит, вы можете добавить смещение с помощью `this.itemActor.moveOriented(...)` или `this.itemActor.rotateLocalEulerAngles(...)`. diff --git a/pages/ru/2_tutorials/5_audio.md b/pages/ru/2_tutorials/5_audio.md new file mode 100644 index 0000000..62bbea3 --- /dev/null +++ b/pages/ru/2_tutorials/5_audio.md @@ -0,0 +1,77 @@ +# Sounds and music + +
+ **Heads up!** `Sup.Audio.SoundInstance` was renamed to `Sup.Audio.SoundPlayer` in Superpowers v0.12, for clarity. +
+ +## Playing a sound effect + +Playing a one-shot sound effect is very straightforward: + +``` +// Just play the sound! +Sup.Audio.playSound("My Sound Asset"); + +// Or, play the sound at half volume +Sup.Audio.playSound("My Sound Asset", 0.5); +``` + +You can control pitch, pan (anywhere between -1.0 for left, 1.0 for right) and whether to loop: + +``` +let player = Sup.Audio.playSound("My Sound Asset", 0.5, { pitch: 0.5, pan: -1, loop: true }); + +// Later on, you can stop the sound with: +player.stop(); +``` + +### Creating a sound player for later usage + +If you want to create a sound without playing it right away, +you can use the `Sup.Audio.SoundPlayer` constructor. + +``` +let sfxPlayer = new Sup.Audio.SoundPlayer("My Sound Asset"); + +// Set it up how you wish +sfxPlayer.setVolume(0.8); + +// ... Later on ... +sfxPlayer.play(); +``` + +## Looping background music (or a machine gun...) + +For looping sound effects or music, you'll want to hold onto the sound player +so that you can stop playback later on. + +For instance, you can put this at the root of a script: + +``` +let inGameMusicPlayer = new Sup.Audio.SoundPlayer("In-Game Music", 1.0, { loop: true }); + +// ... When entering the game, from some behavior ... +inGameMusicPlayer.play(); + +// ... When returning to the menu ... +inGameMusicPlayer.stop(); +``` + +And if you have multiple actors with each their own looping sound effect when they shoot, +you can store the sound player as a member variable of their behavior, like so: + +``` +class SoldierBehavior { + sfxPlayer = new Sup.Audio.SoundInstance("Shoot", 1.0, { loop: true }); + + update() { + if (/* some condition for shooting */) { + // If the sound is already playing, play() does nothing so we can call it repeatedly + this.sfxPlayer.play(); + } else { + this.sfxPlayer.stop(); + } + } +}; +Sup.register(SoldierBehavior); +``` diff --git a/pages/ru/2_tutorials/6_storage.md b/pages/ru/2_tutorials/6_storage.md new file mode 100644 index 0000000..30a9f6f --- /dev/null +++ b/pages/ru/2_tutorials/6_storage.md @@ -0,0 +1,99 @@ +# Saving game data + +Вы можете использовать `Sup.Storage.get` и `.set` чтобы сохранять и восстанавливать строки данных. +Эти данные сохраняются локально на диске игрока. + +``` +// ... Когда игрок выбирает имя +Sup.Storage.set("characterName", "Leonard"); + +// ... При загрузке игры снова позже +let characterName = Sup.Storage.get("characterName"); +``` + +Вы также можете передать значение по умолчанию в качестве второго параметра `Sup.Storage.get`. +Будет возвращено, если для запрошенного ключа не найдено значение. + +``` +let characterName = Sup.Storage.get("characterName", "Unnamed"); +``` + +Кроме того, `Sup.Storage.clear` позволяет вам очистить все сохраненные данные для вашей игры. + +
+ Internally, Superpowers uses the [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API) so it has the same browser-dependent size limitations. Лучше всего подходит для небольших объемов данных.. В любом случае, вам, вероятно, не следует использовать его для хранения более нескольких мегабайт данных, поскольку он является синхронным и заблокирует игру во время сохранения или загрузки. +
+ +## Хранить больше, чем строки + +Для хранения и извлечения чисел, массивов или сложных объектов вы можете использовать `Sup.Storage.setJSON` и `.getJSON`. +Внутренне, он будет (де) сериализовать их, используя `JSON.stringify` и `.parse`. + +``` +let weapon = { + name: "Hand blender", + damage: 9001, + mode: "manual" +}; + +Sup.Storage.setJSON("weapon", weapon); + +// ... Later +let weapon = Sup.Storage.getJSON("weapon"); +``` + +Информация о классе не сохраняется, только различные свойства. Так, например, если вы храните `Sup.Math.Vector2` object, +вы получите только объект типа `{ x: number; y: number; }` и вам нужно будет восстановить вектор из него. + +## Saving on exit + +You can use a `Sup.Input` `"exit"` event handler to automatically save when the game closes. + +``` +Sup.Input.on("exit", () => { + Sup.Storage.set("key", value); +}); +``` + +## Storage demo + +This simple demo lets you move around a sprite and automatically saves its position when the game is closed. + +You can [download the demo project](https://bitbucket.org/sparklinlabs/superpowers-storage-demo). + +``` +class CharacterBehavior extends Sup.Behavior { + speed = 0.1; + + update() { + if (Sup.Input.isKeyDown("LEFT")) this.actor.moveX(-this.speed); + if (Sup.Input.isKeyDown("RIGHT")) this.actor.moveX(this.speed); + if (Sup.Input.isKeyDown("UP")) this.actor.moveY(this.speed); + if (Sup.Input.isKeyDown("DOWN")) this.actor.moveY(-this.speed); + + if (Sup.Input.isKeyDown("ESCAPE")) this.actor.setPosition(0, 0, 0); + } +} +Sup.registerBehavior(CharacterBehavior); + + +// Setup our character and camera +let actor = new Sup.Actor("Character"); +new Sup.SpriteRenderer(actor, Sup.get("Sprite", Sup.Sprite)); +actor.addBehavior(CharacterBehavior); + +let cameraActor = new Sup.Actor("Camera"); +new Sup.Camera(cameraActor); +cameraActor.setLocalPosition(0, 0, 10); + + +// Save character position on exit +Sup.Input.on("exit", () => { + Sup.Storage.setJSON("myCharacterPosition", { x: actor.getX(), y: actor.getY() }); +}); + + +// Restore saved character position on load +let savedPosition = Sup.Storage.getJSON("myCharacterPosition", { x: 0, y: 0 }); +actor.setPosition(savedPosition.x, savedPosition.y, 0); +``` diff --git a/pages/ru/2_tutorials/7_collision-2d.md b/pages/ru/2_tutorials/7_collision-2d.md new file mode 100644 index 0000000..8d8a85d --- /dev/null +++ b/pages/ru/2_tutorials/7_collision-2d.md @@ -0,0 +1,254 @@ +# Основные столкновения в 2D + +Столкновение часто сложно настроить. +Superpowers поставляется с плагином ArcadePhysics2D чтобы облегчить общие вещи. +Он не идеален, но делает достойную работу и очень быстро настраивается при создании прототипа игры.. + +Плагин добавляет новый тип компонента в scene editor,предлагая два типа тел: + +## Тип тела box + +Тип тел `Box` позволяет определить бокс с определенным размером и смещением. + +![](/images/2d-collision/collision-box.png) + +Обязательно снимите флажок `Movable` для объектов, которые должны быть статичными. + +## тип тела Tile map + +Тип тел `Tile Map` позволяет столкновения с tile map. + +По умолчанию любая непустая плитка сталкивается с другими телами. Вы можете установить имя свойства в `Tile Set Property` ограничить столкновения с плитками, которые имеют это конкретное свойство. Вы можете установить эти свойства плитки в редакторе набора плиток.. + +Вы также можете указать список разделенных запятыми индексов слоев, которые должны сталкиваться. Например, вы можете установить слой `0` как слой столкновения, и другие слои будут игнорироваться. + +![](/images/2d-collision/collision-map.png) + +
+ Масштаб актера не учитывается. Вы должны оставить его равным 1 и вместо него использовать анстройку `Pixels / unit` карты. +
+ +## Заставить вещи сталкиваться + +Чтобы ваш персонаж сталкивался с окружающей средой, вы должны поместить следующий код в обновление поведения, прикрепленного к нему: + +``` +Sup.ArcadePhysics2D.collides(this.actor.arcadeBody2D, Sup.ArcadePhysics2D.getAllBodies()); +``` + +Второй аргумент функции - это список тел. В этом случае мы используем все из них, но вы также можете вести свой список списков. + +
+ Посольку функция ArcadePhysics2D's `.collides` обновит позицию вашего актера при обработке столкновений, **вы не можете использовать `.move` или `.setPosition` напрямую больше**. + + Если вам нужно телепортировать вашего актера, используйте `this.actor.arcadeBody2D.warpPosition(...)`. +
+ +Вместо этого, получите текущую скорость тела с `this.actor.arcadeBody2D.getVelocity()`, обновите ее `.x` или `.y` компоненту и затем примените ее обратно `this.actor.arcadeBody2D.setVelocity(...)`. + +## Сборка простого платформера + +
+ Во-первых, вам нужно настроить гравитацию. +
+ +``` +Sup.ArcadePhysics2D.setGravity(0, -0.02); +``` + +Довольно просто, правда? + +
+ Чтобы управлять своим персонажем, создайте сценарий поведения с именем `Player Behavior`. +
+ +``` +class PlayerBehavior extends Sup.Behavior { + speed = 0.3; + jumpSpeed = 0.45; + + update() { + Sup.ArcadePhysics2D.collides(this.actor.arcadeBody2D, Sup.ArcadePhysics2D.getAllBodies()); + + // Как объяснено выше, мы получаем текущую скорость + let velocity = this.actor.arcadeBody2D.getVelocity(); + + // Мы перезаписываем компонент `.x` на основе ввода игрока + if (Sup.Input.isKeyDown("LEFT")) velocity.x = -this.speed; + else if (Sup.Input.isKeyDown("RIGHT")) velocity.x = this.speed; + else velocity.x = 0; + + // Если игрок на земле и хочет прыгать, + // мы обновляем компоненту `.y` соответственно + let touchBottom = this.actor.arcadeBody2D.getTouches().bottom; + if (touchBottom && Sup.Input.wasKeyJustPressed("UP")) velocity.y = this.jumpSpeed; + + //Наконец, мы применяем скорость обратно к телу ArcadePhysics + this.actor.arcadeBody2D.setVelocity(velocity); + } +} +Sup.registerBehavior(PlayerBehavior); +``` + +`.getTouches()` возвращает контактную информацию для каждой стороны корпуса коробки. Мы используем его, чтобы убедиться, что игрок на земле, прежде чем позволить им прыгать. + +## Улучшим то как все выглядит + +Чтобы он выглядел лучше, давайте добавим анимацию и перевернем спрайт игрока в зависимости от направления движения.. + +Мы будем использовать методы `.setAnimation` и `.setHorizontalFlip` на рендере спрайта, чтобы сделать это. + +``` +class PlayerBehavior extends Sup.Behavior { + speed = 0.3; + jumpSpeed = 0.45; + + update() { + Sup.ArcadePhysics2D.collides(this.actor.arcadeBody2D, Sup.ArcadePhysics2D.getAllBodies()); + + // Как объяснено выше, мы получаем текущую скорость + let velocity = this.actor.arcadeBody2D.getVelocity(); + + // Мы перекрываем компоненту `.x` на основе ввода игрока + if (Sup.Input.isKeyDown("LEFT")) { + velocity.x = -this.speed; + // Идя налево, мы переворачиваем спрайт + this.actor.spriteRenderer.setHorizontalFlip(true); + } else if (Sup.Input.isKeyDown("RIGHT")) { + velocity.x = this.speed; + //Когда идем направо, мы очищаем флип + this.actor.spriteRenderer.setHorizontalFlip(false); + } else velocity.x = 0; + + // Если игрок находится на земле и хочет прыгнуть, + // обновляем его `.y` cкомпоненту + let touchBottom = this.actor.arcadeBody2D.getTouches().bottom; + if (touchBottom) { + if (Sup.Input.wasKeyJustPressed("UP")) { + velocity.y = this.jumpSpeed; + this.actor.spriteRenderer.setAnimation("Jump"); + } else { + // Здесь мы должны играть либо "Idle" либо "Run" в зависимости от горизонтальной скорости + if (velocity.x === 0) this.actor.spriteRenderer.setAnimation("Idle"); + else this.actor.spriteRenderer.setAnimation("Run"); + } + } else { + // Здесь мы должны играть либо "Jump" либо "Fall" в зависимости от вертикальной скорости + if (velocity.y >= 0) this.actor.spriteRenderer.setAnimation("Jump"); + else this.actor.spriteRenderer.setAnimation("Fall"); + } + + // Finally, we apply the velocity back to the ArcadePhysics body + this.actor.arcadeBody2D.setVelocity(velocity); + } +} +Sup.registerBehavior(PlayerBehavior); +``` + +Мы выбираем анимацию для воспроизведения в зависимости от скорости игрока и от того, касаемся ли мы земли или нет. + +## Идем дальше + +Одна вещь, которую вы, вероятно, захотите добавить, это односторонние платформы: платформы, через которые вы можете прыгать снизу. + +Для этого мы начнем с создания двух групп актеров на сцене.. + +![](/images/2d-collision/scene.png) + +У нас будет группа для твердых тел, содержащая карту и T-Rex, и еще одна для наших односторонних платформ. +Вот как это выглядит в коде. + +``` +Sup.ArcadePhysics2D.setGravity(0, -0.02); + +class PlayerBehavior extends Sup.Behavior { + speed = 0.3; + jumpSpeed = 0.45; + + solidBodies: Sup.ArcadePhysics2D.Body[] = []; + platformBodies: Sup.ArcadePhysics2D.Body[] = []; + + awake() { + // Мы получаем и храним все тела в двух массивах, по одному для каждой группы. + let solidActors = Sup.getActor("Solids").getChildren(); + for (let solidActor of solidActors) this.solidBodies.push(solidActor.arcadeBody2D); + let platformActors = Sup.getActor("Platforms").getChildren(); + for (let platformActor of platformActors) this.platformBodies.push(platformActor.arcadeBody2D); + } + + update() { + // Сначала проверим на столкновение с твердыми телами. + Sup.ArcadePhysics2D.collides(this.actor.arcadeBody2D, this.solidBodies); + let touchSolids = this.actor.arcadeBody2D.getTouches().bottom; + let velocity = this.actor.arcadeBody2D.getVelocity(); + + // Затем мы проверим на столкновение с односторонними платформами, + // ... но только при падении! Вот и вся хитрость. + let touchPlatforms = false; + if (velocity.y < 0) { + let position = this.actor.getLocalPosition(); + // Мы должны изменить размер тела игрока, чтобы проверялись только ноги + // Для этого мы уменьшаем высоту тела и адаптируем смещение + this.actor.arcadeBody2D.setSize(1.5, 0.4); + this.actor.arcadeBody2D.setOffset({ x: 0, y: 0.2 }); + // Затем мы переопределяем положение тела, используя текущую позицию актера. + this.actor.arcadeBody2D.warpPosition(position); + + // Теперь проверьте по каждой платформе + for (let platformBody of this.platformBodies) { + Sup.ArcadePhysics2D.collides(this.actor.arcadeBody2D, platformBody); + if (this.actor.arcadeBody2D.getTouches().bottom) { + touchPlatforms = true; + velocity.y = 0; + break; + } + } + + // После того, как сделано, сбросьте тело до его полного размера + position = this.actor.getLocalPosition(); + this.actor.arcadeBody2D.setSize(1.5, 1.8); + this.actor.arcadeBody2D.setOffset({ x: 0, y: 0.9 }); + this.actor.arcadeBody2D.warpPosition(position); + } + + // Мы перезаписываем компонент скорости .x на основе ввода игрока + if (Sup.Input.isKeyDown("LEFT")) { + velocity.x = -this.speed; + // Идя налево, мы должны флипнуть спрайт + this.actor.spriteRenderer.setHorizontalFlip(true); + } else if (Sup.Input.isKeyDown("RIGHT")) { + velocity.x = this.speed; + // При движении вправо мы отменяем флип + this.actor.spriteRenderer.setHorizontalFlip(false); + } else velocity.x = 0; + + // Если игрок на земле и хочет прыгать, + // мы соответственно обновляем компонент скорости `.y` + let touchBottom = touchSolids || touchPlatforms; + if (touchBottom) { + if (Sup.Input.wasKeyJustPressed("UP")) { + velocity.y = this.jumpSpeed; + this.actor.spriteRenderer.setAnimation("Jump"); + } else { + // Здесь мы должны сыграть либо «холостой ход», либо «бег» в зависимости от горизонтальной скорости + if (velocity.x === 0) this.actor.spriteRenderer.setAnimation("Idle"); + else this.actor.spriteRenderer.setAnimation("Run"); + } + } else { + // Здесь мы должны играть либо «Прыжок», либо «Падение» в зависимости от вертикальной скорости. + if (velocity.y >= 0) this.actor.spriteRenderer.setAnimation("Jump"); + else this.actor.spriteRenderer.setAnimation("Fall"); + } + + // Наконец, мы применяем скорость обратно к телу ArcadePhysics + this.actor.arcadeBody2D.setVelocity(velocity); + } +} +Sup.registerBehavior(PlayerBehavior); +``` + +Вы можете [загрузить демо проект](https://bitbucket.org/sparklinlabs/superpowers-collision-demo) и попробовать его сами! + +![](http://i.imgur.com/v4tWyIN.gif) + +Дополнительные методы доступне в компоненте `.arcadeBody2D` . Обязательно проверьте API-браузер в Superpowers. diff --git a/pages/ru/2_tutorials/8_raycasting.md b/pages/ru/2_tutorials/8_raycasting.md new file mode 100644 index 0000000..d4a9e8c --- /dev/null +++ b/pages/ru/2_tutorials/8_raycasting.md @@ -0,0 +1,40 @@ +# Отброс лучей, сбор мыши + +Raycasting позволяет обнаруживать пересечения между лучом и геометрическими объектами. +Его можно использовать, например, для проверки попадания пули в игрока или, если мышь парит над кнопкой.. + +## Настройка луча + +``` +let ray = new Sup.Math.Ray(); + +// Вы можете выбрать происхождение и направление +ray.setOrigin(0, 1, 2); +ray.setDirection(0, 0, 1); + +// Или вы можете настроить его с камеры и позиции мыши +ray.setFromCamera(someCameraComponent, Sup.Input.getMousePosition()); +``` + +## Проверка на пересечение с актерами + +``` +let hits = ray.intersectActors([ /* a list of actors */ ]); + +// Пересечения отсортированы по расстоянию от ближайшего к дальнему +for (let hit of hits) { + Sup.log(`Actor ${hit.actor.getName()} was hit by ray at ${hit.distance}`); + // объект `hit` также имеет точку координат и нормаль столкновения +} +``` + +## Проверка на пересечение с плоскостью + +``` +// Плоскость может быть установлена ​​с нормалью и расстоянием от этой нормали +// (В качестве альтернативы, вы можете использовать `plane.setFromPoint(normal, point);`) +let plane = new Sup.Math.Plane(Sup.Math.Vector3.forward(), 10); + +let hit = ray.intersectPlane(plane); +if (hit != null) Sup.log(`Луч попал в плосколсть в ${hit.point}`); +``` diff --git a/pages/ru/2_tutorials/9_prefabs.md b/pages/ru/2_tutorials/9_prefabs.md new file mode 100644 index 0000000..2591b0c --- /dev/null +++ b/pages/ru/2_tutorials/9_prefabs.md @@ -0,0 +1,39 @@ +# Prefabs и instantiation + +Игры часто имеют снаряды, мобов или бонусы, которые создаются +(говорят "экземпляры" в программировании) и уничтожены много раз. + +Они могут состоять из сложной иерархии акторов или, по крайней мере, состоять из нескольких компонентов. +Вместо того, чтобы встраивать их в код, вы можете использовать `Scene` assets как переиспользуемый prefabs. + +## Instantiating содержимого сцены + +Вы можете использовать `Sup.appendScene("Scene Asset")` чтобы добавить всех актеров, описанных в сцене, к вашей сцене. +Существующие актеры не будут удалены. + +
+ **Зв кадром**, `Sup.loadScene(...)` эквивалентно вызову `Sup.destroyAllActors()` с последующим `Sup.appendScene(...)`. +
+ +Вы можете добавлять сцену столько раз, сколько хотите, и при желании указывать родительский актер в качестве второго аргумента. + +## Используем prefabs в scene editor + +Кнопка `New Prefab` возле кнопки `New Actor` в редакторе сцены. +Позволяет вам прикрепить другие сцены как часть вашей основной сцены. + +
+ **Prefabs даже работает рекурсивно**, это означает, что у вас может быть сцена, ссылающаяся на вторую сцену, +  сам ссылаясь на третью сцену и так далее... Superpowers будет автоматически предотвращать циклические ссылки. +
+ +Чтобы сцена могла быть использована в качестве префаба, в ее корне должен быть один актер. +При использовании из другой сцены имя этого корневого актера будет заменено именем префаба. +Например, вы можете иметь сцену с именем `Health Bonus` с корневым актером по имени `Bonus Root`, а также +использовать его в качестве сборного под разными именами, такими как `Secret Health Bonus`, `Health Bonus 3` и т.п. + +
+ **Компоненты актера в prefabs будут настраиваться** в будущей версии. + На данный момент вы можете получить имя префаба (используя `Sup.Actor.getName ()`) в поведении для применения пользовательских настроек. +  Это не идеально, но эй, лучше, чем ничего! +
\ No newline at end of file diff --git a/pages/ru/2_tutorials/index.md b/pages/ru/2_tutorials/index.md new file mode 100644 index 0000000..81c8590 --- /dev/null +++ b/pages/ru/2_tutorials/index.md @@ -0,0 +1 @@ +# Tutorials diff --git a/pages/ru/3_resources/1_getting-help.md b/pages/ru/3_resources/1_getting-help.md new file mode 100644 index 0000000..0fe7ada --- /dev/null +++ b/pages/ru/3_resources/1_getting-help.md @@ -0,0 +1,38 @@ +# Getting help + +The Superpowers community is made of passionate people like you, eager to share their experience. +This page has some advice to best help them help you. You'll find a list of places to ask for help at the end. + +## Reporting a bug + +
+ Make sure you're running the latest version of Superpowers before reporting bugs. + + If possible, try it out in the latest development version to see if it's already been fixed for the next release. +
+ +Bugs can only be fixed if they are reproducible. Your goal when reporting a bug should be to provide as much relevant, precise information as possible. + + 1. Start by stating which version of Superpowers you are using (indicate if you are using a release or the source repositories), and which platform you are running it on (OS version, Superpowers app or browser with version). + + 2. Proceed with describing the issue in a few words, explaining what the expected behavior was, and what happens instead. + + 3. Describe all the steps you've taken that led to the bug. Provide screenshots if you think they will be helpful. + + 4. If you encounter an error message, make sure to copy it in its entirety, and to note when and where it appears. When something is very broken, error messages might appear in the Console tab of the developer tools (accessible using `F12`) so make sure to check there. + +You can further help by trying to reproduce the issue in a fresh, minimal project. If the issue is hard to replicate or requires a lot of steps, attaching a ZIP archive of a minimal project might very useful. + +## Getting help with scripting + +When you've got your head down in a scripting problem, it's easy to forget others don't have the same context as you do. + +When asking for help, describe your goal (the big picture of what you're trying to achieve) first. Asking for help with the specific approach you're trying out would prevent others from helping you effectively. Of course, it's useful to mention what you've been trying but only after you've made clear your actual goal. + +When sharing code, don't share a single line, share enough context so that your code snippet makes sense on its own. + +## Places to ask for help + +[The Superpowers forum on Reddit](https://reddit.com/r/superpowers) is the best place to ask for help (as well as for sharing your projects, bugs and suggestions!). Alternatively, you can use [the Skype group chat](https://sparklinlabs.com/skype/en) if you think live help is better. + +Oh and when you make something cool, share it with @SuperpowersDev on Twitter, we'll be happy to retweet! diff --git a/pages/ru/3_resources/2_giving-help.md b/pages/ru/3_resources/2_giving-help.md new file mode 100644 index 0000000..2730f35 --- /dev/null +++ b/pages/ru/3_resources/2_giving-help.md @@ -0,0 +1,24 @@ +# Helping others out + +The Superpowers community strives to be a friendly, inclusive, welcoming place. +Different people with very different goals or concerns will end up chatting together. + +Here are simple ideas that might help you contribute to that spirit: + +## Be nice, assume good faith, don't reply to everything + +Sometimes, it gets old repeating the same things over and over again and some of us might become frustrated. +It's easy to forget there are real people on the other side of the Internet. + +**If you find that you can't be nice in your reply, then refrain from posting at all.** You don't have to reply to every single post or every single person. It's okay to let a post go by. Someone else who's in a better disposition will reply. + +It's better for a post to go unanswered for a little while, than to inject aggressivity in a discussion. +Aggressivity engenders more aggressivity and soon it'll be driving people away. + +## Dealing with non-constructive behavior and aggression + +If you find someone is not contributing positively, consider pointing it out to them in a friendly way, maybe linking them to this page. + +If someone is being outright aggressive or insulting and you don't see them adopting a more positive attitude, it might be best to remove yourself from the discussion and wait for a moderator to intervene. + +As the Superpowers development team, we try to read and answer in the community's various communication channels whenever possible. You can [get in touch with us privately](mailto:team@sparklinlabs.com) if needed. diff --git a/pages/ru/3_resources/3_api-documentation.md b/pages/ru/3_resources/3_api-documentation.md new file mode 100644 index 0000000..eb9bf77 --- /dev/null +++ b/pages/ru/3_resources/3_api-documentation.md @@ -0,0 +1,5 @@ +# API Documentation + +Since Superpowers is made out of many plugins and you can customize them and install your own, we don't provide an online API documentation. + +Instead, use the **TypeScript API browser** tool in your Superpowers project to discover all the numerous functions and classes made available in your scripts by the plugins installed on your server. diff --git a/pages/ru/3_resources/4_demo-projects.md b/pages/ru/3_resources/4_demo-projects.md new file mode 100644 index 0000000..a4da4c2 --- /dev/null +++ b/pages/ru/3_resources/4_demo-projects.md @@ -0,0 +1,15 @@ +# Demo projects + +Instructions for setting up a project can be found on each project's page. +Generally, it involves clicking on `Download ZIP` page +and unzipping it into [your `projects` folder](/en/getting-started/setting-up-superpowers), +then restarting your server. + +## Open Source games and demos + +You can find all kinds of games and demo projects [on GitHub](https://github.com/superpowers-extra). +They will help you learn various aspects of the software. + +You can play them all in the [Open Source Games made with Superpowers](http://itch.io/c/38089/open-source-games-made-with-superpowers) collection on itch.io. + +![Screenshot from Fat Kevin](http://i.imgur.com/H4nan3c.png) diff --git a/pages/ru/3_resources/5_additional-plugins.md b/pages/ru/3_resources/5_additional-plugins.md new file mode 100644 index 0000000..8e0bcd0 --- /dev/null +++ b/pages/ru/3_resources/5_additional-plugins.md @@ -0,0 +1,6 @@ +# Additional plugins + +Люди из сообщества создали различные плагины. Они могут отлично работать для вас! +Обязательно сообщайте о любой проблеме, с которой вы столкнулись, непосредственно автору плагина. + + * Хранилище плагинов сообщества by Ralmn diff --git a/pages/ru/3_resources/6_assets.md b/pages/ru/3_resources/6_assets.md new file mode 100644 index 0000000..92e5dae --- /dev/null +++ b/pages/ru/3_resources/6_assets.md @@ -0,0 +1,14 @@ +# Downloadable assets + +As a Superpowers early access supporter, you can download various asset packs +from [your account page](https://sparklinlabs.com/account). + +Other valuable resources include: + + * [OpenGameArt.org](http://opengameart.org/) + * [Kenney's Assets](http://www.kenney.nl/assets) + * [Freesound.org](http://www.freesound.org/) + +When using assets downloaded from the Internet, make sure to double-check +their license and abide by the terms. +Some licenses may prevent commercial use, or require that you credit the author diff --git a/pages/ru/3_resources/7_external-tutorials.md b/pages/ru/3_resources/7_external-tutorials.md new file mode 100644 index 0000000..d343e88 --- /dev/null +++ b/pages/ru/3_resources/7_external-tutorials.md @@ -0,0 +1,13 @@ +# External tutorials + +## [Game From Scratch tutorial series](http://www.gamefromscratch.com/post/2016/02/01/Superpowers-Tutorial-Series-Part-One-Getting-Started.aspx) + +A tutorial series with lots of screenshots and step-by-step instructions. + +## [Superpowers tutorials by Michael Seyne](https://github.com/mseyne/superpowers-tutorials) + +A series of detailed tutorials with free assets and source projects. + +## [Translation of tutorials into Russian](http://pajamdev.tk/sup/) + +Перевод документации и уроков на русский язык. diff --git a/pages/ru/3_resources/index.md b/pages/ru/3_resources/index.md new file mode 100644 index 0000000..3c1229e --- /dev/null +++ b/pages/ru/3_resources/index.md @@ -0,0 +1 @@ +# Resources diff --git a/pages/ru/404.md b/pages/ru/404.md new file mode 100644 index 0000000..2a8bd4e --- /dev/null +++ b/pages/ru/404.md @@ -0,0 +1,3 @@ +# Page not found + +Извини за это! Перейти назад [на главную страницу](/ru/). diff --git a/pages/ru/4_development/1_roadmap.md b/pages/ru/4_development/1_roadmap.md new file mode 100644 index 0000000..30f22d5 --- /dev/null +++ b/pages/ru/4_development/1_roadmap.md @@ -0,0 +1,32 @@ +# Roadmap + +Before migrating to GitHub, the core development team used [a Trello board](https://trello.com/b/eQUeNKrq/superpowers) to keep track of planned features, but we are slowly moving away from it. + +## Superpowers v2.0 or later + + * [Allow enabling/disabling plugins on a per-project basis](https://github.com/superpowers/superpowers-core/issues/73) and only export enabled plugins for shorter load times + * [Authentication, access rights and user settings](https://github.com/superpowers/superpowers-core/issues/55) + * [Support exporting for various platforms right from Superpowers](https://github.com/superpowers/superpowers-core/issues/35) + * Superpowers Game: + * [Allow choosing which assets to load on startup and loading the rest dynamically](https://github.com/superpowers/superpowers-game/issues/33) for shorter load times + * [Typed asset tree](https://github.com/superpowers/superpowers-game/issues/35) to increase confidence when reorganizing assets + +## Superpowers v1.0 + +This release will focus on making it easy to release and upgrade the major parts of Superpowers independently. + + * [Split the launcher from the server and redesign it](https://trello.com/c/IVEnTXCe/701-redesign-launcher) + * Release the server and each system (aka. project type) separately with their own version numbers + * Support updating the server and each system from the launcher + * Superpowers Game: + * [Support drag'n'dropping assets from the asset tree into a scene](https://github.com/superpowers/superpowers-game/issues/30) + +## Previous releases + +Release notes for all releases can be found on GitHub: + + * [Client/Server releases](https://github.com/superpowers/superpowers-core/releases) + * [Launcher releases](https://github.com/superpowers/superpowers-app/releases) + * [Superpowers Game releases](https://github.com/superpowers/superpowers-game/releases) + +Release notes for other systems can be found on their own repository. diff --git a/pages/ru/4_development/2_how-to-contribute.md b/pages/ru/4_development/2_how-to-contribute.md new file mode 100644 index 0000000..4ebfa0f --- /dev/null +++ b/pages/ru/4_development/2_how-to-contribute.md @@ -0,0 +1,63 @@ +# How to contribute + +Thanks for your interest in contributing, We're humbled and to be honest, a bit excited ^_^. +There are many ways you can help advance Superpowers! + +## Preamble + +Superpowers adheres to the [Contributor Covenant](https://github.com/superpowers/superpowers-core/tree/master/CODE_OF_CONDUCT.md). +By participating, you are expected to honor this code. + +As a new contributor, we want you to feel welcome and comfortable. +You're not going to break anything, so feel free to experiment. +We appreciate it when people follow the conventions detailed below, +but if you're unsure about where to post, pick a place that makes sense to you +and someone will point you to the right one if needed. + +### Superpowers's source code [is hosted on GitHub](https://github.com/superpowers) + +GitHub is a website for collaborating on projects. Superpowers is split over several repositories: + + * [superpowers/superpowers](https://github.com/superpowers/superpowers-core) — The core (client/server) + * [superpowers/superpowers-app](https://github.com/superpowers/superpowers-app) — The desktop app + * [superpowers/superpowers-game](https://github.com/superpowers/superpowers-game) — The Superpowers Game system + * [superpowers/superpowers-html5.com](https://github.com/superpowers/superpowers-html5.com) — Superpowers's website + +Other systems and plugins might be hosted elsewhere by developers unaffiliated with the Superpowers project. + +## Reporting and triaging bugs + +Bugs should be reported on GitHub. When in doubt, feel free to [open an issue in the core repository](https://github.com/superpowers/superpowers-core/issues/new). + +You can help triage bugs and make them more useful by: + + * Asking bug reporters which platform (Windows, OS X or Linux, 32-bit or 64-bit) and which browser/app version they're using. + * Trying to reproduce the bug with the latest development version of Superpowers on any platform possible and reporting your findings. + * If you can't reproduce the bug, it's worth sharing that too and maybe ask for more details! + +## New features and suggestions + +Check out [the Roadmap](/en/development/roadmap) for an idea of where development is headed. + +Ideas and suggestions for new features should be posted [on the forums](http://itch.io/engine/superpowers/community). +Once a feature proposal gets support and traction in the community, +you can create an issue on GitHub to discuss its design in details before moving on to implementation. + +## Documentation + +The documentation website is written in Markdown. +New pages should be treated as new features, following the same proposal and discussion process outlined above. + +`FIXME: It should probably be rewritten as a Superpowers project and published on GitHub Pages?!` + +## Contributing code + +See [the build instructions](/en/development/building-superpowers) to get the development version of Superpowers +running on your own computer. + +## Sending a pull request + + * Use imperative in your commits message, for instance `Add flux capacitor` not `Added a flux capacitor` + * If you're fixing a bug with an existing issue number of GitHub, mention it in the commit message: `Increase gigawatt output, closes #6` + * Try to stick to the existing coding style. You can use the `tslint` plugin in Visual Studio Code to help. + * Make your pull request as small as possible. Don't bundle many unrelated changes together. diff --git a/pages/ru/4_development/3_building-superpowers.md b/pages/ru/4_development/3_building-superpowers.md new file mode 100644 index 0000000..cd53338 --- /dev/null +++ b/pages/ru/4_development/3_building-superpowers.md @@ -0,0 +1,95 @@ +# Building Superpowers + +## Prerequisites + +You'll need to install the latest [`5.x` version of Node.js](https://nodejs.org/dist/latest-v5.x/) and a Git client. + +If you are not already familiar with Git and GitHub, +[we recommend reading up on them](https://google.com/search?q=learn+git+github). +You can either [use the command line version of Git](http://git-scm.com/) or a Git client app +like [GitExtensions](http://gitextensions.github.io/), [SourceTree](https://www.sourcetreeapp.com/) or [GitHub Desktop](https://desktop.github.com/). + +We also recommend using a text editor with good TypeScript support like [Visual Studio Code](https://code.visualstudio.com/) for development. + +## Building Superpowers core and systems + +In a terminal, run the following commands: + +```bash +# Clone the core repository in superpowers/core +git clone https://github.com/superpowers/superpowers-core superpowers/core +cd superpowers/core + +# Clone the Superpowers Game system in superpowers/core/systems/game +git clone --recursive https://github.com/superpowers/superpowers-game systems/game + +# Build it all. This will take a few minutes. +npm run build +``` + +### Running the server + +Once it's done, you can start the server with: + +```bash +node server start +``` + +Open `http://localhost:4237/` in your browser. +Later, you can hit `Ctrl+C` in the terminal to stop the server. + +### Rebuilding selectively + +After updating the Git repositories or making changes, you'll need to rebuild. + +```bash +cd superpowers/core + +# You can rebuild core and all systems with one command +npm run build +# Or rebuild only some specific folders like SupCore +npm run build SupCore +# or a particular system +npm run build systems/game + +# To build in verbose mode +# (Notice there are two pairs of double dashes) +npm run build -- --verbose +``` + +## Building the desktop app + +The desktop app is powered by [Electron](http://electron.atom.io/). + +In a terminal, run the following commands: + +```bash +git clone https://github.com/superpowers/superpowers-app superpowers/app +cd superpowers/app +npm run build +``` + +Once it's done, you can start the app by running: + +```bash +# Install Electron the first time (and then everytime you want to update it) +npm install -g electron + +npm run start +``` + +## Enabling development mode + +In order to catch as many runtime errors as possible while working on Superpowers, +you can enable development mode. +When development mode is enabled, the project header in the top-left corner +will be blue. When it turns red, it's a good sign that you should +open your browser's dev tools and look for errors in the Console tab. + +Enabling development mode will also add the `None` language to the language selector, which is useful for finding strings that need to be internationalized. + +To enable development mode, open a Superpowers project, press `F12` to open the dev tools and type the following in the console: + + localStorage.setItem("superpowers-dev-mode", "true"); + +Reload for the change to take effect. diff --git a/pages/ru/4_development/4_translating-superpowers.md b/pages/ru/4_development/4_translating-superpowers.md new file mode 100644 index 0000000..fb16e49 --- /dev/null +++ b/pages/ru/4_development/4_translating-superpowers.md @@ -0,0 +1,20 @@ +# Translating Superpowers + +## Adding support for a new language + +Superpowers supports multiple languages. You can add support for your own language! + +To do so, you'll need to [build Superpowers from source](/en/development/building-superpowers). +Translation files (also called "localization files") are stored in the `locales` folders throughout the repositories. + + * The core localization files are located in `public/locales`. + * Each system has its own localization files in `systems/SYSTEM_NAME/public/locales`. + * Each plugin has its own localization files in `systems/SYSTEM_NAME/plugins/AUTHOR_NAME/PLUGIN_NAME/public/locales`. + +You should start by creating a folder in `public/locales` with a name consisting of [the two-letter code for your language](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), for instance `fr` or `ja`. +The very first localization file you'll need is `common.json`. Copy it from the `en` folder to your own language's folder and translate all the values on the right (but leave the keys on the left as is). + +## Testing your changes + +Most of the localized strings will be baked into various `index.YOUR_LANGUAGE_CODE.html` files when building Superpowers. +To test your changes, execute `npm run build` and restart Superpowers afterwards. diff --git a/pages/ru/4_development/5_extending-superpowers.md b/pages/ru/4_development/5_extending-superpowers.md new file mode 100644 index 0000000..8804331 --- /dev/null +++ b/pages/ru/4_development/5_extending-superpowers.md @@ -0,0 +1,253 @@ +# Extending Superpowers + +Superpowers is a highly extensible platform. +While it is primarily used to make video games, it can be repurposed for any kind of creative work. +Make sure you have [the development version of Superpowers](/en/development/building-superpowers). + +## Systems and plugins + +Superpowers currently ships with a single system, `Superpowers Game` which lets you make 2D and 3D games with TypeScript. +You can build your own systems to provide entirely different project types. + +The system itself provides the shared components (like a game engine for instance) +upon which various plugins will build to provide editors and tools. + +## Setting up your own system + +Systems are stored in the `systems` folder, inside your Superpowers app. + +
+ **In Superpowers v1.0, systems and plugins will be moved** to [the user data folder](/en/getting-started/setting-up-superpowers). +
+ +You can create a new system by running: + +```bash +cd superpowers +node server init $SYSTEM_ID +``` + +Then open `systems/$SYSTEM_ID/package.json` and customize things as you like. +You'll want to edit `systems/$SYSTEM_ID/public/locales/en/system.json` to describe your system, too: + + { + "title": "Dummy", + "description": "A demo system that doesn't do much, but does it well." + } + +These strings will appear in the project creation popup. + +## Setting up a plugin + +Plugins are stored in `systems/$SYSTEM_ID/plugins/$PLUGIN_AUTHOR/$PLUGIN_NAME`. + +You can create a plugin by running: + +```bash +cd superpowers +node server init $System_ID:$PLUGIN_AUTHOR/$PLUGIN_NAME +``` + +Plugin included by default with your system should be placed in the `plugins/default` author folder. + +We maintain [a set of common plugins](https://github.com/superpowers/superpowers-common-plugins) including the home chat, +the settings tool and the real-time collaborative text editor widget. +You can include them in your repository as a Git submodule in `plugins/common`. + +## Anatomy of a plugin + +At the root of your plugin, you'll find a `package.json` file +(following [npm's package.json file format](https://docs.npmjs.com/files/package.json)). + +Here's what it might look like: + + { + "name": "superpowers-$SYSTEM_ID-$PLUGIN_AUTHOR-$PLUGIN_NAME-plugin", + "description": "My plugin for Superpowers Dummy", + "scripts": { + "build": "gulp --gulpfile=../../../../../scripts/pluginGulpfile.js --cwd=." + } + } + +Besides `package.json`, you'll find the following files at the root of your plugin: + + * `tsconfig.json` is used by `pluginGulpfile.js` to set TypeScript compiler options + * `index.d.ts` is used by TypeScript to find the type definition files for Superpowers (`SupCore`, `SupClient`, etc.) + +The plugin's `public` folder contains all the files that will be exposed to the client (the user's browser or the Superpowers app). +Many of them will be generated by compiling source files (written in Jade, Stylus and TypeScript for instance) +into files that can be consumed by the browser directly (HTML, CSS and JavaScript). + +A plugin can do 3 types of things: + + * Define asset and/or resource classes in `data/` + * Provide asset editors and/or tools in `editors/` + * System-specific stuff like exposing scripting APIs, scene components for Superpowers Game, etc. + +## Building your plugin + +[Gulp](http://gulpjs.com/) is the build tool used throughout Superpowers, +and [`pluginGulpfile.js`](https://github.com/superpowers/superpowers-core/blob/master/scripts/pluginGulpfile.js) +is a shared build file for your plugins that ships as part of Superpowers's main repository. + +It assumes you're using Jade, Stylus and TypeScript to build your plugin. If you'd rather use something else, +you can write your own Gulpfile instead (or run whatever build command you want in your `package.json`'s `build` script). + +You can build just your plugin by typing `npm run build $PLUGIN_AUTHOR/$PLUGIN_NAME` at the root of the Superpowers repository. +Or, if you have `gulp` installed globally, you can directly run `npm run build` inside your plugin's folder. + +If you're using `pluginGulpfile.js`, several things will happen when you run `npm run build` in your plugin's folder. + +If it exists, `data/index.ts` will automatically be compiled to `data/index.js` so it can be loaded by the server. +A [browserified](http://browserify.org/) version of `data/index.js` will then be generated at `public/bundles/data.js` for +the client to load. + +Any other folders at the root of your plugin containing an `index.ts` file will have a browserified bundle generated +and placed in `public/bundles/$FOLDER_NAME.js` so that it can be loaded from the client. + +## Editors and tools + +Your plugin can expose zero or more editors in `editors/*/`. Again, assuming you're using `pluginGulpfile.js`: + + * `editors/*/index.jade` will be transpiled to `public/editors/*/index.html` + * `editors/*/index.styl` will be transpiled to `public/editors/*/index.css` + * `editors/*/index.ts` will be browserified to `public/editors/*/index.js` + +When an editor is associated with an asset type, it becomes an asset editor. +Otherwise, it'll appear in the tool shelf in the bottom-left corner of the project window. + +The query string passed to your editor is parsed and stored in `SupClient.query`. +When you're in an asset editor (as opposed to a tool), `SupClient.query.asset` will contain the ID of the asset that should be edited. + +An SVG icon for each editor should be placed in `public/editors/*/icon.svg`. + +## Asset classes + +Superpowers projects are basically made of a tree of assets. +Your plugin can define one or more asset types. + +Each asset type is a class that inherits from [`SupCore.Data.Base.Asset`](https://github.com/superpowers/superpowers-core/blob/master/SupCore/Data/Base/Asset.ts) ([example](https://github.com/superpowers/superpowers-game/blob/master/plugins/default/sprite/data/SpriteAsset.ts)). + +The `Asset` base class itself inherits from [`SupCore.Data.Base.Hash`](https://github.com/superpowers/superpowers-core/blob/master/SupCore/Data/Base/Hash.ts), +which stores a dictionary of data in its `.pub` property, with a schema for validating data. +Properties can be marked as `mutable` in the schema, allowing clients to edit them directly through `setProperty` (more on editing below). + +Asset classes must be registered with `SupCore.system.data.registerAssetClass` in `data/index.ts`. +The first parameter should be the name of the editor associated with the asset type ([example](https://github.com/superpowers/superpowers-game/blob/master/plugins/default/sprite/data/index.ts)). + +## Resources + +Resources are similar to assets, but for a particular resource class, there is always a single instance of it in every project and it doesn't appear in the asset tree. +They are used to store project-wide settings or information. Tools will often subscribe to one or more resources that they allow editing. +A tool might edit a settings resource that is then used in the associated asset editor for project-wide configuration. + +A resource class must inherit from `SupCore.Data.Base.Resource` and be registered under a unique name. +For instance, the startup scene of a Superpowers Game project is stored in [the `gameSettings` resource](https://github.com/superpowers/superpowers-game/tree/master/plugins/default/gameSettings/data). + +## Subscriptions and editing + +In order to allow editing the project's assets and resources, editors must subscribe to them. + +First of all, your editor should open a connection to the server through `SupClient.connect` ([example](https://github.com/superpowers/superpowers-game/blob/7ac686ab4e08681e90abb6d6b8de83bf8a1fec1f/plugins/default/sound/editors/sound/index.ts#L16)). + +Once connected, you'll probably want to create an instance of [`SupClient.ProjectClient`](https://github.com/superpowers/superpowers-core/blob/master/SupClient/src/ProjectClient.ts) +([example](https://github.com/superpowers/superpowers-game/blob/7ac686ab4e08681e90abb6d6b8de83bf8a1fec1f/plugins/default/sound/editors/sound/index.ts#L43)). +It can be used to manage subscriptions to the project's assets tree (name of each asset, type, parent, order, etc.), or to particular assets and resources +and it's easier than sending raw socket.io messages and keeping track of things yourself. + +To subscribe to an asset, use `projectClient.subAsset(assetId, assetType, subscriber);` ([example](https://github.com/superpowers/superpowers-game/blob/7ac686ab4e08681e90abb6d6b8de83bf8a1fec1f/plugins/default/sound/editors/sound/index.ts#L45)). +The callbacks on your subscriber object will be called when various events are received from the server. +`subscriber.onAssetReceived` will be called as soon as the asset has been received ([example](https://github.com/superpowers/superpowers-game/blob/7ac686ab4e08681e90abb6d6b8de83bf8a1fec1f/plugins/default/sound/editors/sound/index.ts#L54)). + +To edit an asset, you can use `projectClient.editAsset(assetId, command, args..., callback);`. + +The server, [through `RemoteProjectClient`](https://github.com/superpowers/superpowers-core/blob/60145c1aba13f7ffd8056cdcf1aac6117999b2c3/server/RemoteProjectClient.ts#L325) +will call a method starting with `server_` followed by the command you specified. + +If the command's callback doesn't return an error, the server [will emit back the command to every client subscribed to the asset](https://github.com/superpowers/superpowers-core/blob/60145c1aba13f7ffd8056cdcf1aac6117999b2c3/server/RemoteProjectClient.ts#L346). +In turn, on the client-side, `ProjectClient` [will call the corresponding `client_` method on your asset](https://github.com/superpowers/superpowers-core/blob/60145c1aba13f7ffd8056cdcf1aac6117999b2c3/SupClient/src/ProjectClient.ts#L157), applying the changes provided by the server. +Then it will notify all subscribers of the change. + +In `server_` methods, whenever the asset is edited, you should call `this.emit("change");` +to let the project server know that the asset has changed and should be [scheduled for a write to disk soon](https://github.com/superpowers/superpowers-core/blob/60145c1aba13f7ffd8056cdcf1aac6117999b2c3/server/ProjectServer.ts#L249). +The server saves a particular asset to disk [no more often than once every 60s](https://github.com/superpowers/superpowers-core/blob/60145c1aba13f7ffd8056cdcf1aac6117999b2c3/server/ProjectServer.ts#L11). + +`TODO: We still need to design a way to stream large assets.` + +## Internationalization + +You can place JSON localization files in `public/locales/$LANGUAGE_CODE/$NAMESPACE.json` ([example](https://github.com/superpowers/superpowers-game/tree/master/plugins/default/sound/public/locales/en)). + +They will be made available through the `t("namespace:path.to.key")` function to your Jade templates. +You can also load them up at runtime with [`SupClient.i18n.load`](https://github.com/superpowers/superpowers-core/blob/master/SupClient/src/i18n.ts) +and use them with `SupClient.i18n.t("namespace:path.to.key")`. +([example](https://github.com/superpowers/superpowers-game/blob/master/plugins/default/sound/editors/sound/index.ts#L130)) + +`public/locales/$LANGUAGE_CODE/plugin.json` should contain an `editors.*.title` key for each of your editors. + +## Generic plugin API + +You can use `SupCore.system.registerPlugin` to expose bits of code or data that can be reused by other plugins. +For instance, the Superpowers Game system uses this facility to let each plugin expose TypeScript APIs, as well as component configuration classes. + +Each such plugin must be attached to a context (for instance `"typescriptAPI"`) and given a name ([example](https://github.com/superpowers/superpowers-game/blob/273611624b3168a629514c2a644b71d9ac325387/plugins/default/sound/typescriptAPI/index.ts)). +You should also define an interface to get type checking ([example](https://github.com/superpowers/superpowers-game/blob/273611624b3168a629514c2a644b71d9ac325387/plugins/default/typescript/typescriptAPI/TypeScriptAPIPlugin.d.ts)). + +On the server-side, `SupCore.system.requireForAllPlugins` lets you require a module for all plugins. +This can be used to conveniently load all registered plugins for a particular context ([examples](https://github.com/superpowers/superpowers-game/search?utf8=%E2%9C%93&q=SupCore.system.requireForAllPlugins&type=Code)) . + +On the client-side, you'll need to load them by appending a `