Спрайт-листы (.sprite.ts)
Спрайт-листы как данные: один файл .sprite.ts на изображение, export default defineSpriteSheet({...}).
ОДНА модель: каждая именованная запись — регион изображения (прямоугольник), по желанию
нарезанный на сетку анимации, по желанию несущий именованные клипы по этой сетке — так что
игровой код ссылается на спрайты и клипы по имени и никогда не зашивает прямоугольники.
Визуальный редактор спрайтов (lecodes-2d-editor) читает и пишет эти файлы; ручные правки
сохраняются.
Обзор
// hero.sprite.ts
export default defineSpriteSheet({
image: asset('./hero.png'),
anchor: [0.5, 1],
fps: 10,
sprites: {
hero: {
rect: [0, 0, 1344, 1536],
slice: [7, 8], // сетка 7×8 из ячеек по 192px
directions: ['S', 'SE', 'E', 'NE', 'N', 'NW', 'W', 'SW'],
clips: {
idle: { frames: [0], perDirection: true },
walk: { frames: [1, 2, 3, 4, 5, 6], perDirection: true },
},
},
},
})// props.sprite.ts
export default defineSpriteSheet({
image: asset('./props.png'),
anchor: [0.5, 1],
sprites: {
tree: { rect: [0, 0, 64, 128] },
water: { rect: [64, 0, 128, 32], slice: [4, 1] }, // четыре кадра по 32px
},
})// main.ts
import hero from './hero.sprite'
import props from './props.sprite'
const scene = new Scene2D()
scene.add(props.make('tree', { position: [80, 144], layer: 1 }))
scene.add(props.make('water', { position: [0, 0] })) // нарезан, без клипов → зацикливается сам
const player = hero.make('hero', { clip: 'idle', layer: 1 })
scene.add(player)
player.anim.play('walk', [1, 0]) // ходьба, лицом на восток
scene.open()Определение
defineSpriteSheet({
image: string // asset('./sheet.png')
anchor?: [x, y] // пивот по умолчанию для каждого спрайта; [0.5, 1] = ступни
fps?: number // fps воспроизведения по умолчанию для нарезанных спрайтов / клипов (иначе 12)
sprites?: Record<string, {
rect?: [x, y, w, h] // пиксельный прямоугольник региона в изображении
slice?: [cols, rows] // разбить прямоугольник на сетку анимации (по желанию)
fps?: number // переопределение fps для этого спрайта
clips?: Record<string, Clip> // именованные прогоны по ЛОКАЛЬНОЙ сетке (по желанию; см. SpriteAnimation)
directions?: string[] // имена направлений в порядке локальных строк для клипов perDirection
anchor?: [x, y] // переопределение для этого спрайта
}>
}): SpriteSheetТри уровня спрайта, каждый по желанию:
- только rect — статичный спрайт (пропсы, предметы).
- rect + slice — анимированный тайл: все ячейки зацикливаются по порядку с момента создания (вода, огонь, факелы). Клип вызывать не нужно — он идёт сам.
- rect + slice + clips — персонаж: клипы именуют прогоны кадров по локальной сетке спрайта
(построчно, индекс 0 = левая верхняя ячейка прямоугольника), управляются по имени через
.anim.
Создание спрайтов
sheet.make(name, opts & { clip: string }): Sprite & { anim: SpriteAnimation } // запускает клип
sheet.make(name, opts?): Sprite
// opts: { position?, layer?, anchor?, clip?, direction? }make() собирает АРТ узла: кадр, мировой размер, якорь, анимацию. Неизвестное имя бросает
исключение. Лист никогда не несёт семантику мира — коллайдеры и тела принадлежат сцене:
прикрепи Shape2D / Physics2D / Trigger2D к размещённому узлу (список aspects: в
.scene2d.ts или .aspect(...) в коде).
Мировой размер нарезанного спрайта — одна ячейка (rect / количество), известен до загрузки
текстуры. Текстура загружается лениво при первом make() (или явном sheet.load()); спрайты,
созданные до её прихода, получают кадр по прибытии, так что раскладка и Y-сортировка не ждут
пикселей.
sheet.load(): Promise<Texture2D> // идемпотентная явная предзагрузка
sheet.texture // Texture2D | null (null до загрузки)
sheet.spriteNames // string[]
sheet.rectOf(name) // пиксельный прямоугольник региона (весь rect, нарезан или нет), или null
sheet.def // определение (по соглашению только для чтения)Подводные камни
- Индексы кадров клипа локальны для rect спрайта — индекс 0 это левая верхняя ячейка прямоугольника, а не изображения.
- Нарезанный спрайт без клипов играет один неявный клип,
'all';make()типизирует его без.anim(он доступен какsprite.get(SpriteAnimation)). Нужен контроль? Назови клип и используй.anim. - Ищешь
collider:? Листы — только арт: ставьShape2D(+Physics2D/Trigger2D) на размещённый узел в сцене.
Смотрите также
- SpriteAnimation — клипы,
perDirection, воспроизведение по вектору - Sprite — узел, который строит
make() - Physics2D — тела для размещённых спрайтов (через аспекты
Shape2D)