Android, canvas: Comment effacer (supprimer le contenu de) un canevas (= bitmaps), vivant dans une SurfaceView?

Pour créer un jeu simple, j’ai utilisé un modèle qui dessine un canevas avec des bitmaps comme ceci:

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); } } 

(Le canevas est défini dans “run ()” / le SurfaceView réside dans un GameThread).

Ma première question est la suivante: comment puis-je effacer (ou redessiner) la canvas entière pour une nouvelle mise en page?
Deuxièmement, comment puis-je mettre à jour une partie de l’écran?

 // 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); } } } } 

Comment puis-je effacer (ou redessiner) la canvas WHOLE pour une nouvelle mise en page (= essayer au jeu)?

Appelez simplement Canvas.drawColor(Color.BLACK) ou la couleur avec laquelle vous souhaitez effacer votre Canvas .

Et: comment puis-je mettre à jour une partie de l’écran?

Il n’existe pas de méthode permettant simplement de mettre à jour une “partie de l’écran” car Android OS redessine chaque pixel lors de la mise à jour de l’écran. Mais, lorsque vous ne videz pas d’anciens dessins sur votre Canvas , les anciens dessins sont toujours en surface et c’est probablement l’une des manières de «mettre à jour une partie» de l’écran.

Donc, si vous voulez “mettre à jour une partie de l’écran”, évitez simplement d’appeler la méthode Canvas.drawColor() .

Dessiner une couleur transparente avec PorterDuff en mode clair fait le tour de ce que je voulais.

 Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR) 

J’ai trouvé cela dans Google groupes et cela a fonctionné pour moi ..

 Paint clearPaint = new Paint(); clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); canvas.drawRect(0, 0, width, height, clearPaint); 

Cela supprime les rectangles de dessins, etc. tout en conservant le bitmap défini.

J’ai essayé la réponse de @mobistry:

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

Mais ça n’a pas marché pour moi.

La solution pour moi était:

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

Peut-être que quelqu’un a le même problème.

 mBitmap.eraseColor(Color.TRANSPARENT); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 

utiliser la méthode de réinitialisation de la classe Path

 Path.reset(); 

s’il vous plaît coller ci-dessous le code sur surfaceview extend class constructeur ………….

codage constructeur

  SurfaceHolder holder = getHolder(); holder.addCallback(this); SurfaceView sur = (SurfaceView)findViewById(R.id.surfaceview); sur.setZOrderOnTop(true); // necessary holder = sur.getHolder(); holder.setFormat(PixelFormat.TRANSPARENT); 

codage xml

   

essayez le code ci-dessus …

Pour moi, appeler Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR) ou quelque chose de similaire ne fonctionnerait qu’après avoir touché l’écran. J’appellerais donc la ligne de code ci-dessus, mais l’écran ne disparaîtrait qu’après avoir touché l’écran. Donc, ce qui a fonctionné pour moi était d’appeler invalidate() suivi de init() qui est appelé au moment de la création pour initialiser la vue.

 private void init() { setFocusable(true); setFocusableInTouchMode(true); setOnTouchListener(this); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setColor(Color.BLACK); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(6); mCanvas = new Canvas(); mPaths = new LinkedList<>(); addNewPath(); } 

Voici le code d’un exemple minimal montrant que vous devez toujours redessiner chaque pixel du canevas à chaque image.

Cette activité dessine une nouvelle bitmap par seconde sur SurfaceView, sans effacer l’écran auparavant. Si vous le testez, vous verrez que le bitmap n’est pas toujours écrit dans le même tampon et que l’écran alterne entre les deux tampons.

Je l’ai testé sur mon téléphone (Nexus S, Android 2.3.3), et sur l’émulateur (Android 2.2).

 public class TestCanvas extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new TestView(this)); } } class TestView extends SurfaceView implements SurfaceHolder.Callback { private TestThread mThread; private int mWidth; private int mHeight; private Bitmap mBitmap; private SurfaceHolder mSurfaceHolder; public TestView(Context context) { super(context); mThread = new TestThread(); mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon); mSurfaceHolder = getHolder(); mSurfaceHolder.addCallback(this); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mWidth = width; mHeight = height; mThread.start(); } @Override public void surfaceCreated(SurfaceHolder holder) {/* Do nothing */} @Override public void surfaceDestroyed(SurfaceHolder holder) { if (mThread != null && mThread.isAlive()) mThread.interrupt(); } class TestThread extends Thread { @Override public void run() { while (!isInterrupted()) { Canvas c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { c.drawBitmap(mBitmap, (int) (Math.random() * mWidth), (int) (Math.random() * mHeight), null); } } finally { if (c != null) mSurfaceHolder.unlockCanvasAndPost(c); } try { sleep(1000); } catch (InterruptedException e) { interrupt(); } } } } } 

Canvas.drawColor (Color.TRANSPARENT, PorterDuff.Mode.CLEAR)

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

J’ai dû utiliser une passe de dessin séparée pour effacer la canvas (verrouiller, dessiner et déverrouiller):

 Canvas canvas = null; try { canvas = holder.lockCanvas(); if (canvas == null) { // exit drawing thread break; } canvas.drawColor(colorToClearFromCanvas, PorterDuff.Mode.CLEAR); } finally { if (canvas != null) { holder.unlockCanvasAndPost(canvas); } } 

Votre première exigence, comment effacer ou redessiner un canevas entier – Réponse – utilisez la méthode canvas.drawColor (color.Black) pour effacer l’écran avec une couleur noire ou celle que vous spécifiez.

Votre deuxième exigence, comment mettre à jour une partie de l’écran – Réponse – par exemple si vous souhaitez que toutes les autres choses restnt inchangées sur l’écran mais dans une petite zone de l’écran pour afficher un nombre entier (par exemple compteur) qui augmente toutes les cinq secondes. utilisez ensuite la méthode canvas.drawrect pour dessiner cette petite zone en spécifiant la partie inférieure droite et la peinture. puis calculez la valeur de votre compteur (en utilisant une sauvegarde différée de 5 secondes, etc.), convertissez-le en chaîne de texte, calculez les coordonnées x et y dans ce petit rectangle et utilisez la vue texte pour afficher le changement. valeur de compteur.

Il suffit d’appeler

canvas.drawColor (Color.TRANSPARENT)