Android,canvas:如何清除(删除内容)画布(= bitmaps),生活在surfaceView中?

sam*_*lem 88 android surfaceview android-canvas

为了制作一个简单的游戏,我使用了一个模板来绘制带有这样的位图的画布:

private void doDraw(Canvas canvas) {
    for (int i=0;i<8;i++)
        for (int j=0;j<9;j++)
            for (int k=0;k<7;k++)   {
    canvas.drawBitmap(mBits[allBits[i][j][k]], i*50 -k*7, j*50 -k*7, null); } }
Run Code Online (Sandbox Code Playgroud)

(画布在"run()"中定义/ SurfaceView存在于GameThread中.)

我的第一个问题是如何清除(或重绘)整个画布以获得新的布局?
其次,如何更新屏幕的一部分?

// This is the routine that calls "doDraw":
public void run() {
    while (mRun) {
        Canvas c = null;
        try {
            c = mSurfaceHolder.lockCanvas(null);
            synchronized (mSurfaceHolder) {
                if (mMode == STATE_RUNNING) 
                    updateGame();
                doDraw(c);          }
        } finally {
            if (c != null) {
                mSurfaceHolder.unlockCanvasAndPost(c);  }   }   }       }
Run Code Online (Sandbox Code Playgroud)

Sil*_*ria 270

使用PorterDuff清除模式绘制透明色可以实现我想要的技巧.

Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
Run Code Online (Sandbox Code Playgroud)

  • 这对我不起作用,留下空白表面而不是透明 (4认同)
  • 实际上,`Color.TRANSPARENT`是不必要的.`PorterDuff.Mode.CLEAR`足以用于`ARGB_8888`位图,这意味着将alpha和颜色设置为[0,0].另一种方法是使用`Color.TRANSPARENT`和`PorterDuff.Mode.SRC`. (3认同)
  • 这应该有效,但似乎在4.4(至少在N7.2上)使用`Bitmap#eraseColor(Color.TRANSPARENT)`,如下面的HeMac答案. (2认同)

Wro*_*lai 71

如何清除(或重绘)WHOLE画布以获得新布局(=在游戏中尝试)?

只需打电话Canvas.drawColor(Color.BLACK),或任何你想要清除你的颜色Canvas.

而且:我怎样才能更新屏幕的一部分?

由于Android OS在更新屏幕时重新绘制每个像素,因此没有这样的方法只更新"屏幕的一部分".但是,当你没有清除你Canvas的旧图纸时,旧的图纸仍然在表面上,这可能是"仅更新屏幕的一部分"的一种方式.

因此,如果您想"更新屏幕的一部分",请避免调用Canvas.drawColor()方法.

  • 不,如果你不绘制表面中的每个像素,你将得到非常奇怪的结果(因为通过交换指针实现双缓冲,所以在你没有绘制的部分你将看不到之前的那些).你*在每次迭代时都要重绘表面的每个像素. (4认同)
  • @ViktorLannér:如果你调用`mSurfaceHolder.unlockCanvasAndPost(c)`然后`c = mSurfaceHolder.lockCanvas(null)`,那么新的`c`不包含与前一个`c`相同的东西.你不能仅仅更新SurfaceView的一部分,这就是我猜的OP. (2认同)
  • 骂我!!! 我只是在游戏开始时才初始化我的阵列而不是在连续的重新开始 - 所以所有旧的棋子仍然"在屏幕上" - 他们只是被重新绘制!对于我的"哑巴",我非常抱歉!感谢你们俩 !!! (2认同)

Ruk*_*ias 30

在谷歌小组中找到了这个,这对我有用..

Paint clearPaint = new Paint();
clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(0, 0, width, height, clearPaint); 
Run Code Online (Sandbox Code Playgroud)

这样可以在保持设置位图的同时删除图形矩形等.

  • 这给了我一个黑色区域 - 而不是我背后的位图:( (3认同)

Der*_*rzu 18

我尝试了@mobistry的答案:

canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);

但它对我没有用.

对我来说,解决方案是:

canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);

也许有人有同样的问题.

  • 答案就是透明。否则,在某些设备上可能会变成黑色。 (3认同)

Rak*_*esh 15

使用Path类的reset方法

Path.reset();
Run Code Online (Sandbox Code Playgroud)


heM*_*Mac 12

mBitmap.eraseColor(Color.TRANSPARENT);

canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
Run Code Online (Sandbox Code Playgroud)

  • 这怎么回事?为什么只要drawColor就可以使用位图? (2认同)

ali*_*ian 6

canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);
Run Code Online (Sandbox Code Playgroud)

  • 请添加您的代码如何解决问题的说明。这被标记为低质量帖子 - [来自评论](http://stackoverflow.com/review/low-quality-posts/15421966) (2认同)