2009-12-12 9 views
6

Estaba programando un juego simple y quería mostrarlo a través de la API Java Graphics + Swing. Se sentía un poco lento, por supuesto, así que medí cuánto tiempo tomó volver a pintar, que fue de alrededor de 32 ms. Luego, leí acerca de los gráficos acelerados de Java y utilicé el método descrito aquí: Space Invadersrendimiento gráfico de Java

Sin embargo, de alguna manera esto es aún más lento. Ahora tarda unos 98ms en volver a dibujar. ¿Porqué es eso?

Tenga en cuenta que conozco bibliotecas como LWGL y JOGL, pero no quiero utilizar un contenedor OpenGL completo para un juego tan simple.

+1

¿Puedes publicar algo de tu código de pintura? y lógica de reloj/temporizador? – basszero

+0

La lógica de reloj/temporizador es simplemente la diferencia de dos valores largos obtenidos a través de System.currentTimeMillis().Sé que no es un buen enfoque para medir el tiempo de esta manera, pero solo quería un cálculo aproximado de cuánto tiempo lleva. El código de pintura simplemente dibuja una imagen estática en el lienzo. Así que solo es g.drawImage (img, 0, 0, null) donde g se obtiene a través de la variable BufferStrategy. –

Respuesta

6
  1. Leer this sobre temporizadores
  2. utilizar un hilo de dormir siempre en segundo plano para reducir la tasa de interrupción del sistema para obtener contadores de tiempo mucho más precisos!
  3. Puede echar un vistazo a mi código en here
  4. Un pequeño juego que he creado se puede encontrar here

    long renderStart = System.nanoTime() 
    // render stuff here 
    long renderTime = (System.nanoTime() - renderStart)/1000000; 
    
+0

He descargado su biblioteca (Bonsai). Pero tengo una pregunta: usted hizo una clase 'Game Engine '. ¿Cuál es el propósito aquí (traducción de Google)? –

+0

En realidad, tuve un problema con mi complemento Eclipse SVN, por lo que no eliminó el archivo de forma remota. Justo hoy eliminé el archivo a través de otro cliente SVN ... que bloqueó todo el proyecto del eclipse, así que tuve que reconstruirlo, lo que de alguna manera destruyó el repositorio: D Entonces, el archivo es simplemente un sobrante del desarrollo, en algún momento que quería factorizar el motor real desde el applet/gui. –

+0

gracias (15 caracteres) –

6

La oscilación será lenta para un juego. Su mejor opción es probablemente un contenedor SDL, como jsdl o sdljava. SDL es bastante liviano y es compatible con muchas plataformas.

Lo bueno es que los envoltorios de la biblioteca de gráficos 2d bien implementados implementan la interfaz Graphics, por lo que debería poder probar varios y ver cuál funciona mejor para su aplicación sin modificar su código.

+0

Tanto jsdl como sdljava están muy fuera de datos hoy en día. La mayoría de las personas que buscan un alto rendimiento de gráficos en Java simplemente usan OpenGL directamente, p. via LWJGL (http://lwjgl.org/) – mikera

1

Estoy de acuerdo con Nicolas, para el procesamiento de gráficos/interactividad es grande

1

Trate JGame. Es un motor simple para juegos en 2D que usa GL cuando está disponible y puede producir juegos que se ejecutan en cualquier cosa, desde un teléfono móvil hasta un sistema de escritorio.

1

En primer lugar, usted debe comprobar y ver la cantidad de tiempo se gasta en su propio código, en comparación con la cantidad de tiempo que se dedica realmente al dibujo del marco. Puede tener algún error o falla que lo haga funcionar más lentamente.

Debería poder obtener un rendimiento mucho mejor que 98ms para dibujar la pantalla. Esas bibliotecas de juegos probablemente usarán las mismas llamadas gráficas que usted. Pero los contenedores que usa pueden tener un gran impacto en la rapidez con que se dibujan las cosas. Recuerdo que hace un par de meses que trabajaba en un código de gráficos con búfer doble y cómo se creó el búfer posterior hizo una gran diferencia en el rendimiento.

En particular, asegúrese de crear solo una imagen de fondo una vez o al menos, solo cuando cambie el tamaño de su lienzo. En mi código sorteo hago esto:

 //create a graphics backplane 
    if(backplane == null || !backplaneSize.equals(this.getSize())){ 
     backplane = this.createImage((int)this.getSize().getWidth(), (int)this.getSize().getHeight()); 
     backplaneSize = this.getSize(); 
    } 

Así que el avión de vuelta solamente se crea si es nuevo o si se cambia el tamaño del componente. Esto tiene un gran impacto en la velocidad.

He estado haciendo programación de gráficos en Java desde JDK 1.0. De hecho, nunca había escuchado sobre esta cosa de BufferStrategy. Je.

Nunca he tenido problemas para obtener buenas velocidades de cuadros con llamadas básicas de gráficos java. Otra cosa a tener en cuenta es asegurarse de que Swing no intente borrar el fondo de su componente por usted. Esa puede ser otra fuente de desaceleración.

3

No soy un experto, pero Java2D admite diferentes tuberías de representación. En mi máquina, el cambio a la OpenGL uno mediante el establecimiento de la propiedad del sistema

sun.java2d.opengl = true

produjo un aumento sustancial de la velocidad de renderizado.

6

Algunas sugerencias para mejorar el rendimiento:

  1. Clip y simplemente dibujar el área que ha cambiado
  2. no escalan nada cuando dibujo
  3. utilizar la estrategia correcta memoria intermedia
  4. Uso full screen exclusive mode si apropiado.

La oscilación no es inherentemente lenta. La mayor parte de la confusión sobre Swing proviene de personas que no conocen ni entienden el tema del envío del evento (y sí, es un gran esfuerzo hacer las cosas bien).

En cuanto a sus tiempos, ¿solo está llamando a g.drawImage entre las configuraciones de tiempo? De ser así, ¿de qué tamaño está repintando y está haciendo escala en esta llamada?

EDIT: Ha olvidado mencionar Pulp Core - un marco de juego muy agradable para Java.

1

El rendimiento de Java2D es un poco oscuro. Puede variar entre plataformas, pero es posible hacerlo funcionar bien.

A veces, hacer cosas aparentemente inocuas puede resultar en un rendimiento mucho más lento. Desea asegurarse de que es using accelerated images as much as possible.

La type de la imagen también puede ser significativa. No conozco todos los detalles, pero sí sé que mis programas fueron mucho más rápidos usando imágenes de tipo 1 (INT RGB) que otros tipos como el tipo 5 (3BYTE BGR) debido a problemas de conversión.

1

No puedo decir exactamente lo que está haciendo. Tu pregunta es sobre Swing pero mencionas un Canvas y una Bufferstrategy. Bueno, en Swing usaría un JPanel que tiene doble buffer automáticamente para que no tenga que preocuparse por eso.

Probé una animación simple con 1000 bolas en movimiento. El temporizador estaba configurado para disparar cada 100 ms. Cuando se disparaba el temporizador, la bola 1000 se movía aleatoriamente a una nueva posición y se creaba una imagen Buffered nueva y se repintaba el panel que mostraba la imagen. La diferencia en el tiempo entre el repintado fue de 110 ms, lo que implica que solo tomó 10 ms crear una nueva Imagen Buffered y hacer la pintura. La pintura se realizó a pantalla completa, por lo que no se realizó ningún recorte.

Este posting muestra el código de ejemplo que probé.

+0

Si desea medir el tiempo para algo rápido, la mejor manera es usar System.nanoTime() (agregado en JDK 1.5), que mide en nanosegundos. No es tan preciso durante largos períodos como System.currentTimeMillis, pero por períodos cortos es obviamente más eficiente. –

Cuestiones relacionadas