Вопрос по mobile – Бесконечный повторяющийся фон прокрутки

0

У меня проблема с AS3 и AIR. Я работаю над игрой с боковой прокруткой для смартфонов с плоскостью и использую разные фоны в качестве слоев.

Прежде всего: я использую GPU и только растровые изображения, качество установлено на низкое. Таким образом, настройки производительности настроены для использования смартфоном.

Я поместил их в прямоугольник, используя API рисования, и переместил фон с помощью матрицы:

protected var scrollingBitmap:BitmapData;
protected var canvas:Graphics;
protected var matrix:Matrix;

public function move(dx:Number, dy:Number):void {
    matrix.translate(dx, dy);
    if(dx != 0) matrix.tx %= scrollingBitmap.width;
    if(dy != 0) matrix.ty %= scrollingBitmap.height;
    drawCanvas();
}

protected function drawCanvas():void {
    canvas.clear();
    canvas.beginBitmapFill(scrollingBitmap, matrix, true, true);
    canvas.drawRect(0, -scrollingBitmap.height, 1404, scrollingBitmap.height);
}

UPDATE2 (

Взгляните на это:http://plasticsturgeon.com/2010/06/infinite-scrolling-bitmap-backgrounds-in-as3/

Я использовал это, чтобы создать свой фон.

При этом я могу смоделировать, что моя плоскость летит вправо, не перемещая весь фон, и я могу использовать маленький отдельный рисунок, который повторяется каждый раз (для слоя переднего плана).

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

Мой метод move находится на событии enterframe. Таким образом, я могу обновить фон каждого кадра с помощью «движения» моего самолета.

)

Плоскость может превышать высоту растровых изображений. Каждый раз, когда растровое изображение возвращается в окно / экран, происходит очень длительное отставание. И когда самолет летит очень быстро, игра тоже начинает лагать.

Моим первым подходом было использование файлов .PNG (но они очень большие: размер 1-3 МБ). Следующим моим подходом было использование файлов .GIF (гораздо меньшего размера).

С обоими это одинаково. Так что это не может быть так.

Я читал про draw () и copyPixels (), но не знаю, как их использовать, чтобы повторить изображение.

UPDATE1:

protected var scrollingBitmap:BitmapData;
protected var canvas:Bitmap;

protected function init(e:Event):void {
    removeEventListener(Event.ADDED_TO_STAGE, init);
    canvas = new Bitmap(new BitmapData(1404, scrollingBitmap.height, true), "auto", true);
    this.addChild(canvas);
    drawCanvas();
}

public function move(dx:Number, dy:Number):void {
    if(dx != 0) dx %= scrollingBitmap.width;
    if(dy != 0) dy %= scrollingBitmap.height;
    drawCanvas(dx, dy);
}

protected function drawCanvas(xPos:Number = 0, yPos:Number =  0):void {
    canvas.bitmapData.copyPixels(scrollingBitmap, new Rectangle(0, 0, 1404, scrollingBitmap.height), new Point(xPos, yPos), scrollingBitmap);
}
Обновил мой вопрос с помощью & quot; Update2 & quot; может быть, это приведет к лучшему пониманию того, чего я достигну WolvDev
Звучит так, будто ваша графика намного больше (в два раза больше), чем должна быть, что является частью вашей проблемы со скоростью. Amy Blankenship
Я получил фоновый рисунок, который намного больше, чем в два раза. Мне нужно прокрутить это изображение с 1% скоростью полета, чтобы имитировать дальний фон, а другой слой на переднем плане будет двигаться с нормальной скоростью. WolvDev
Движение работает, оно движется влево, со скоростью, с которой летит самолет. Но я перемещаю весь уровень: мувиклип (это другой файл) в направлении у. Посмотрите здесь:plasticsturgeon.com/2010/06/… WolvDev
Я думаю, что ваше перемещение не сработает, потому что вы перемещаете только растровое изображение с переводом - я не вижу, куда вы перемещаете любые пиксели назад на другую сторону. Но ваш вопрос касается скорости копирования, а не эффективности перемещения, поэтому я ответил на него. Amy Blankenship

Ваш Ответ

2   ответа
0

http://www.greensock.com/blitmask

Это может помочь, хотя и не бесплатно

Спасибо за ваш ответ, но с этим решением я не могу повторить изображения внутри маски. WolvDev
3

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

Давайте перефразируем ваш холст, чтобы он был растровым, а не MC. Ваш новый код будет выглядеть так:

protected function drawCanvas():void {
   canvas.bitmapData.copyPixels(scrollingBitmap, new Rectangle(0, 0, scrollingBitmap.width, scrollingBitmap.height), new Point(0,0), scrollingBitmap);
}

Ох, и посмотри на это! Этот код не только быстрее, это всего лишь одна строка кода!

EDIT: Added working code

package  {
    import flash.display.MovieClip;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.geom.Rectangle;
    import flash.geom.Point;


    public class EndlessBG extends MovieClip{
        //this one stays stationary, we're getting the pixels for the right side of the pic from here
        private var _source:BitmapData;
        //this is the one moving to the left (the pixels for the right side are not visible except for once a cycle);
        private var _movingPixels:BitmapData;
        private var _canvas:Bitmap;
        private var _xOffset:int = 0;
        private var _rect:Rectangle = new Rectangle();;
        private var _point:Point = new Point();

        public function EndlessBG() {
            super();
            _source = new BathroomStillLife();
            _canvas = new Bitmap(new BitmapData(_source.width, _source.height));
            _canvas.bitmapData.draw(_source);
            _canvas.x = stage.stageWidth/2 - _canvas.width/2;
            _canvas.y = 5;
            addChild(_canvas);
            addEventListener(Event.ENTER_FRAME, gameLoop);
            setGeometryDefaults();
            _movingPixels = new BitmapData(_source.width, _source.height);
            _movingPixels.copyPixels(_source, _rect, _point);
            //turn this on to watch red pixels be drawn where the source pixels are coming in
            //_source = new BitmapData(_source.width, _source.height, false, 0xFF0000);
        }

        private function gameLoop(e:Event):void {
            _xOffset--;//where the background is moving to
            if (_xOffset < -_source.width) {
                _xOffset = 0;
                //this doesn't seem to work correctly:
                //_movingPixels.scroll(_source.width, 0);
                _movingPixels = new BitmapData(_source.width, _source.height);
                _movingPixels.copyPixels(_source, _rect, _point);
            }
            trace(_xOffset);
            setGeometryDefaults();
            _movingPixels.scroll(-1, 0);
            //draw the moved part of the canvas
            _canvas.bitmapData.copyPixels(_movingPixels, _rect, _point);
            //If we stop here, we get a smear to the right
            //so, get the remaining pixels directly from the source
            //1) reset our rect and point to be to the right side
            _rect.x = 0;
            _rect.width = -_xOffset;
            _point.x = _source.width + _xOffset;
            //2) copy from the source
            _canvas.bitmapData.copyPixels(_source, _rect, _point);
        }
        private function setGeometryDefaults():void {
            _rect.x=0;
            _rect.y=0;
            _rect.width = _source.width;
            _rect.height = _source.height;
            _point.x = 0;
            _point.y = 0;
        }

    }

}

Не идеально, и еще недостаточно отточено для поста в блоге, но должно помочь вам начать.

Edit: В конце концов я написал этоСообщение блога.

Я нахожу это .. маловероятным. Но если вы найдете эту статью, то я буду очень заинтересован в ней, поэтому, пожалуйста, бросьте ее мне.
Ах, это все еще отличная информация для меня - я всегда использую.rect свойство при рисовании на весь BitmapData. Спасибо!
Мне кажется, я где-то читал, что внутри Rectangle создает новый каждый раз, когда вы читаете его, поэтому нет смысла хранить ссылку на Rectangle. Я не могу найти ссылку прямо сейчас. Но даже если вы сохранили ссылку на прямоугольник и точку, вы сохраните ее вне функции. Чтобы показать это, мне пришлось бы написать и объяснить дополнительный код в какой-то не связанной части;)
Хотя это всего лишь одна строка кода, вы создаете новый прямоугольник и новую точку для каждого рендера. Не самая лучшая. Тем не менее +1.
Хорошо, вот ссылка, говорящая о том, что я смутно помню. Если вы вызываете BitmapData.rect (что, возможно, мы могли бы сделать выше), он каждый раз создает новый прямоугольникdivillysausages.com/blog/tracking_memory_leaks_in_as3 , Не совсем то же самое, но вот почему моя память несовершенна.

Похожие вопросы