Afin de faire un jeu simple, j'ai utilisé un modèle qui dessine une toile 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 ()"/la SurfaceView vit dans un GameThread.)
Ma première question est de savoir comment effacer (ou redessiner) le canevas entier pour une nouvelle mise en page?
Deuxièmement, comment puis-je mettre à jour une partie seulement 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 effacer (ou redessiner) la toile ENTIÈRE pour une nouvelle mise en page (= essayer le jeu)?
Appelez simplement Canvas.drawColor(Color.BLACK)
, ou la couleur de votre choix pour effacer votre Canvas
avec.
Et: comment puis-je mettre à jour juste une partie de l'écran?
Aucune méthode de ce type ne met à jour une "partie de l'écran" depuis Android l'OS redessine chaque pixel lors de la mise à jour de l'écran. Toutefois, lorsque vous n'effacez pas d'anciens dessins sur votre Canvas
, les anciens dessins sont toujours à la surface et c'est probablement un moyen de "mettre à jour une partie seulement" de l'écran.
Donc, si vous voulez "mettre à jour une partie de l'écran", évitez simplement d'appeler la méthode Canvas.drawColor()
.
Dessinez des couleurs transparentes avec le mode clair PorterDuff, faites ce que je voulais.
Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
Trouvé cela dans les groupes de Google 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 dessin, etc. tout en conservant la définition bitmap.
J'ai essayé la réponse de @mobistry:
canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
Mais ça n'a pas fonctionné pour moi.
La solution, pour moi, était la suivante:
canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);
Peut-être que quelqu'un a le même problème.
utiliser la méthode reset de la classe Path
Path.reset();
mBitmap.eraseColor(Color.TRANSPARENT);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
veuillez coller ci-dessous le code sur le constructeur de la classe d’extension surfaceview .............
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
<com.welcome.panelview.PanelViewWelcomeScreen
Android:id="@+id/one"
Android:layout_width="600px"
Android:layout_height="312px"
Android:layout_gravity="center"
Android:layout_marginTop="10px"
Android:background="@drawable/welcome" />
essayez le code ci-dessus ...
Pour moi, appeler Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
ou quelque chose de similaire ne fonctionnerait que lorsque je toucherais l'écran. SO J'appellerais la ligne de code ci-dessus, mais l'écran ne s'effacerait qu'après avoir touché l'écran. Ce qui a bien fonctionné pour moi a donc été 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();
}
canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);
Voici le code d'un exemple minimal montrant qu'il faut toujours redessiner chaque pixel du canevas à chaque image.
Cette activité dessine un nouveau bitmap toutes les secondes sur le SurfaceView, sans vider l’écran auparavant. Si vous le testez, vous verrez que le bitmap n'est pas toujours écrit dans le même tampon, et 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();
}
}
}
}
}
N'oubliez pas d'appeler invalidate ();
canvas.drawColor(backgroundColor);
invalidate();
path.reset();
Avec l'approche suivante, vous pouvez effacer la totalité ou une partie de la toile.
N'oubliez pas de désactiver l'accélération matérielle car PorterDuff.Mode.CLEAR ne fonctionne pas avec l'accélération matérielle et appelle enfin setWillNotDraw(false)
, car nous remplaçons le onDraw
méthode.
//view's constructor
setWillNotDraw(false);
setLayerType(LAYER_TYPE_HARDWARE, null);
//view's onDraw
Paint TransparentPaint = new Paint();
TransparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(0, 0, width, height, TransparentPaint);