2010-11-09 5 views
0

J'essaie d'apprendre les ficelles du développement de jeux et d'Android et ça a été une expérience d'apprentissage géniale jusqu'à présent, mais les trucs Android Activity Lifecycle m'a un peu bloqué.Android Game Singleton ou Application ou aucun

Disons que j'ai trois activités -

  • Menu Jeu
  • Sélection du niveau
  • Le jeu réel (jeu 2d en utilisant la SurfaceView).

Je pense que je dois charger tous les bitmaps et sons en dehors de l'activité de jeu réel pour éviter d'avoir à décharger et les recharger à chaque fois onDestroy et onCreate est appelé, par exemple, comme lorsque le téléphone se met en veille, ou chaque fois qu'un nouveau niveau est choisi à partir de l'écran de sélection de niveau. Cela m'a conduit à l'approche Singleton qui a du sens et semble être ce que je suis après, mais je ne comprends pas vraiment où je devrais décharger le Singleton pour s'assurer qu'il obtient GC'd, par exemple , pourrais-je le publier dans le menu du jeu onDestroy, si oui, comment puis-je savoir si l'activité du menu du jeu va traîner indéfiniment. J'ai également vu la mention d'Android capable de tuer le singleton seul. J'ai également lu quelques-uns sur l'utilisation du contexte d'application qui me donnerait le cycle de vie.

Quelle serait la meilleure façon d'aborder cela? Est-ce que je veux vraiment décharger et recharger toutes les ressources de l'activité de jeu? Est-ce que je vais dans la bonne direction avec l'idée Singleton ou Application?

+0

Vous pouvez également consulter http://gamedev.stackexchange.com –

Répondre

1

Il faut toujours présumer votre activité sera détruite. En supposant que le contraire vous donnera toujours des maux de tête. Personnellement, j'ai pris l'approche d'avoir mon activité de chargement et de jeu principal dans le même sens que pendant la création de la surface, je peux superposer un graphique/écran de chargement sur le dessus de la surface et précharger tous les bitmaps/sons dans onCreate.

La sélection de niveau et d'autres activités sont ensuite générées à partir de l'activité principale, généralement via une méthode startActivityForResult. Cela vous permet de 1) Créer un écran de chargement pendant que le préchargement/l'instanciation a lieu 2) Présenter un écran principal avec Démarrer le jeu etc ... 3) Avoir déjà créé le SurfaceView mais être caché ou derrière l'activité principale du jeu.

De toute évidence, vous ne devriez pas commencer les threads ou quoi que ce soit jusqu'à ce qu'ils commencent le jeu, mais la surface elle-même peut être prête à partir. De cette façon, Start Game est fluide et rapide. Vous venez de masquer toutes les autres vues et d'amener votre SurfaceView au sommet.

Mais encore une fois, supposez toujours que votre activité sera détruite. Signification sauver l'état de jeu etc ...

En ce qui concerne le jeu principal, vous devez diviser votre jeu en 2 threads - un pour la logique de jeu et un pour le dessin réel sur la toile. Dans votre activité de jeu, vous devez passer outre:

  • onCreate: bitmaps Précharger, sons, instancier la classe principale du jeu et commencer fil de jeu (UI/Canvas en plus du fil logique du jeu) lorsque le bouton Start Game est pressé
  • OnDestroy: Tuez tous les fils
  • OnPause: Pause toutes les discussions (fil de toile doit être tué sur surfaceDestroy)
  • onResume: fil CV

profil toujours votre application en utilisant les outils av disponible. Demandez à votre application de mettre à jour les threads et de les suivre à l'aide du tracker de ressources pour vous assurer que vous n'utilisez pas d'objets temporaires. Créez toujours ces objets dans votre activité/classe principale et référencez-les. Mon application n'exécute jamais le GC à moins que je le dise et il fonctionne sans problème en utilisant le design mentionné ci-dessus.

Espérons que cela aide. J'ai écrit quelques articles concernant le développement de jeux Android au methodin.tumblr.com.

+0

Wow, j'aime vraiment cette idée. Alors, relâchez-vous des sons et recyclez-vous des bitmaps? Comment géreriez-vous la situation où quelqu'un joue le jeu mais le pose et il dort puis passe par un onDestroy complet et de retour à onCreate? – tp0w3rn

+0

Généralement, vous trouverez lors d'une utilisation normale que vous n'avez jamais à vous soucier de détruire des événements. Bien sûr, il y a des cas de bord, mais généralement quelqu'un joue votre jeu ou non. Libérer des éléments préchargés causerait probablement des problèmes de GC pendant le jeu, il est donc préférable d'éviter cela. Vous devrez gérer l'état du jeu de stockage vous-même soit à la DB ou d'autres méthodes. Lorsque vous appelez onCreate again, vous préchargez tout, puis récupérez l'état de DB si vous l'avez. Vraiment dépend de votre jeu. – methodin

+0

Merci, je vais donner un tour à votre design, ça a plus de sens que mon approche. – tp0w3rn

1

La méthode onDestroy de l'activité n'est pas garantie d'être appelée (par exemple Task Killer), donc ne dépendez pas de celle-ci.

Si vous avez besoin de présélectionner une classe à travers votre cycle d'application, Singleton ou les référencer dans la classe d'application est également applicable, en effet, Singleton semble plus logique pour un design plus propre.

Je ne pense pas que vous ayez besoin d'enlever votre contenu de manière explicite, car GC va tout sortir une fois que ce n'est pas nécessaire (du moins, il le fera une fois que votre application sera détruite par android). De plus, attacher ces objets au cycle de vie de Game Menu est une mauvaise idée. Je suppose que vos activités aimeraient:

Game Menu Activity -> Level Selection Activity -> Main Game Activity 

Il est parfois possible que, pendant que vous êtes dans « Activité principale du jeu », le « menu du jeu » est en fait détruit. (Oui et si vous appuyez sur 'retour', il passera à un menu de jeu nouvellement créé)

0

La classe Application est un endroit pour stocker des informations qui seront disponibles pour le cycle de vie de l'application. C'est un bon endroit pour mettre les choses qui sont utilisées par plusieurs activités (état de l'application globale). C'est essentiellement la même chose que d'utiliser un singleton.

Toutefois, si l'utilisateur quitte l'application en appuyant sur la touche accueil, il n'y a aucune garantie que l'application restera éternelle. Si elles reviennent 20 minutes plus tard, l'application peut avoir besoin d'être recréée.

Je ne pense pas que vous ayez besoin de vous inquiéter des choses en cours de GCed, Android reprendra de la mémoire si elle en a besoin. Sinon, les choses seront libérées lorsque l'application existe.

Assurez-vous de lire attentivement les informations sur le Activity lifecycle.Si vous allez de GameActivity -> Level Select -> GameActivity, très probablement le GameActivity ne sera pas détruit et recréé. Au lieu de cela, il sera simplement arrêté et redémarré. Ce n'est pas une garantie, mais ce sera vrai dans la plupart des cas.

0

Vous ne devriez pas avoir à vous soucier de GC vous-même. Lorsqu'un utilisateur quitte votre application (et ne revient pas pendant un certain temps), le système d'exploitation lui-même se chargera d'éliminer l'application pour vous.

Si vous souhaitez utiliser un singleton, vous pouvez le déclarer au niveau de l'application. Par exemple, un « AssetManager » est disponible ici:

public class YourGameApplication extends Application { 

    public AssetManager assetManager = new AssetManager(); 

    @Override 
    public void onCreate() 
    { 
     super.onCreate(); 
    } 
} 

Vous pouvez alors l'appeler d'une autre activité:

YourGameApplication application = ((YourGameApplication) this.getApplication()); 
application.assetManager.someFunction(); 
+0

Donc, je ne devrais pas vous soucier de recycler les bitmaps et de libérer des sons? – tp0w3rn

+0

@ tp0w3rn À moins que vous ayez besoin de vous libérer de la mémoire (i.e passage à de nouvelles musiques de fond ou n'utilisant plus certaines bitmaps), alors je dirais non, vous n'avez pas besoin de vous en préoccuper. Lorsque le système d'exploitation tue l'application, il va gérer cela pour vous. –

+0

Eh bien c'est rafraîchissant, j'ai été inquiet à mort en essayant de m'assurer que je libère tout correctement. – tp0w3rn