Как стать автором
Обновить

Комментарии 42

Полезная статья, спасибо!
Упражняюсь в английском, незачто!
И в русском поупражняйтесь, не_за_что.
Точно!
Огромное Вам спасибо за вклад в освещение HTML5!
Хорошо, что это еще кому-нибудь, кроме меня, полезно
Гигантское вам спасибо за совет использовать многослойные canvas. Вроде бы и просто, а в голову не пришло.
Метод довольно эффективен, так как переносит довольно большую часть операций на ОС. Особенный профит от его использования возникает в играх-платформерах, когда весь уровень можно отрисовать в фоновом канвасе и просто двигать его внизу, под основной сценой. То же самое, когда реализуется паралакс-эффект.

Еще, думается, можно попробовать отдельные спрайты делать канвасами – потому что основная сцена получается очень разреженной.
На мобильных устройствах ситуация абсолютно обратная — многослойные канвасы сильно тормозят, приходится использовать 1 + пререндер сцены в бэкграунд (причём бэк div'а размером с канвас и расположенный под ним, поскольку необъяснимым образом background у канваса опять же сильно тормозит).
Ещё многими хитрыми способами можно добиться вполне нормальной скорости работы канваса на мобильниках.
Будет круто, если вы напишите о них. Я портировал игру под canvas, нацеливаясь именно на Android и iOS, но проблемы с производительностью даже в браузере развеяли мои мечты и я подзабил. Хотелось бы довести до ума.
Всё никак не наберу критическую массу хаков для полноценной статьи.
Я как раз использую несколько слоёв при разработке игры на LibCanvas.
Не надо увлекаться, пары слоёв вполне достаточно. Основной выигрыш дали другие приёмы, несколько слоёв просто немного помогли мне. Кеширование в бэк-буфер, не полная отрисовка канваса (а только изменённые части), и т.п.
Прошу прощения, это писал я, с ноута девушки. Забыл перелогиниться.
Допустим, у нас есть супермарио. Почти весь экран статичен, только несколько спрайтов движутся. Разве будет плохо, если уровень отрисовать в нижнем слое, а поверх него двигать canvas'ы размером со спрайт?
Я бы лучше избежал лишних дом-операций. Уровень классно отрисовывать в нижнем слое,, согласен, ещё слой для статичных, редко-меняющихся объектов типа разрушающихся стен. а в верхнем слое — оптимизированно отрисовывать маленькие спрайты.
Ого, огромная работа. Спасибо.
Тогда от следующего перевода вы в обморок упадете :)
Энтузиазм на высоте ;)
Работать и учиться не хочется :)
Особенно работать ;)
Практика показала, что работать хочется больше, чем учиться :(
>>К сожалению, на момент написания, только iOS 5.0 beta с Safari 5.1 использовала аппаратное ускорение canvas

Вроде на обновлении винФона тоже Ие с аппаратным ускорением. Хотя что говорить о телефонах — когда даже на декстопах нормальное ускорение канваса есть только у ИЕ и ФФ
Меня тоже удивило, что мой хром не использует аппаратное ускорение.
about:flags
Не буду оригинальничать, добавлю два примеров, как легко использовать оптимизации из топика на LibCanvas:

Используйте многослойные canvas для сложных сцен

var layer1 = new LibCanvas('canvas');
layer2 = layer1.createLayer('second');
layer3 = layer1.createLayer('elseOne');

layer1.ctx.fill( new Rectangle(20,20,50,50) );
layer3.ctx.fill( new Rectangle(80,80,50,50) );


Избегайте нецелых координат

Параметр optimize у drawImage. Оптимизация, кстати, очень хорошая, производительность повысилась значительно.
ctx.drawImage({
   image: libcanvas.getImage('test'),
   from: [15, 25],
   optimize: true
});
<эстетика головного мозга>createLayer – хм, удобно, но не очень элегантно :) Вы думаете, так лучше, чем какой-нибудь класс Scene и его поле – Layers = [Layer1,Layer2,..] ?</эстетика>
Это разные уровни абстракции ;) Какой-нибудь Scene вполне может использовать эти самые createLayer.
Ну а в целом, createLayer – это такое продвинутое копирование и все?
Нет, это просто создание холста во враппере с абсолютной позицией, как описано в топике. Просто изящный интерфейс и ряд мелких плюшек внутри.
Ну, я это и обозвал продвинутым копированием, но библиотека у вас удобная, да
Мы сейчас на работе делаем два коммерческих проекта — игры на LibCanvas, осенью будет бета, так что развитие библиотеки гарантированно. Ну и будет что интересненькое показать)
Был немного удивлен первым триком.
Я как-то надеялся что браузер оптимизирует поток рендера хотя бы внутри requestAnimationFrame
Остается только построить кореляцию между ускорением использование этого pbufferа, и лишней нагрузкой которую генерит копирование, очень больших вообщето, обьемов данных.
И хотелось бы добавить про многослоные канвасы: дети, каждый канвас занимает в памяти как минимум X*Y*3.
гм, посмотрел на исходник первого теста, понял что кто-то в интерете не прав.
Ваш «канвас» ничем от обычной картинки не отличается
Очевидно, что текст не совпадает с примером и это вина не переводчика, в оригинале тоже непонятно.
Судя по коду имеется ввиду, что вместо того, чтобы каждый кадр рисовать графические примитивы — лучше их отрисовать один раз в буфер, а потом отрисовывать из буфера и это правда — отрисовать круг согласно математическим расчётам, которые производятся в .arc или кривую, согласно математическим расчётам, которые производятся в bezierCurveTo значительно медленнее, чем просто скопировать картинку соответствующего размера.

А вот реальная «двойная буферизация» особого смысла не имеет — ведь браузер имеет свой собственный бек-буфер, а отрисовка бек-буфера на основной слой:
1. Занимает слишком много времени
2. Мешает искать узкие места отрисовки

Каждый канвас занимает не X*Y*3, а X*Y*4, вы забыли про альфа-канал, но это не так важно на практике.
Если у нас игра размером, скажем, 1680*1050 (размер — огромен, обычно казуалки намного меньше), то это 7 метров на слой. Даже 5 слоёв — это 35 метров оперативки на игру, не так много ;)
Честно говоря, не могу попасть в контекст ваших двух комментариев. Но если у вас есть конкретные предложения для правок – внимательно слушаю.
Вы не виноваты, точно такой же текст и в оригинале. Просто название раздела «Предварительно отрисовывайте в виртуальный canvas» немного сбиваешь с мысли и начинаешь думать не о «кешировании векторных объектов в растре», а о «двойной буферизации»
А, наконец-то понял. И все к тому, что целиком растровые сцены нет реального смысла буфферизировать?
Да.
Как-то в статье не заметил, но хотя бы в абзац про нецелые координаты стоило бы добавить, что координатная сетка не целочисленная и начинается с (0.5; 0.5), а целые координаты — границы пикселей.
В интернетах это освещено более подробно, а на сайте MDN можно посмотреть пример (линии нечётной ширины выглядят шире, как-будто «размытыми»).
На самом деле это не совсем так. Ведь когда вы делаете fillRect — ничего не блурится ;) И линия шириной 2 пикселя — тоже не блурится. Просто особенности рендеринга и на производительность они мало влияют.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории