PDA

View Full Version : [J2ME]Gestire eventi pausa/stop applicazione


Donbabbeo
19-08-2008, 16:57
Sto creando un'applicazione sempliciotta (uno space invaders clone) tramite j2me: il gioco funziona, riesco anche a salvare gli highscore senza richiedere permessi (scrivo sul recordstore).
Il problema è che non mi piace quello che accade alla mia morte! Mi spiego meglio, mostrando una parte del codice:

public void run()
{
Graphics g = getGraphics();

while(inGioco == true)
{
if (inPausa == false)
{
input();

tick();

render(g);

try{Thread.sleep(sleepTime);
}catch(InterruptedException ie) {}
}

else
{
if (getKeyStates() != 0)
inPausa = false;
}
}
//if (getKeyStates() != 0)
//torna al menù principale
}

Questo è il thread in esecuzione, input gestisce i miei movimenti, thick gestisce i movimenti della flotta di alieni e render disegna a schermo. Ad ogni morte vado in pausa fino alla pressione di un nuovo tasto, in modo da avere un attimo di tempo per riorganizzarmi :D
Il problema è che spesso mentre vengo colpito sto già premendo un tasto, di conseguenza la pausa non avviene per niente... Ed inoltre non capisco perchè, non riesco a far apparire un messaggio in sovraiscrizione! Vorrei sostituirlo con qualcosa del tipo:
if (HaiPersoUnaVita == true)
{

//SCRIVI A SCHERMO -> "HAI PERSO UNA VITA!"
//ATTENDI 2 SECONDI

}

Seconda domanda: al game over il gioco mi rimane bloccato al punto della morte (ovvio, imposto lo stop del thread)... Io vorrei però che mi tornasse al menù! Tipo:
if (SeiMorto == true)
{

//SCRIVI A SCHERMO -> "GAMEOVER!"
//ATTENDI 2 SECONDI
//TORNA AL MENU
}

Qualche consiglio?

Io gestisco il tutto così, ma ovviamente non funziona (non mi scrive a schermo):

public void stop()
{
Graphics g = getGraphics();

if (fleet.size() > 0 && vite > 0)
{
g.setColor(0xFFFFFF);
g.drawString("HAI PERSO UNA VITA", getWidth()/4, getHeight()/2, 0);
inPausa = true;
}
else if (fleet.size() > 0 && vite <= 0)
{
g.setColor(0xFFFFFF);
g.drawString("HAI PERSO! IL TUO PUNTEGGIO E': " + score, getWidth()/4, getHeight()/2, 0);
high = getHighScore();
if (score > high)
{
g.drawString("COMPLIMENTI! HAI FATTO IL NUOVO HIGHSCORE", getWidth()/4, getHeight()/2, 0);
setHighScore(score);
}
inGioco = false;
}
else if (fleet.size() <= 0 && vite > 0)
{
g.setColor(0xFFFFFF);
g.drawString("HAI VINTO! IL TUO PUNTEGGIO E': " + score, getWidth()/4, getHeight()/2, 0);
high = getHighScore();
if (score > high)
{
g.drawString("COMPLIMENTI! HAI FATTO IL NUOVO HIGHSCORE", getWidth()/4, getHeight()/2, 0);
setHighScore(score);
}
inGioco = false;
}
}

^TiGeRShArK^
19-08-2008, 19:37
aspè...
ma il getGraphics() lo stai chiamando sulla canvas corretta?
E sei sicuro di essere all'interno del thread grafico?

Donbabbeo
19-08-2008, 20:38
aspè...
ma il getGraphics() lo stai chiamando sulla canvas corretta?
E sei sicuro di essere all'interno del thread grafico?

volendo potrei metterlo nel thread ma non riesco a visualizzarlo comunque
public void run()
{
Graphics g = getGraphics();

while(inGioco == true)
{
if (inPausa == false)
{
input();

tick();

render(g);

try{Thread.sleep(sleepTime);
}catch(InterruptedException ie) {}
}

else
{
g.setColor(0xFFFFFF);
g.drawString("HAI PERSO UNA VITA", getWidth()/4, getHeight()/2, 0);
if (getKeyStates() != 0)
inPausa = false;
}
}
//if (getKeyStates() != 0)
//torna al menù principale
}

Ad esempio se faccio così mi fa tutto correttamente, va in pausa, ma la scritta non la fa...

^TiGeRShArK^
20-08-2008, 00:11
volendo potrei metterlo nel thread ma non riesco a visualizzarlo comunque
public void run()
{
Graphics g = getGraphics();

while(inGioco == true)
{
if (inPausa == false)
{
input();

tick();

render(g);

try{Thread.sleep(sleepTime);
}catch(InterruptedException ie) {}
}

else
{
g.setColor(0xFFFFFF);
g.drawString("HAI PERSO UNA VITA", getWidth()/4, getHeight()/2, 0);
if (getKeyStates() != 0)
inPausa = false;
}
}
//if (getKeyStates() != 0)
//torna al menù principale
}

Ad esempio se faccio così mi fa tutto correttamente, va in pausa, ma la scritta non la fa...
ecco..
allora avevo intuito bene..
quel metodo run fa parte di un altro thread diverso dal thread grafico e in java, come in praticamente tutti gli alitri linguaggi esistenti, è assolutamente necessario modificare lo stato degli oggetti grafici dallo stesso thread che gestisce la grafica..Se provi ad eseguire dei cambiamenti sugli oggetti grafici da un thread diverso ottieni degli errori o comunque, nel caso migliore, hai un risultato imprevedibile, come nel tuo caso mi sa :p
Esegui l'aggiornamento dal thread grafico.
In J2SE si usa SwinUtilities.invokeLater() per effettuare delle chiamate asincrone da un thread diverso che verrano instradate sull' EDT grafico...
con J2ME sinceramente non ho mai fatto una cosa del genere e non so se esiste qualcosa di simile, anche se immagino di si.

Donbabbeo
20-08-2008, 11:59
Grazie! :mano:

Finalmente (quasi) funziona! :yeah:

Ho pure aggiunto un temporizzatore per i messaggi e rimosso il check sulla pressione del tasto, quindi ora funziona esattamente come volevo.
Grazie ancora :D

Oggi pomeriggio un pò di pulizia generale del codice, aggiungo qualche commento qua e là ed ho fatto! :winner: