Как прокрутить изображение с экрана памяти - PullRequest
2 голосов
/ 08 января 2012

Используя приведенный ниже код для прокрутки, у меня есть нить Surfaceview и растровое изображение текстуры вне холста, который генерируется (изменяется), первая строка (строка), каждый кадр, а затем копируется на одну позицию (строку) вниз на обычном растровом изображении поверхности, чтобы сделатьэффект прокрутки, и я продолжаю рисовать другие вещи поверх этого.Что ж, это то, чего я действительно хочу, однако я не могу заставить его работать, хотя я создаю отдельный холст для закадрового растрового изображения.Он просто не прокручивается вообще.

Другими словами, у меня есть растровое изображение памяти, такого же размера, как у холста Surfaceview, которое мне нужно прокручивать (сдвигать) вниз на одну строку в каждом кадре, а затем заменять верхнюю строку новойслучайную текстуру, а затем нарисуйте ее на обычном холсте Surfaceview.

Вот то, что я думал, будет работать;

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

@Override
    public void surfaceCreated(SurfaceHolder holder) {
    intSurfaceWidth = mSurfaceView.getWidth();
    intSurfaceHeight = mSurfaceView.getHeight();

    memBitmap = Bitmap.createBitmap(intSurfaceWidth, intSurfaceHeight,
            Bitmap.Config.ARGB_8888);
    memCanvas = new Canvas(memCanvas);

    myThread = new MyThread(holder, this);
    myThread.setRunning(true);
    blnPause = false;
    myThread.start();
}

Мой поток, только показывающий основную среднюю бегущую часть:

@Override
public void run() {
  while (running) {     
    c = null;
try {
    // Lock canvas for drawing
    c = myHolder.lockCanvas(null);                  

    synchronized (mSurfaceHolder) {
        // Scroll down off screen canvas and hopefully underlying bitmap bitmap
        Rect src = new Rect(0, 0, intSurfaceWidth, intSurfaceHeight - 1);
        Rect dst = new Rect(0, 1, intSurfaceWidth, intSurfaceHeight);
        memCanvas.drawBitmap(memBitmap, src, dst, null);

        // Note scrolling up like this works fine
        // Rect src = new Rect(0, 1, intSurfaceWidth, intSurfaceHeight + 1);
        // Rect dst = new Rect(0, 0, intSurfaceWidth, intSurfaceHeight);
        // memCanvas.drawBitmap(memBitmap, src, dst, null);

        // Create random one line(row) texture bitmap
        textureBitmap = Bitmap.createBitmap(imgTexture, 0, rnd.nextInt(intTextureImageHeight), intSurfaceWidth, 1);

        // Now add this texture bitmap to top of screen canvas and hopefully underlying bitmap
        memCanvas.drawBitmap(textureBitmap,
                intSurfaceWidth, 0, null);

        // Draw above updated off screen bitmap to regular canvas, at least I thought it would update (save changes) shifting down and add the texture line to off screen bitmap the off screen canvas was pointing to.
        c.drawBitmap(memBitmap, 0, 0, null);

        // Other drawing to canvas comes here


    } finally {
        // do this in a finally so that if an exception is thrown
        // during the above, we don't leave the Surface in an
        // inconsistent state
        if (c != null) {
            myHolder.unlockCanvasAndPost(c);
        }
    }
}       
}

Для моей игры Tunnel Run, https://market.android.com/details?id=com.zubima.TunnelRun, сейчас у меня есть рабочее решение, где вместо этого у меня есть массив растровых изображений,размер высоты поверхности, которую я заполняю своей случайной текстурой, а затем смещаюсь вниз в цикле для каждого кадра.Я получаю 50 кадров в секунду, но я думаю, что могу добиться большего успеха, если прокрутить растровое изображение.

Ответы [ 2 ]

1 голос
/ 16 января 2012

Вы пытаетесь нарисовать растровое изображение поверх себя, то, что никогда не работало на Android AFAIK. Я попал в эту дыру с моей первой игрой, боковым скроллером под названием Mole Miner.

Проблема очень проста: drawBitmap (), по сути, является специальным видом memcpy (), в котором байты всегда адресуются вперед . Это нормально, оптимально использует кэш L1 и т. Д., Но вы, очевидно, столкнетесь с проблемой, если области источника и назначения (а) перекрываются и (б) адрес источника <адрес-адрес. </p>

(Между прочим, реальные реализации memcpy () проверяют эту возможность и при необходимости выполняют копирование в обратном направлении. Canvas.drawBitmap () этого не делает.)

Обходной путь, который я использовал для Mole Miner, заключался в том, чтобы иметь два закадровых растровых изображения и переключаться между ними на альтернативных кадрах. Но это было в 2009 году, и в эти дни я бы вообще не использовал прокрутку.

0 голосов
/ 08 января 2012

В канве есть функция drawBitmap со следующей подписью:

public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint);

Вы можете сделать dst размером с холст, и ваш src может быть настроен как новый

 Rect(0,offset,width,height+offset)

Затем вы можете увеличивать смещение каждого кадра и получать плавно прокручиваемое растровое изображение в своем представлении.

...