2009-12-12 14 views
6

Stavo programmando un gioco semplice e volevo visualizzarlo tramite l'API Java Graphics + Swing. Mi sentivo un po 'lento, naturalmente, quindi ho misurato quanto tempo ci è voluto per ridipingere, che era di circa 32ms. Poi ho letto della grafica Java accelerata e ho usato il metodo descritto qui: Space InvadersPrestazioni grafiche Java

Tuttavia, in qualche modo questo è ancora più lento. Ora ci vogliono circa 98ms per ridisegnare. Perché?

Nota che sono a conoscenza di librerie come LWGL e JOGL, ma non voglio utilizzare un wrapper OpenGL in piena regola per un gioco così graficamente semplice.

+1

Puoi pubblicare un po 'del tuo codice pittura? e la logica orologio/timer? – basszero

+0

La logica orologio/timer è semplicemente la differenza di due valori lunghi ottenuti tramite System.currentTimeMillis().So che non è un buon approccio per misurare il tempo in questo modo, ma volevo solo una stima approssimativa di quanto tempo ci vuole. Il codice del disegno disegna semplicemente un'immagine statica sulla tela. Quindi è solo g.drawImage (img, 0, 0, null) dove g è ottenuto tramite la variabile BufferStrategy. –

risposta

6
  1. this Leggi su timer
  2. utilizzare un filo sempre dormire in background per abbassare il tasso di interruzione del sistema per ottenere i timer molto più precisi!
  3. Potete dare un'occhiata al mio codice in here
  4. Un piccolo gioco che ho creato può essere trovato here

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

Ho scaricato la tua libreria (Bonsai). Ma ho una domanda: hai fatto un gioco di classe 'GameEngine'. Qual è lo scopo qui (traduzione di Google)? –

+0

In realtà ho avuto un problema con il mio plugin SVN Eclipse, quindi non ha eliminato il file da remoto. Proprio oggi ho cancellato il file tramite un altro client SVN ... che ha fatto crashare l'intero progetto eclipse, quindi ho dovuto ricostruirlo che poi in qualche modo ha distrutto il repository: D Quindi il file è solo un residuo dello sviluppo, a volte volevo per calcolare il motore attuale dall'applet/gui. –

+0

thanks (15 caratteri) –

6

L'oscillazione sarà lenta per una partita. La soluzione migliore è probabilmente un wrapper SDL, ad esempio jsdl o sdljava. SDL è abbastanza leggero e supportato su molte piattaforme.

La cosa bella è che i wrapper di librerie grafiche 2d ben implementate implementano l'interfaccia Graphics, quindi dovresti essere in grado di provarne diversi e vedere quale si comporta meglio per la tua app senza modificare il codice.

+0

Oggigiorno jsdl e sdljava sono molto fuori dai dati. La maggior parte delle persone che cercano prestazioni grafiche elevate su Java usano semplicemente OpenGL direttamente, ad es. via LWJGL (http://lwjgl.org/) – mikera

1

Concordo con Nicolas, per elaborazione grafica/interattività è grande

1

Prova JGame. È un motore semplice per giochi 2D che usa GL quando è disponibile e può produrre giochi che funzionano su qualsiasi cosa, da un telefono cellulare a un sistema desktop.

1

Prima di tutto, si dovrebbe controllare e vedere quanto tempo viene speso nel proprio codice rispetto a quanto tempo viene speso effettivamente per disegnare la cornice. Potresti avere qualche bug o malfunzionamento che lo fa girare più lentamente.

Si dovrebbe essere in grado di ottenere prestazioni migliori di 98 ms per disegnare lo schermo. Queste librerie di giochi probabilmente useranno le stesse chiamate grafiche come faresti tu. Ma quali contenitori usi possono avere un grande impatto sulla rapidità con cui le cose si disegnano. Ricordo un paio di mesi fa che lavoravo su un codice grafico a doppio buffering, e come il buffer posteriore è stato creato ha fatto un'enorme differenza nelle prestazioni.

In particolare, assicuratevi di creare solo un'immagine di sfondo una volta o almeno, solo quando la tela viene ridimensionata. Nel mio codice pareggio faccio questo:

 //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(); 
    } 

Così l'aereo per tornare solo si crea se si tratta di nuovo, o se il componente viene ridimensionato. Questo ha un impatto enorme sulla velocità.

Ho eseguito la programmazione grafica in Java da JDK 1.0. In realtà non avevo mai sentito parlare di questa cosa di BufferStrategy. Eh.

Non ho mai avuto problemi a ottenere una buona frequenza di fotogrammi con le chiamate di grafica java di base. Un'altra cosa da tenere a mente è assicurarsi che Swing non stia cercando di cancellare lo sfondo del componente per te. Questa può essere un'altra fonte di rallentamento.

3

Non sono un esperto, ma Java2D supporta diverse pipeline di rendering. Sulla mia macchina, il passaggio al OpenGL uno impostando la proprietà di sistema

sun.java2d.opengl = true

ha prodotto un aumento sostanziale della velocità di rendering.

6

Alcuni suggerimenti per migliorare le prestazioni:

  1. Clip e solo disegnare l'area che ha cambiato
  2. non scala nulla quando disegno
  3. Usa la strategia tampone corretto
  4. Usa full screen exclusive mode se adeguata.

L'oscillazione non è intrinsecamente lenta. La maggior parte della confusione su Swing proviene da persone che non conoscono o non capiscono il thread di invio degli eventi (e sì, è molto impegnativo farlo bene).

Per quanto riguarda i tempi, stai chiamando g.drawImage tra le impostazioni dell'ora? In caso affermativo, che dimensioni stai ridipingendo e stai effettuando un ridimensionamento per questa chiamata?

MODIFICA: Dimenticato menzionare Pulp Core - un framework di gioco molto bello per Java.

1

Le prestazioni di Java2D sono un po 'oscure. Può variare tra piattaforme, ma è possibile farlo funzionare bene.

A volte azioni apparentemente innocue possono comportare prestazioni molto più lente. Vuoi assicurarti di essere using accelerated images as much as possible.

L'immagine type può anche essere significativa. Non conosco tutti i dettagli, ma so che i miei programmi erano molto più veloci con le immagini di tipo 1 (RGB INT) rispetto ad altri tipi come il tipo 5 (3BYTE BGR) a causa di problemi di conversione.

1

Non riesco a dire esattamente cosa stai facendo. La tua domanda riguarda Swing, ma menzioni una Canvas e una Bufferstrategy. Bene, in Swing useresti un JPanel che viene automaticamente con doppio buffering, quindi non devi preoccuparti di questo.

Ho testato una semplice animazione con 1000 sfere mobili. Il Timer era impostato per sparare ogni 100ms. Quando il Timer ha sparato, la palla da 1000 dove si è spostata a caso in una nuova posizione e una nuova BufferedImage è stata creata e il pannello che mostrava l'immagine è stato ridipinto. La differenza di tempo tra la ridipintatura era di 110ms, il che implicava solo 10ms per creare una nuova BufferedImage e fare il dipinto. Il dipinto è stato fatto a schermo intero, quindi non è stato effettuato alcun ritaglio.

Questo posting mostra il codice di esempio che ho provato.

+0

Se si desidera misurare il tempo per qualcosa di veloce, il modo migliore è utilizzare System.nanoTime() (aggiunto in JDK 1.5), che misura in nanosecondi. Non è accurato per lunghi periodi come System.currentTimeMillis, ma per brevi periodi è ovviamente più efficiente. –