2D вид камеры с боковой прокруткой в ​​​​html5

Мне было интересно, как я мог бы создать вид, похожий на камеру, где я мог бы прокручивать уровень внутри элемента холста, как это:

http://playbiolab.com/

Скриншот биолаборатории


person Oni Enzeru    schedule 26.10.2011    source источник
comment
+1: очень старая школа и затягивающая игра. ;)   -  person freakish    schedule 28.10.2011
comment
Простой. спасти(); перевести(-camera.x, -camera.y); рисоватьВсе(); восстановить();   -  person    schedule 13.10.2015


Ответы (2)


Итак, вы хотите, чтобы холст размером 500x500 отображал что-то (игровой уровень), который на самом деле имеет размер 9000x500 или около того.

Это хорошо. Что вы делаете, так это думаете о холсте как о «порте просмотра» для большей сцены. Вы перемещаете холст (или все остальное) в нужное место и рисуете все нужные вещи в этом месте.

Вот пример:

http://jsfiddle.net/hKrrY/

Нажмите на холст и удерживайте нажатой клавишу со стрелкой влево, чтобы увидеть, как сцена проходит, пока красная точка игрока остается «неподвижной».

Когда вы прокручиваете холст размером 100x100, вы видите объекты, которые рисуются в одном месте вне экрана, например (330,50). Перевод холста делает их видимыми.


Я думаю, стоит упомянуть, что именно здесь оптимизация холста начинает действительно иметь значение. Пример, который я привел выше, представляет собой очень упрощенный способ создания окна просмотра, и по мере того, как ваш код прогрессирует, вам захочется все больше и больше думать о том, что вы рисуете и сколько вы рисуете. Например, вам следует избегать рисования объектов, которые полностью находятся за пределами экрана, и если ваша игра или приложение имеет фон размером 9000x500, вы, вероятно, не хотите каждый раз рисовать все целиком!

Таким образом, концепция является здесь выводом, но вам нужно очень хорошо подумать о том, как вы ее реализуете и сколько работы вы заставляете холст выполнять. Если у вас возникнут проблемы с производительностью в приложении с боковой прокруткой, обязательно сообщите нам об этом :)

person Simon Sarris    schedule 27.10.2011
comment
Смотрите мой другой комментарий. В настоящее время это можно сделать лучше, уменьшив пиксели до касания с помощью javascript и включив режим pwnage :-) - person user1610743; 22.02.2014

Я всегда считал, что более эффективно обернуть ваш холст в div с шириной и высотой вашего окна просмотра и скрытым переполнением, а затем просто нарисовать весь свой холст и прокрутить div туда, где вы хотите просмотреть.

Таким образом, html будет:

<div id='wrapper' style='width: 200px; height: 200px; overflow: hidden;'>
     <canvas width='1000' height='1000'></canvas>
</div>

и javascript будет что-то вроде

function scrollWrapper(x, y){
    var wrapper = document.getElementById('wrapper');  
    wrapper.scrollTop = x;
    wrapper.scrollLeft = y;
}

Затем просто вызовите функцию с x и y, которые вы хотите просмотреть. вы можете обернуть его в setTimeout или что-то в этом роде, если хотите переместиться туда, а не просто прыгать туда.

person hobberwickey    schedule 27.10.2011
comment
Однако рисование всего холста должно быть медленным. - person scottheckel; 28.10.2011
comment
если вы просто рисуете холст один раз, а затем просто обновляете то, что меняется, это хорошо, особенно если вы просто отслеживаете, а не рисуете то, что меняется за кадром. - person hobberwickey; 28.10.2011
comment
+1 за этот путь. Чтобы произвести впечатление: мое движение холста 640 * 480 пикселей с помощью getImageData и putImageData на requestAnimationFrame заняло почти 80% ядра ЦП (i7 4770k Haswell); используя этот подход, я сократил его примерно до 10%! Это почти на порядок, и независимо от того, что говорит счетчик кадров в секунду, он кажется НАМНОГО более плавным (вероятно, потому, что срабатывает сглаживание от прокрутки браузера. Учебник: создайте меньший окружающий DIV с переполнением: прокрутка, привяжите событие колесика мыши к func с e.preventDefault() и используйте .scrollTop!Это делает все веселее! - person user1610743; 22.02.2014
comment
добавить overflow:hidden в div-оболочку - person kurumkan; 27.09.2016