带有drawBitmap(Matrix)的Android SurfaceView会留下闪烁的鬼影

时间:2016-08-16 07:10:54

标签: android graphics 2d

前言,考虑到这种奇怪的互动,我可能会使用Views而不是SurfaceView,但我的好奇心让我变得更好,我想知道发生了什么。

所以我有一个矩阵类变量。我运行matrix.setTranslate()一次,每隔一帧我说一次matrix.setTranslate()。在此之后,我调用canvas.drawBitmap(,matrix,null)。在100帧之后,我停止绘制位图。

以下是代码:

public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //      matrix = new Matrix(); //Doesn't matter if I add this.
    //      matrix.reset(); //This doesn't matter either.
    if (!once) {
        matrix.setTranslate(100, 100);
    } else {
        matrix.setTranslate(800,800);
    }
    once = true;
    if (++timer < 100) {
        canvas.drawBitmap(ball, matrix, null);
    }
}

我期待发生的事情:三种可能性。

  1. 由于整个屏幕无效
  2. ,因此只能看到右下方的位图
  3. 这两个位图都是可见的,因为SurfaceView在使用脏矩形
  4. 时很聪明
  5. 没有显示任何内容,因为没有画出来。
  6. 实际发生的事情:左上方位图闪烁,右下方位图显示稳定。

    我很确定我的所有基地都已覆盖:

    • 所有类变量都在构造函数中正确设置。
    • SurfaceView.onDraw()在其自己的线程中每33毫米调用一次。
    • 线程调用lockCanvas,然后调用onDraw,然后调用unlockCanvasAndPost

    那么,这里发生了什么?还有奖金问题,这些鬼影会消耗任何额外的资源,我该如何清除它们呢?

    其余的代码,主要是样板:

    public class FullscreenActivity extends Activity {
        GameSurface ball;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ball = new GameSurface(this);
            setContentView(ball);
        }
    }
    
    
    class GameSurface extends SurfaceView implements SurfaceHolder.Callback {
        GameThread thread;
        boolean once = false;
        Bitmap ball;
        Matrix matrix;
        int timer = 0;
    
    
        public GameSurface(Context context) {
            super(context);
            ball = BitmapFactory.decodeResource(getResources(),R.drawable.football);
            matrix = new Matrix();
    
            getHolder().addCallback(this);
            setFocusable(true);
        }
    
        @Override
        public void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
    //      matrix = new Matrix(); //Doesn't matter if I add this.
    //      matrix.reset(); //This doesn't matter either.
            if (!once) {
                matrix.setTranslate(100, 100);
            } else {
                matrix.setTranslate(800,800);
            }
            //matrix.postRotate(timer); //For even more weirdness...
            once = true;
            if (++timer < 100) {
                canvas.drawBitmap(ball, matrix, null);
            }
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            thread = new GameThread(getHolder(), this);
            thread.setRunning(true);
            thread.start();
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
        }
    
    
        class GameThread extends Thread {
            private SurfaceHolder surfaceHolder;
            private GameSurface gameView;
            private boolean run = false;
    
            public GameThread(SurfaceHolder surfaceHolder, GameSurface gameView) {
                this.surfaceHolder = surfaceHolder;
                this.gameView = gameView;
            }
    
            public void setRunning(boolean run) {
                this.run = run;
            }
    
            @Override
            public void run() {
                Canvas c;
                while (run) {
                    c = null;
                    try {
                        Thread.sleep(33);
                    }
                    catch(InterruptedException e) {}
    
                    try {
                        c = surfaceHolder.lockCanvas();
                        synchronized (surfaceHolder) {
                            gameView.onDraw(c);
                        }
                    } finally {
                        if (c != null) {
                            surfaceHolder.unlockCanvasAndPost(c);
                        }
                    }
                }
            }
        }
    }
    

0 个答案:

没有答案