2011-08-03 7 views
4

Je fais un jeu, et depuis que je suis nouveau sur Android, j'ai basé la conception de l'exemple LunarLander code. Dans sa conception, GameThread.doStart() est appelé à partir GameActivity, et le fil passe alors tout de sa boucle GameThread.run() comme indiqué ci-dessous (une grande partie du code a été pour plus de clarté):SurfaceHolder.lockCanvas() Retour de null

public class GameActivity extends Activity 
{ 
    public void onCreate(Bundle savedInstanceState) 
    { 
     gameView = new GameView(this); 
     fl = new FrameLayout(this); 
     fl.addView(gameView); 

     setContentView(fl); 

     gameThread = gameView.getThread(); 
     gameThread.doStart(); 
    } 
} 

.

class GameThread extends Thread 
{ 
    public void doStart() 
    { 
    } 

    public void run() 
    { 
     while (running) 
     { 
      Canvas c = null; 
      try 
      { 
       c = mSurfaceHolder.lockCanvas(); 
       // Use canvas 
      } 
      finally 
      { 
      } 
     } 
    } 
} 

Pour essayer de résoudre certains problèmes que j'ai je courais en ai essayé de mettre plus de contrôle dans les mains de GameActivity, comme indiqué ci-dessous:

public class GameActivity extends Activity 
{ 
    public void onCreate(Bundle savedInstanceState) 
    { 
     gameView = new GameView(this); 
     fl = new FrameLayout(this); 
     fl.addView(gameView); 

     setContentView(fl); 

     gameThread = gameView.getThread(); 

     while (gameThread.isRunning()) 
     { 
      gameThread.run(); 
     } 
    } 
} 

.

class GameThread extends Thread 
{ 
    public void doStart() 
    { 
    } 

    public void run() 
    { 
     Canvas c = null; 
     try 
     { 
      c = mSurfaceHolder.lockCanvas(); 
      // Use canvas 
     } 
     finally 
     { 
     } 
    } 
} 

Sauf quand je fais ça lockCanvas() retourne toujours nulle, et donc je ne peux pas tirer quoi que ce soit à l'écran. Comme je l'ai dit je suis encore nouveau sur Android, donc je ne sais pas pourquoi le second cas ne fonctionne pas. Quelqu'un sait-il ce qui se passe ou pourquoi cela ne fonctionne pas?

EDIT: D'après ce que j'ai testé, la surface n'est jamais créée. Pendant GameView.onResume() j'ai eu l'activité attendez que la surface soit créée avant de continuer avec le jeu, mais il a attendu pour toujours. Comment se fait-il que la première instance soit le seul cas où la surface est créée?

Répondre

2

Vous démarrez une activité thred sur create, alors qu'elle doit être démarrée uniquement lorsque SurfaceView est créé et prêt. Vérifiez ceci dans la seconde, l'exemple SurfaceView: How can I use the animation framework inside the canvas?

+0

Qu'est-ce que vous proposez est ce que je fais déjà. Je n'ai juste pas montré ce code. Je vais l'ajouter si vous voulez. –

+0

Je ne ferme pas le thread sur la pause d'activité, il suffit de définir un indicateur booléen afin que la boucle de thread n'appelle aucune méthode. En résumé je réinitialise à nouveau ce drapeau et l'animation continue ... Si la surface est détruite alors sur surfaceCreated va créer un nouveau thread la prochaine fois. – Lumis

+0

Si la surface n'est pas créée, vous pouvez la détecter et redémarrer l'activité. – Lumis

1

Commencez à exécuter le fil une fois la surface créée. c'est-à-dire lorsque vous recevez un callback surfaceCreated(), démarrez le thread.

Code Snippet

public void surfaceCreated(SurfaceHolder holder) { 
    thread.setRunning(true); 
    thread.start(); 
} 

Shash

+0

Qui est exactement ce que je suis Faire. –