Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Способы прокрутки повторяющегося фона (http://www.flasher.ru/forum/showthread.php?t=178177)

PlutDem 16.04.2012 18:53

Способы прокрутки повторяющегося фона
 
Здравствуйте, хотелось бы узнать как правильно реализовать прокрутку повторяющегося фона. Можно создать одну битмапу на весь экран и прокручивать ее методом scroll(), а можно создать несколько экземпляров битмапы и подставлять их в нужные места. Не знаю что выбрать.

Dukobpa3 16.04.2012 19:24

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

(к слову сказать скроллить то всё-равно придется, единственное с чем нужно определиться это с размером паттерна)

PlutDem 16.04.2012 19:55

scroll(), безусловно, удобнее. Фон представляет собой нечто вроде облаков, так что все что нужно это сдвигать его с помощью scroll(). Были опасения насчет производительности. Все таки ворочать тыщи пикселов каждый кадр это не пальцем в носу ковырять:)

Dukobpa3 16.04.2012 20:17

как раз наоборот. проще прокрутить одну большую картинку чем кучу маленьких.

PlutDem 16.04.2012 22:00

Вложений: 1
Цитата:

Сообщение от Dukobpa3 (Сообщение 1075298)
как раз наоборот. проще прокрутить одну большую картинку чем кучу маленьких.

Кучу маленьких? Кажется мы не поняли друг друга. Там всего может быть максимум 5 картинок. Это если скролить по 2 осям. Если по одной то 3.

NikolyA 16.04.2012 22:15

http://www.flashperfection.com/tutor...AS3-09938.html

PlutDem 16.04.2012 22:35

NikolyA
Ну да, не три, а две:)
И все же хотелось бы услышать мнение по поводу использования метода scroll() вместо нескольких картинок.

anmelegov 17.04.2012 11:38

http://plasticsturgeon.com/2010/11/s...-huge-bitmaps/

Wolsh 17.04.2012 12:12

updateAfterEvent() с частотой 3 мс, чтобы двигать облачка на фоне игры – мягко говоря перебор.

PlutDem 17.04.2012 21:42

scroll() одной картинки занимает 4 мс, думаю остальные операции с bitmapData немногим быстрее и уж точно не быстрее простого перемещения картинки.

Psycho Tiger 17.04.2012 22:49

Цитата:

Сообщение от PlutDem (Сообщение 1075488)
scroll() одной картинки занимает 4 мс, думаю остальные операции с bitmapData немногим быстрее и уж точно не быстрее простого перемещения картинки.

Да вот нет. copyPixels быстрее, чем поменять координату.

strangedk 17.04.2012 23:05

Для прокрутки фона я использовал сдвиг матрицы bitmapData по координате X

PlutDem 18.04.2012 12:34

Psycho Tiger
Код AS3:

img= Bitmap(loader.content)
 
var tim:Number = getTimer();
img.bitmapData.copyPixels(img.bitmapData, new Rectangle(0,0,50,50),new Point(50,50));
 
trace(getTimer()-tim);// 4 мс

Тоже 4 мс. Нет, я конечно не знаю, может я что то не так делаю?

Psycho Tiger 18.04.2012 18:15

Единичный тест ничего не стоит. Тесты нужно проводить пачками, и по клику, когда FP уже "разогрелся".
К тому же неплохо, правда? Там просто координату подвинули за 4 мс, а тут создали новый Rectangle, новый Point, ещё и перерисовали - и тоже 4.

PlutDem 18.04.2012 18:36

Цитата:

Сообщение от Psycho Tiger (Сообщение 1075734)
Там просто координату подвинули за 4 мс...

???
Цитата:

Сообщение от PlutDem (Сообщение 1075488)
...не быстрее простого перемещения картинки.

Под перемещением картинки я имел ввиду изменение x и y координат DisplayObject. Сколько бы вы не "грели" FP scroll() и copyPixels() не станут работать в 400 раз быстрее.

anmelegov 18.04.2012 18:43

зачем вообще таймер я не понимаю... не проще сделать override public function set x(value:Number):void { и дальше тот код с прямоугольником и копиПикселс и просто тупо двигать?

Psycho Tiger 18.04.2012 18:47

Цитата:

Сколько бы вы не "грели" FP scroll() и copyPixels() не станут работать в 400 раз быстрее.
Когда происходит сдвиг координат - процессор нагружается. Он не может не нагружаться ) И если где-то в системе поднято 3 сервера, открыто 20 IDE и Вы занимаетесь перекодированием видео, то вполне вероятно, что флешка может тормозить. А так да, конечно, ни старт FP, ни что-то другое не влияет на скорость исполнения скрипта.


В общем, если Вы ищите правду - возьмите какой-нибудь спрайт, отрисуйте его в BitmapData, и сделайте 1000 раз copyPixels, замерьте время. Потом расплодите этот спрайт на 1000 других и поменяйте разок каждому координату (да, именно так. Я верю, что внутри Flash API есть инвалидаторы). Удивитесь результату. А потом запускайте тест секунд через 5 после старта FP, например, по клику. И снова удивитесь результату.

PlutDem 18.04.2012 19:19

Psycho Tiger
Код AS3:

for (var i:int = 0; i < 10000; i++) {
        vImg[i].x += 1;
        vImg[i].y += 1;
}
//~7 ms

Код AS3:

for (var i:int = 0; i < 10000; i++) {
        img.bitmapData.copyPixels(img.bitmapData, rect,point);
}
//~ 270 ms


Psycho Tiger 18.04.2012 19:34

Ну, что-то неправильно. Вы делали BitmapData#lock? Давайте полный код теста.

PlutDem 18.04.2012 19:39

Код AS3:

public class Main extends Sprite {
 
                public var loader:Loader = new Loader();
                public var img:Bitmap;
                public var vImg:Vector.<Sprite> = new Vector.<Sprite>;
 
 
                public function Main():void {
 
                        loader.load(new URLRequest("../lib/dirt.jpg"));
                        stage.addEventListener(MouseEvent.MOUSE_DOWN, initImg);
 
                        for (var i:int = 0; i < 10000; i++) {
                                vImg.push(new Sprite);
                        }
 
                }
                public function initImg(e:MouseEvent):void {
 
                        var rect:Rectangle = new Rectangle(0, 0, 50, 50);
                        var point:Point = new Point(50, 50);
 
                        img= Bitmap(loader.content)
 
                        var tim:Number = getTimer();
 
                        for (var i:int = 0; i < 10000; i++) {
                                //img.bitmapData.copyPixels(img.bitmapData, rect,point);
                                vImg[i].x += 1;
                                vImg[i].y += 1;
                        }
                        trace(getTimer()-tim);
                }
 
        }


Psycho Tiger 18.04.2012 20:21

Суть такая: происходит выполнение кода -> происходит обновление вьюпорта, т.е. окна флешки.
В случае обновления одной битмапы (метод с copyPixels) - обновление окна флешки произойдёт почти мгновенно. Обновить одну битмапу не сложно. Вся нагрузка - это вот есть copyPixels.

В случае с спрайтами - внутри кода меняется 2 координаты - это не долго. А вот перерисовать окно флешки с новыми координатами - это уже проблема, надо обновить позицию 10 тысяч клипов.
Так вот в обоих случаях замеряется только выполнение кода. Чтобы замерить сколько времени уйдёт на отрисовку - нужно как-то хитро поиграться с stage#Event.RENDER и stage#Event.ENTER_FRAME. Или ещё лучше - сделать реальный тест, в котором 10к клипов будут гонятся за мышкой. А потом повторить его, но гонятся будут пиксели через copyPixels. В первом случае FPS будет критично малым.

PlutDem 18.04.2012 21:59

Psycho Tiger
Тестировать не буду, поверю на слово. Я, по правде сказать, даже не могу представить себе ситуацию, в которой выбор стоял бы между copyPixels() и обновлением позиции 10к спрайтов!:D
Но в конкретно в моем случае побеждает все таки обновлением позиции так как в таких масштабах (1 bitmap vs 4 DO) copyPixels() дает мизерный выигрыш в скорости обновления окна флешки, но зато в 400 медленнее обрабатывается в коде.

Psycho Tiger 19.04.2012 14:53

Если речь идёт всего о 4-х объектах, то я чисто принципиально бы не стал заморачиваться с copyPixels - метод не так удобен в разработке, как просто менять x/y у DO.

wvxvw 19.04.2012 15:43

Вы серьезно расчитываете с такой скоростью экран обновлять? Он просто физически так быстро не может :) 50 кадров в секунду - это 1000 / 50 миллисекунд на кадр = 20 миллисекунд на отрисовку одного кадра. Если вы собираетесь рисовать со скоростью 3 миллисекунды на кадр - это 1000 / 3 кадров в секунду = 333 fps. Такое, наверное, только в Матрице возможно :)
Флешевый таймер даже с такой точностью не работает.

По поводу того, как сркорллить - если есть возможность использовать scroll() - это оптимальный вариант. Следующий за ним - отрисовывать части битмапдаты в один объект Graphics с применением матрицы трансформации, чтобы сдвинуть картинку относительно точки привязки. Манипулировать экранными объектами будет медленнее т.как от отрисовки никто не избавит, а вот накладные расходы на пересчет из одной системы координат в другую усложнят задачу.


Часовой пояс GMT +4, время: 03:14.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.