Tijdens het maken van een spel in java zijn we een aantal problemen tegen gekomen: namelijk zonder te bufferen gaan je images schokkend worden getekend.
Eerste oplossing: zelf dubbel buffering doen: een private Image buffer bijhouden. Wanneer je iets wil tekenen, tekenen op de buffer. Om de zoveel milliseconden schrijf je de buffer dan weg naar je ECHTE graphics2D.
Probleem: deze methode werkt alleen bij AWT. Waarom? Omdat de update methode bij swing components niet meer wordt opgeroepen. (awt: repaint >> update >> paint || swing: repaint >> paint). Voorbeeld van die update methode:
Het probleem is dat we swing gebruiken.
tweede mogelijke oplossing:
Sinds java 1.4 is er de klasse BufferStategy bijgekomen. Deze inkapsuleert de dubbel buffering voor u (dubbel buffering, page flipping, gebruikmakend van de hardware, wanneer deze aanwezig zou zijn) Hij kijkt namelijk of pageflipping mogelijk is en dan gebruikt hij daar de hardware mogelijkheden voor.
Voor het aanmaken van de bufferStrategy is er de methode createBufferStrategy(iint aantalBuffers).
Het probleem hierbij is dat dit niet werkt!!: hij tekent maar het hapert verschrikkelijk en lijkt alsof het niet gedubbelbufferd is.
We testen op twee pc's tegelijk: één laptop met ati radeon 7500 en een gewone pc met een geforce mx.
We hebben het boek van Dave Brackeen gebruikt: Developing Games in Java. Hij heeft een ScreenManager geschreven die te vinden is op: http://www.brackeen.com/javagamebook/ (chapter 2)
Dit is de methode uit de klasse ScreenManager om fullscreen te gaan:
Het probleem is dat op de ene pc mijn muisaanwijzer flikkert. Wat is het verschil tussen 1 2 of 3 meegeven bij die createBufferStrategy? Als je 1 meegeeft, betekent dat dat er één buffer wordt gebruikt die om de zoveel seconden dan automatisch wordt weggeschreven??
In de main van onze game:
Eerst en vooral wordt dan een NullREpaintManager.install() opgeroepen. Deze bevat een nullpaintManager die NIETS doet: dus gewoon methodes leeg geimplementeerd.
Ik teken zowieso op de ScreenManager.getGraphics elke keer.
De game loop (screen is instantie van ScreenManager):
Bon.. we hebben er al enkele dagen op zitten zoeken, het internet afschuimen en we krijgen er grijze haren van!!!
Eerste oplossing: zelf dubbel buffering doen: een private Image buffer bijhouden. Wanneer je iets wil tekenen, tekenen op de buffer. Om de zoveel milliseconden schrijf je de buffer dan weg naar je ECHTE graphics2D.
Probleem: deze methode werkt alleen bij AWT. Waarom? Omdat de update methode bij swing components niet meer wordt opgeroepen. (awt: repaint >> update >> paint || swing: repaint >> paint). Voorbeeld van die update methode:
Java:
1
2
3
4
5
| if (offScreenImage == null) { offScreenImage = this.createImage(4000,2000); } paint(offScreenImage.getGraphics()); g.drawImage(offScreenImage,0,0,this); |
Het probleem is dat we swing gebruiken.
tweede mogelijke oplossing:
Sinds java 1.4 is er de klasse BufferStategy bijgekomen. Deze inkapsuleert de dubbel buffering voor u (dubbel buffering, page flipping, gebruikmakend van de hardware, wanneer deze aanwezig zou zijn) Hij kijkt namelijk of pageflipping mogelijk is en dan gebruikt hij daar de hardware mogelijkheden voor.
Voor het aanmaken van de bufferStrategy is er de methode createBufferStrategy(iint aantalBuffers).
Het probleem hierbij is dat dit niet werkt!!: hij tekent maar het hapert verschrikkelijk en lijkt alsof het niet gedubbelbufferd is.
We testen op twee pc's tegelijk: één laptop met ati radeon 7500 en een gewone pc met een geforce mx.
We hebben het boek van Dave Brackeen gebruikt: Developing Games in Java. Hij heeft een ScreenManager geschreven die te vinden is op: http://www.brackeen.com/javagamebook/ (chapter 2)
Dit is de methode uit de klasse ScreenManager om fullscreen te gaan:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| public void setFullScreen(DisplayMode displayMode) { final JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setUndecorated(true); frame.setIgnoreRepaint(true); frame.setResizable(false); device.setFullScreenWindow(frame); if (displayMode != null && device.isDisplayChangeSupported()) { try { device.setDisplayMode(displayMode); } catch (IllegalArgumentException ex) { } // fix for mac os x frame.setSize(displayMode.getWidth(), displayMode.getHeight()); } // avoid potential deadlock in 1.4.1_02 try { EventQueue.invokeAndWait(new Runnable() { public void run() { frame.createBufferStrategy(3); } }); } catch (InterruptedException ex) { // ignore } catch (InvocationTargetException ex) { // ignore } } |
Het probleem is dat op de ene pc mijn muisaanwijzer flikkert. Wat is het verschil tussen 1 2 of 3 meegeven bij die createBufferStrategy? Als je 1 meegeeft, betekent dat dat er één buffer wordt gebruikt die om de zoveel seconden dan automatisch wordt weggeschreven??
In de main van onze game:
Eerst en vooral wordt dan een NullREpaintManager.install() opgeroepen. Deze bevat een nullpaintManager die NIETS doet: dus gewoon methodes leeg geimplementeerd.
Ik teken zowieso op de ScreenManager.getGraphics elke keer.
De game loop (screen is instantie van ScreenManager):
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| while (true) { try { //draw our graphics Graphics2D g = screen.getGraphics(); pnlMapFrontend.update(g); //draw swing graphics JFrame f = screen.getFullScreenWindow(); //f.getLayeredPane().paintComponents(g); screen.getGraphics().dispose(); screen.update(); Thread.sleep(20); } catch (Exception e) { } } |
Bon.. we hebben er al enkele dagen op zitten zoeken, het internet afschuimen en we krijgen er grijze haren van!!!