1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

Meine Gedanken zur Spieleprogrammierung - Teil 1 - Spielstrukturen

Dieses Thema im Forum "Android Spiele Entwicklung" wurde erstellt von DocJunioR, 16.07.2009.

  1. DocJunioR, 16.07.2009 #1
    DocJunioR

    DocJunioR Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    56
    Erhaltene Danke:
    6
    Registriert seit:
    25.06.2009
    Vorwort:

    Ich nenne dies hier absichtlich nicht Tutorial, howto, etc., weil es lediglich das wiedergibt, was ich mir zum Thema denke. Möglicherweise gehts auch eleganter..

    Teil 1 Spielstrukturen.
    Wer sich schonmmal so ein Spiel angesehen hat, der weiß, das es selten gleich nach dem Aufruf des Programms losgeht. Warum auch? Vielleicht möchte man ja nur mal die Soundeinstellungen ansehen oder jemandem den Trailer zeigen?
    So ein Spiel besitzt also einige Komponenten, die um das eigentliche Spiel herum gestrickt sind. Im android-Deutsch wären dies Views. Selbst innerhalb des eigentlichen Spieles können diese benutzt werden- beispielsweise wenn es darum geht, ein Character sheet zu erstellen, etc.

    Ich möchte hier also mal zeigen, wie ich das Ganze angehen würde.
    Überlegen wir uns ein einfaches Spiel, bei dem man Spielstände laden und speichern kann, sowie spielen und, natürlich, das Spiel verlassen. Wir haben also folgende Views

    • Hauptmenue (da fängt das Programm nach dem Start an)
    • Load Game
    • Save Game, was aber nur dann sichtbar sein sollte, wenn was zu speichern da ist
    • das eigentliche Spiel
    Jede View erfüllt ihre eigene Aufgabe mit eigenen Event Handlern. Dummerweise gibt es so immer nur einen, der weiß, wann die View nicht mehr benötigt wird: die View selbst. Auch ist sie die Einzige, die weiß, welche View ihr folgen muss. Dennoch muss die Activity, das eigentliche Programm auf eine neue View schalten.

    Ich habe das Ganze so gelöst, dass meine Activity ein Interface IViewSetter implementiert. Dieses Interface sieht so aus:
    Code:
    public interface IViewSetter {
        public void setView (String viewName);
    }
    Jetzt muss unsere View noch wissen, wer unser ViewSetter ist. Da wir noch nicht wissen, ob wir eine SurfaceView, ListView oder ein Layout dafür nutzen, definieren wir ein weiteres Interface IGameView. Dies hat den Nachteil, dass wir das Ganze jedes Mal neu implementieren müssen, aber durch geschickte Vererbung eigentlich auch nur einmal pro Viewtyp.
    Code:
    public interface IGameView {   
        /**
         * @param setter Instance of the program setting the active view
         */
        public void setViewSetter (IViewSetter setter);
    }
    Die IGameView wird später sämtliche View-übergreifenden Funktionen transportieren.
    Zurück zur Viewsteuerung.
    Die Activity bekommt also einen String übergeben, der ihr sagt, was als nächstes gezeigt werden soll. Dies kann sie dann einfach überprüfen:

    Code:
    public class MainActivity extends Activity implements IViewSetter {
        
        public void onCreate (Context context) {
            super.onCreate(context);
    
            // blende den Titel des Programms aus (Vollbild)
            requestWindowFeature(Window.FEATURE_NO_TITLE);
    
            // Lade die Hauptansicht.
            setView("main");
        }
    
        public void setView(String, viewName) {
            IGameView view = null
            if (viewName.equals("main")) {
                view = new MainMenu(this.getContext();
    
            } else if (...) {
            } else { // alles unbekannte heißt exit
                thist.finish(); 
            }
    
            // mache den ViewSetter bekannt
            view.setViewSetter(this);
            // setze die neue View
            setContentView ((View) view);
        }
    }
    Auch, wenn es nicht unbedingt notwendig ist, hier der Vollständigkeit halber die Implementierung der IGameView in einem LinearLayout:
    Code:
    public class MainMenu extends LinearLayout implements IGameView, OnClickListener {
        IViewSetter setter = null;
    
        public MainMenu(Context context) {
        super(context);
        //TODO: Buttons erstellen, etc.
        }
    
        @Override
        public void setViewSetter(IViewSetter setter) {
            this.setter = setter;
        }
    
        @Override
        public void onClick(View v) {
            // wenn etwas bestimmtes passierte, ändere die View..
            this.setter.setView ("loadfile");
        }
       
    '}
    
    Um die Geschwindigkeit des Viewwechsels zu erhöhen könnte man sämtliche Views zu Anfang instanziieren und einfach die Instanzen tauschen. Ob das wirklich einen merklichen Vorteil bringt, hängt wohl davon ab, was man zu instanziieren hat.

    Soo,ich hoffe, dass ich euch damit schonmal etwas Interessantes erklären konnte. Als nächstes würde ich erklären, wie man quasi für lau Spielstände da rein bringen kann- so ihr das noch wollt ;).

    wenn du schon bis hier gekommen bist, hinterlass doch bitte eine ehrliche Meinung- bin Kritikfähig.. *Kettensäge zück*
     
    Zuletzt bearbeitet: 16.07.2009
    Epic46 und Luise Lustig haben sich bedankt.
  2. zx128, 16.07.2009 #2
    zx128

    zx128 Android-Lexikon

    Beiträge:
    1,179
    Erhaltene Danke:
    143
    Registriert seit:
    23.01.2009
    Danke für den Beitrag. Bin gespannt auf die Fortsetzung.

    Vor allem interessiert mich das Aufbau einer Game-Engine.

    Habe eigentlich nur eine Anmerkung/Frage:

    im Android-Source sehe ich, dass die meistens die Activity wechseln,
    um eine andere View zu zeigen.

    D.h. an eine View hängt an einer Activity.

    Views mit setContectView zu wechseln habe ich auch schon mal gemacht und dabei keine Nachteile festgestellt.

    Weiß du warum (wann) die eine oder die andere Methode besser ist?
     
  3. DocJunioR, 16.07.2009 #3
    DocJunioR

    DocJunioR Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    56
    Erhaltene Danke:
    6
    Registriert seit:
    25.06.2009
    so weit ich das verstanden habe, startet eine neue activity ein komplett neues Fenster, was m.E. mehr Ressourcen frisst als nur das Austauschen der View. Ansonsten kann es beim Tauschen der View wohl auch nicht passieren, dass man zwischendurch den Desktop sieht..
    Die gleiche Mimik kann man auch über Activities machen, allerdings muss der Setter dann eien extra Klasse sein. Bisher hab ich allerdings auch noch keinen Weg gefunden, innerhalb einer Viewklasse ein layout.xml zu laden..
     
  4. Temar, 16.07.2009 #4
    Temar

    Temar Erfahrener Benutzer

    Beiträge:
    214
    Erhaltene Danke:
    14
    Registriert seit:
    25.06.2009
    Das wird eigentlich nach Wiederverwendbarkeit gruppiert. Angenommen du schreibst ein Gallerie-Programm um die Bilder auf deinem Handy anzuschauen. Diese Gallerie besteht aus 2 Views: Das eine zeigt eine Vorschau der Bilder, dass andere zeigt das Bild im Vollbildmodus. Was nimmst du nun?

    Ganz klar entscheidest du dich für zwei Activities anstatt für zwei Views in einem Activity. Warum? Wegen der Wiederverwendbarkeit. Das Activity zum anzeigen des Bildes im Vollbildmodus kann so von externen Activities sehr einfach genutzt werden. Das ginge zwar auch mit nur einem zentralen Activity allerdings macht es keinen Sinn die ganze Logik zum verwalten der Bilder auf der Festplatte mitzuladen, nur weil ein Programm ein Bild anzeigen will.

    Ein Beispiel bei dem mehrere Views verwendet werden aber nur eine Activity wäre ein Preferences-Activity mit mehreren Unterseiten. Die Wiederverwendbarkeit ist hier gering, in der Regel will der User alle möglichen Einstellungen sehen und selbst wenn eine Einstellungs-Unterseite direkt aufgerufen wird, macht es nicht viel aus den Rest mitzuladen. Die Logik ist über alle Einstellungsseiten ziemlich die gleiche.
     

Diese Seite empfehlen