Como ustedes se habran fijado, me ha encantado lo que es manejo de imagenes en java 2d, y es qu esta preciosa la cosa, sobre todo cuando los programadores de sun te dejan muchas formas de hacerlo y tu solo tiens que elegir una, aun asi es bueo concocer como funcionana estads tecnicas en vista de escoger la mejor para cada uno.
Prosiguiendo con el capitulo
3.4. Information on Graphics Capabilities
Ahora se preguntaran, y que si mi tarjeta de video no soporta page flipping ¿como examinamos las capacidades de mi tarjeta de video? pues resulta que ademas de venir muy completo y listo para funcionar el codigo de Andrew hay que agradecer que el libro esta completisimo y ademas viene con un funcion que ilustra algunas de la formas de examinar las capacidades de la tarjeta grafica.
private void reportCapabilities() { GraphicsConfiguration gc = gd.getDefaultConfiguration(); // Capacidad de las imagenes ImageCapabilities imageCaps = gc.getImageCapabilities(); System.out.println("Image Caps. isAccelerated: " + imageCaps.isAccelerated() ); System.out.println("Image Caps. isTrueVolatile: " + imageCaps.isTrueVolatile()); // Capacidad del buffer BufferCapabilities bufferCaps = gc.getBufferCapabilities(); System.out.println("Buffer Caps. isPageFlipping: " + bufferCaps.isPageFlipping()); System.out.println("Buffer Caps. Flip Contents: " + getFlipText(bufferCaps.getFlipContents())); System.out.println("Buffer Caps. Full-screen Required: " + bufferCaps.isFullScreenRequired()); System.out.println("Buffer Caps. MultiBuffers: " + bufferCaps.isMultiBufferAvailable()); } // fin de reportCapabilities() private String getFlipText(BufferCapabilities.FlipContents flip) { if (flip == null) return "false"; else if (flip == BufferCapabilities.FlipContents.UNDEFINED) return "Undefined"; else if (flip == BufferCapabilities.FlipContents.BACKGROUND) return "Background"; else if (flip == BufferCapabilities.FlipContents.PRIOR) return "Prior"; else // if (flip == BufferCapabilities.FlipContents.COPIED) return "Copied"; } // fin de getFlipTest()
reportCapabilities() cisualiza las caracteristicas de las tarjetas graficas, en general, pueden haber muchos objetos GraphicsConfiguration asociados a una sola tarjeta grafica, cada uno representa diferentes modos de dibujo y/o capacidades
El obejto ImageCapabilities permite ver en detalle las caracteristicas de la aceleracion por hardware , isAccelerated() muestra su la aceleracion por hardaware es posible o no. En windows siempre devolvera verdadero la funcion isVolatile() (la imagen se peude perder en la VRam) si isAccelerated() devuelve verdadera
En general trodas las funciones con is… devuelven si la maquina es capaz o no de hacerlo.
getFlipContents() devuelve la tecnica usada por page Flipping:
FlipContents.COPIED -> esta valor significa que los contenidos son copiados a la pantalla
FlipContents.PRIOR -> Inidica que utilizamos el apuntador a la VRam, aunque no es garantizado
3.5. Rendering the Game
El codigo de run() seria:
while(running) { gameUpdate(); screenUpdate();
Como Veran se borran 2 funciones para dar paso a screenUpdate().
private void screenUpdate() // usar renderizado activo { try { gScr = bufferStrategy.getDrawGraphics(); gameRender(gScr); gScr.dispose(); if (!bufferStrategy.contentsLost()) bufferStrategy.show(); else System.out.println("Contents Lost"); // Sincroniza la pantalla en algunos sistemas // En linux arregla algunos problemas Toolkit.getDefaultToolkit().sync(); } catch (Exception e) { e.printStackTrace(); running = false; } } // fin de screenUpdate()
gameRender()
private void gameRender(Graphics gScr) { // limpia la pantalla gScr.setColor(Color.white); gScr.fillRect (0, 0, pWidth, pHeight); gScr.setColor(Color.blue); gScr.setFont(font); //Escribe el numero de frames y el promedio de FPS y UPS gScr.drawString("Average FPS/UPS: " + df.format(averageFPS) + ", " + df.format(averageUPS), 20, 25); // was (10,55) // dibujka el timepo y las cajas usadas gScr.drawString("Time Spent: " + timeSpentInGame + " secs", 10, pHeight-15); gScr.drawString("Boxes used: " + boxesUsed, 260, pHeight-15); // dibuja la pausa y los botones de salida drawButtons(gScr); gScr.setColor(Color.black); // dibuja los elemntos dle juego (gusanos y cajas) obs.draw(gScr); fred.draw(gScr); if (gameOver) gameOverMessage(gScr); } // fin de gameRender()
La diferencia fundamental es que ya no se necesita crear un dibujo fuera de pantalla. eso pasa a ser de initFullScreen añ momento de llamar a createBufferStrategy()
3.6. Finishing Off
El metodo finishOff() es llamado de la misma forma que en UFS().
private void finishOff() /* Tareas que se dene hacer nates de terminar, llamado al final de run() * y via readyForTermination() al momentod e cerrar * no es necesarion en run() pero esta por seguridad */ { if (!finishedOff) { finishedOff = true; printStats(); restoreScreen(); System.exit(0); } } // fin de finishedOff() }
3.7. Displaying the Display Mode
initFullScreen() tien un metodo comenatdo setDisplayMode(), este metodo se usa solo despues de que la aplicacion haya entrado en el modo pantalla completa
la funcion showCurrentMode() devuleve le modo actual de la pantalla
private void showCurrentMode() // imprime los detalles de la resolcuion de pantalla { DisplayMode dm = gd.getDisplayMode(); System.out.println("Current Display Mode: (" + dm.getWidth() + "," + dm.getHeight() + "," + dm.getBitDepth() + "," + dm.getRefreshRate() + ") " ); }
3.8. Changing the Display Mode
¿Por qué cambiar el modo? pues porque necesitamos incrementar la performance, entre menos resolucion de pantalla, menos peso en la data que se transfiere del buffer a la pantlla. aunque esta ventaja es irrelevante si pageflipping es el metod que se usa.
setDisplayMode() es le metodo que hace el cambio.
private void setDisplayMode(int width, int height, int bitDepth) // { if (!gd.isDisplayChangeSupported()) { System.out.println("Display mode changing not supported"); return; } if (!isDisplayModeAvailable(width, height, bitDepth)) { System.out.println("Display mode (" + width + "," + height + "," + bitDepth + ") not available"); return; } DisplayMode dm = new DisplayMode(width, height, bitDepth, DisplayMode.REFRESH_RATE_UNKNOWN); try { gd.setDisplayMode(dm); System.out.println("Display mode set to: (" + width + "," + height + "," + bitDepth + ")"); } catch (IllegalArgumentException e) { System.out.println("Error setting Display mode (" + width + "," + height + "," + bitDepth + ")"); } try { // dormimos para darle chance a la pantalla poder cambiar Thread.sleep(1000); // 1 seg } catch(InterruptedException ex){} } // fin de setDisplayMode()
Ademas se ve si se puede hacer el cmabio de resolucion
private boolean isDisplayModeAvailable(int width, int height, int bitDepth) /* cheka si se peude hacer el cmabio de resolucion */ { DisplayMode[] modes = gd.getDisplayModes(); showModes(modes); for(int i = 0; i < modes.length; i++) { if (width == modes[i].getWidth() && height == modes[i].getHeight() && bitDepth == modes[i].getBitDepth()) return true; } return false; } // fin de isDisplayModeAvailable()
showModes() imprime todos los modos disponibles
private void showModes(DisplayMode[] modes) { System.out.println("Modes"); for(int i = 0; i < modes.length; i++) { System.out.print("(" + modes[i].getWidth() + "," + modes[i].getHeight() + "," + modes[i].getBitDepth() + "," + modes[i].getRefreshRate() + ") " ); if ((i+1)%4 == 0) System.out.println(); } System.out.println(); } // fin de showModes()