Устройство проекта
Проект LeCodes — это обычный TypeScript, но несколько правил отличаются от привычной кодовой базы, и каждая страница этого гайда на них опирается. Пять минут здесь сэкономят путаницу везде дальше.
Всё глобально — никаких импортов
Вся поверхность SDK (Scene, Sprite, UIScreen, Vec3, fetch, …) доступна в каждом файле без единого импорта. Сборка подставляет реализацию того, что ты используешь, и вырезает то, что нет, — поэтому глобалы ничего не стоят.
Единственные допустимые import-инструкции в проекте — относительные пути к его собственным файлам и ассетам:
import { hud } from './ui/hud' // ✓ твой собственный модуль
import hero from './hero.png' // ✓ ассет — превращается в URL ресурса в бандле
import _ from 'lodash' // ✗ ошибка сборки: пакетные импорты запрещеныnpm здесь нет намеренно: рантайм на устройстве — не Node и не браузер, а компилятору нужно видеть весь код, чтобы ужать его до килобайтов.
Точка входа
Точка входа — файл без экспортов. Маленький проект — это часто один файл; в многофайловом проекте точка входа связывает остальные модули и запускает приложение: для UI-приложения это Router.init(home) или screen.open(), для игры — scene.open().
Ассеты
На файлы проекта (изображения, модели, звуки, шрифты) ссылаются двумя способами — импортом или инлайн-макросом asset():
import hero from './hero.png' // одно и то же, две записи
const tex = await Texture2D.load(asset('./hero.png'))asset() — макрос времени компиляции: бандлер переписывает его в ссылку на ресурс, поэтому путь обязан быть строковым литералом — asset(someVariable) не соберётся. Внешним https://… URL макрос не нужен: передавай их обычными строками.
Время: покадровый цикл и таймеры
setLoop(dt => { // срабатывает каждый отрисованный кадр
player.x += 120 * dt // dt — СЕКУНДЫ с прошлого кадра (~0.016 при 60 fps)
})
setTimeout(() => {}, 500) // таймеры принимают МИЛЛИСЕКУНДЫ, как в вебеОдно соглашение, которое стоит усвоить сразу: dt в setLoop — это секунды. Умножай движение на него — и приложение будет вести себя одинаково при любой частоте кадров. Таймеры и длительности анимаций (animate, UI .animateTo()) — миллисекунды.
И правило-спутник: цикл работает, пока его не остановили. Всё, что экран запускает в onOpen, он обязан остановить в onClose — см. жизненный цикл.
Что делает компилятор
Когда ты нажимаешь «запустить», компилятор упаковывает проект в один портативный app.js: подставляет SDK, разрешает ассеты, инлайнит векторную математику и агрессивно вырезает лишнее — вплоть до неиспользуемых методов классов. Именно этот бандл исполняет каждая платформа, а отрисовка, вёрстка и физика работают как нативный код движков — никакого WebView. Если интересно, как устроены части, — смотри Архитектуру.
Практическое следствие: приложение весит мегабайты, а не десятки мегабайт, и ведёт себя одинаково в браузерном превью, на iOS, Android, Windows, macOS и Linux.
Где смотреть детали
- Соглашения — единицы измерения, системы координат, цвета, семантика значений: правила, на которые опирается каждая страница API.
- Глобалы хоста —
setLoop, таймеры,asset(),console. - Остальной справочник API — каждый глобал, с сигнатурами и единицами измерения.
Что дальше
Выбери трек в обзоре и начинай собирать.