paintComponent(), spelet flyter inte perfekt

Permalänk
Medlem

paintComponent(), spelet flyter inte perfekt

Tjena undrar om jag har gjort rätt

Har en separat tråd som anropar repaint() 60ggr/sec...

Ungefär så här ser paintComponent() ut

OBS. Jag har inte kopierat koden utan bara skrivit ungefär hur det ser ut/förkortat så det kan finnas vissa misstag i koden. Spelet fungerar men jag är inte helt nöjd med flytet och tror det har med hur jag använt paintComponent är det såhär man ska göra?

//Denna ligger i PaintPanel som extendar JPanel och används som spelplanen. public void paintComponent(Graphics g){ super.paintComponent(g); g2 = (Graphics2D) g; //aliens är en arraylist där jag har sparat alla fiender som ska ritas. Så jag loopar igenom den och ritar alla... for(int i=0; i<aliens.size(); i++){ Alien tempAlien = aliens.get(i); g2.drawImage(tempAlien.getImage(), tempAlien.getX(), tempAlien.getY(), this); } //Sedan ska alla missiler som spelarens rymdskepp skjuter ritas...missiles är också en arraylist med alla missiler. for(int i=0; i<missiles.size(); i++){ Missile tempMissile = missiles.get(i); g2.drawImage(tempMissile.getImage(), tempMissile.getX(), tempMissile.getY(), this); } //Rita spelarens rymdskepp g2.drawImage(player.getImage(), player.getX(), player.getY(), this); }

Permalänk
Medlem

Blir det små hack med någon sekunds mellanrum så är det förmodligen garbage collectorn som kickar in. Det enda du kan göra åt det är att hålla hårt om alla objekt du skapar och låta bli att använda metoder från javas bibliotek som skapar temporära objekt åt sig själv, alternativt byta till ett annat språk.

Visa signatur

"Some poor, phoneless fool is probably sitting next to a waterfall somewhere, totally unaware of how angry and scared he's supposed to be." - Duncan Trussell

Permalänk
Medlem
Skrivet av JohnMAD:

Tjena undrar om jag har gjort rätt

Har en separat tråd som anropar repaint() 60ggr/sec...

Ungefär så här ser paintComponent() ut

OBS. Jag har inte kopierat koden utan bara skrivit ungefär hur det ser ut/förkortat så det kan finnas vissa misstag i koden. Spelet fungerar men jag är inte helt nöjd med flytet och tror det har med hur jag använt paintComponent är det såhär man ska göra?

[kod]

Kör du med double buffering? För att få mjuka animationer brukade man åtminstone förr i tiden köra något i stil med:

(0. Buffer B1 visas)

1. Rita all grafik som ska visas till buffer B2. Detta får ta den tid det tar;
2. När allting är färdigt, kopiera B2 till B1
3. Upprepa från 1.

Exempelvis skulle din paintComponent-metod kunna ha en enda uppgift; att rita ut buffer B1 (g.drawImage(0, 0, bufferOne);)
Sedan har du en swap som "målar över" B1 med B2. Buffrarna kan t ex vara BufferedImage eller VolatileImage i standardbiblioteket.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Kör du med double buffering? För att få mjuka animationer brukade man åtminstone förr i tiden köra något i stil med:

(0. Buffer B1 visas)

1. Rita all grafik som ska visas till buffer B2. Detta får ta den tid det tar;
2. När allting är färdigt, kopiera B2 till B1
3. Upprepa från 1.

Exempelvis skulle din paintComponent-metod kunna ha en enda uppgift; att rita ut buffer B1 (g.drawImage(0, 0, bufferOne);)
Sedan har du en swap som "målar över" B1 med B2. Buffrarna kan t ex vara BufferedImage eller VolatileImage i standardbiblioteket.

Gjorde så att koden skrev till b2 och försökte flippa men resultatet blev epilepsi blinkande plus att den gammla grafiken inte försvann utan bara skrevs över. Så ändrade tillbaka :S

Permalänk
Medlem

Kan du förklara bättre hur flytet inte är ok? Missade att du körde repaint() i någon separat tråd, jag antar att du då skyddat dig för alla problem som kommer med det? tex att du inte springer runt och uppdaterar dina aliens när de är på väg att ritas. Det skulle kunna ge en känsla av o-flyt. En annan anledning vore det jag skrev ovan.

Jag känner inte till hur swing fungerar, men annars låter det ju konstigt om inte JPanel redan skulle använda dubbla buffrar per default. Och hade så inte varit fallet så skulle du ha upplevt "epilepsi blinkande" för länge sen. Förmodligen fick du det nu för att du ritade till den främre buffern nu när du försökte göra det manuellt.

Visa signatur

"Some poor, phoneless fool is probably sitting next to a waterfall somewhere, totally unaware of how angry and scared he's supposed to be." - Duncan Trussell

Permalänk

Du måste dubbelbuffra. Detta görs inte automatiskt. http://www.realapplets.com/tutorial/DoubleBuffering.html

Permalänk
Medlem

Har för mig du bör använda 3 buffrar. Om du bara kör med 2 så kan du få problem med vsyncen.

Visa signatur

.

Permalänk
Medlem
Skrivet av JohnMAD:

Gjorde så att koden skrev till b2 och försökte flippa men resultatet blev epilepsi blinkande plus att den gammla grafiken inte försvann utan bara skrevs över. Så ändrade tillbaka :S

Det låter som du målade B1 och B2 omväxlande i paintComponent. Det är alltså INTE meningen att du ska göra detta; du ska bara måla B1. B2 fyller du med data och när den är färdigfylld (dvs. när du har en frame) så kopierar du HELA B2 till B1 i ett rakt svep. Nästa gång paintComponent körs kommer hela innehållet i B1 målas.

edit: för optimal prestanda bör du använda BufferedImage (eller VolatileImage som sagt) för buffern. Om du har en separat tråd som pollar repaint() kan det möjligtvis även behövas trådsynkroniseringen runt kopieringen från B2 till B1 så du inte får en repaint mitt i processen.

Visa signatur

Kom-pa-TI-bilitet