Kezdőlap > elmélet > Duplabufferelés

Duplabufferelés

Dobjunk fel a formunkra egy rajzvásznat (vagy nevezzük canvasnak, ha úgy tetszik), rajzoljunk rá valamit, majd töröljük le. Tegyük ezt meg újra és újra, sokszor egymás után. Ha csak kicsit változik a kép, és ezt elég sűrűn teszi, akkor úgy tűnik, minhta mozognának az alakzatok a vásznon. Innen már csak egy ötlet és kitartás kérdése, s már is egy egyszerű kis játék büszke szerzői lehetünk.

Az örömünk mégsem teljes, mert a kép furcsán villódzik. Érthető is ez, mert ha csak a másodperc tört részére, de akkor is letöröljük a képernyőt és ezalatt csak a nagy fehérség látszik, aztán megint a kép, amit mutatni szeretnénk. Idegesítő jelenség, de szerencsére a megoldást tálcán nyújtják felénk csak el kell fogadni.

Felveszünk a háttérben egy másik vásznat, ami rejtett a felhasználó előtt. Erre rajzolgatunk, s majd ha kész, akkor kirajzoljuk a látható vászonra is.

Ez így mind szép és jó, de az implementáció tartogat néhány buktatót. Szóval akkor lássuk is. JAVAban természetesen.

Két megoldást is találtam. Az első, ami a “józan paraszti ész” csapásirányát követi és ezáltal a nyelvi lehetőségeket nem annyira használja ki. Létrehozunk egy rejtett vásznat (Image), meg egy Graphics objektumot, amivel tudunk rá rajozlni. A paint() metódusban rajzolgatunk kedvünkre, de ezt a rejtett vászonra tesszük. S majd a legvégén az egész képet egyszerre rajzoljuk ki a látható Canvasra. (Ne felejtsük el letörölni rajzolás előtt a vásznat!)

Példakód:

public class myCanvas extends Canvas {

	Image bufferImage;
	Graphics bufferGraphics;

	public void paint(Graphics g){
		// letöröljük a vásznat
		bufferGraphics.clearRect(0, 0, getWidth(), getHeight());
		// itt rajzolgatunk, amit akarunk,
		// de ezt a rejtett vászonra tegyük pl:
		bufferGraphics.setColor(Color.RED);
		bufferGraphics.drawRoundRect(200, 200, 150, 100, 10, 15);
		...
		// kirajzoljuk a rejtett vásznat
		g.drawImage(bufferImage, 0, 0, null);
	}

	public void update(Graphics g){
		// ez alapból letörli a Canvast,
		// ezután pedig meghívja a paint metódust
		// a letörlést mi végezzük
		// különben is ez okozza a villódzást,
		// ezért most ezt mellőzük
		paint(g);
	}

	// elvégzi a rejtett és a látható vászon összerendelését.
	// ezt csak akkor tehetjük meg, ha már látható a Canvas!!!
	public void setDubleBuffer() {
		bufferImage = createImage(getWidth(), getHeight());
		bufferGraphics = bufferImage.getGraphics();
	}
}

A másik lehetőség jobban kihasználja, hogy már mások is gondoltak erre a megoldásra, ezért jobban integrált nyelvi elemeket is adtak a kezünkbe.

Ebben az esetben nem piszkálunk bele a paint() metóduba, hanem ehelyett a az update() metódust módosítjuk. A duplabuffer kialakítását pedig a Canvas osztály void createBufferStrategy(int bufferlayers) metódusával végezzük, amit a setDubleBuffer metódusunkhoz hasonlóan csak a Canvas megjelenítése után futtathatunk.

Példakód (Canvas osztály update metódusának overloadingja):

    public void update(Graphics g) {
        BufferStrategy b = getBufferStrategy();
        Graphics graph = b.getDrawGraphics();
        graph.clearRect(0, 0, getWidth(), getHeight());
        paint(graph);
        graph.dispose();
        b.show();
    }

A formunkon a következő képpen alakítható ki a duplabuffer:


        // mindenképpen láthatónak kell lennie a Canvasnak!!!
        form.setVisible(true);
        mycanvas.createBufferStrategy(2);

Bármelyik megoldást is választjuk, az eredmény ugyanaz. A megjelenítés nem villódzik, kényelmes a szemnek, és csupa jóság.

Megszenvedtem a wordpress szövegszerkesztőjével, szóval tessék megbecsülni. Meg is ijedtem, hogy ha ilyen szenvedés itt kódot beilleszteni és olvashatóra formázni, akkor virágzó kapcsolatom a wordpress-szel hamar derékba törik…

Kategóriák:elmélet Címkék:, ,

MINDEN VÉLEMÉNY SZÁMÍT!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Módosítás )

Twitter kép

You are commenting using your Twitter account. Log Out / Módosítás )

Facebook kép

You are commenting using your Facebook account. Log Out / Módosítás )

Kapcsolódás: %s

Follow

Get every new post delivered to your Inbox.