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

Meine Gedanken zur Spieleprogrammierung - Teil 3 - Die Leinwand

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
    Herzlich Willkommen zurück in meinem Gedankengut- ich hoffe, es ist nich zu wirr.
    Wir haben es bisher geschafft, unser Menü zu steuern, und Spieledaten zu speichern. Das alles würde in Verbindung mit ein paar ListViews, etc. schon ausreichen um beispielsweise ein Börsenspiel zu programmieren.

    Aaaber man will ja mehr. Echte Grafik beispielsweise. Android bietet hier eine so genannte SurfaceView, die wir als Basis für ein Grafikpanel nutzen wollen. Dieses Panel wird zudem IGameView implementieren, es soll ja in den Rest unseres Framework integriert werden können.
    Code:
    public class GamePanel extends SurfaceView implements
        SurfaceHolder.Callback, IGameView {
        protected IViewSetter viewSetter = null;
        protected GameThread thread = null;
    
        .... <-- Das aus dem vorherigen Teil muss auch noch rein
    
        /**
         * @param context
         */
        public GamePanel(Context context) {
            super(context);
            // Änderungen am Canvas werden hier verarbeitet
            this.getHolder().addCallback(this);
            // Gamethread erstellen
            this.thread = new GameThread(this);
            // das Panel ist fokussierbar
            this.setFocusable(true);
        }
    
    
        /**
         * @return
         * @see de.docjunior.androidengine.GameThread#isRunning()
         */
        public boolean isRunning() {
            return thread.isRunning();
        }
    
        /**
         * @param running
         * @see de.docjunior.androidengine.GameThread#setRunning(boolean)
         */
        public void setRunning(boolean running) {
            thread.setRunning(running);
        }
    
        /**
         * spielupdate
         */
        public void updateGame() {
            // TODO: Physikberechnungen, Objekt-KI, etc.
        }
    
        @Override
        public void onDraw(Canvas canvas) {
            // TODO: Darstellen der Objekte
        }
    
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // tote Threads werden wieder erschaffen
            if (!this.thread.isAlive()) {
                this.thread = new GameThread(this);
            }
    
            // der thread wird gestartet
            thread.setRunning(true);
            thread.start();
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            boolean waiting = true;
            thread.setRunning(false);
            while (waiting) {
                try {
                    this.thread.join();
                    retry = false;
                } catch (InterruptedException e) {
                //versuche mit thread eins zu werden..
                }
            }
            Log.i(getClass().getSimpleName(), "Thread terminated...");
        }
    }
    
    Über Drawables, oder einfach Graphics-Primitive könnten wir im Android schon malen, auch das Abfangen von events ist ein sehr einfaches Unterfangen. Allerdings sieht es ein wenig unglücklich aus, wenn die Gegner sich nur bewegen, wenn man selbst irgendetwas getan hat. Dies ist der große Nachteil eventbasierter Softwaresysteme. Früher zu DOS-Zeiten gab es einen Mainloop der erst einmal geschaut hat, ob irgendetwas neues vom Spieler kam und anschließend die KI, sowie Grafiken aktualisierte.

    Dies gilt es, jetzt nachzustellen. Hierbei hilft uns nach meiner Auffassung das Android-Framework nicht sonderlich. Der Java-Standard Allerdings schon. Java bietet die Möglichkeit, Funktionen über Threads parallel ablaufen zu lassen.

    Wir schreiben uns also eine Klasse, die als parallel laufender Thread unser Spielefenster aktualisiert. Dies sollte nicht unbedingt permanent passieren. Unser Thread wird sich nach 25ms schlafen legen. Dies ermöglicht uns (je nach Rechenzeit der Einzelschritte) ca. 40 Frames pro Sekunde- mehr als ausreichend.

    Threads sind mit Vorsicht zu genießen. Wenn man auf nicht direkt am Thread hängende Daten zugreift, kann das zu ziemlichen Zugrifssproblemen und zum Absturz des Programms führen. Wir müssen uns synchronisieren. Das Ganze kann dann so aussehen.

    Code:
    public class GameThread extends Thread {
        private boolean running = false;
        private GamePanel gamePanel;
    
        public boolean isRunning() {
            return running;
        }
    
        public void setRunning(boolean running) {
            this.running = running;
        }
    
    
        public GameThread(GamePanel pGamePanel) {
            this.gamePanel = pGamePanel;
        }
    
        /* (non-Javadoc)
         * @see java.lang.Thread#run()
         */
        @Override
        public void run() {
            while (isRunning()) {
                Canvas canvas = null;
                try {
                canvas = gamePanel.getHolder().lockCanvas();
                
                synchronized (gamePanel.getHolder()) {
                    // spieledaten updaten
                    gamePanel.updateGame();
                    // spiel neu zeichnen
                    gamePanel.onDraw(canvas);
                    
                }
                    sleep(25);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    if (canvas != null) {
                        gamePanel.getHolder().unlockCanvasAndPost(canvas);
                    }
                }
            }
        }
    
        
    }
    
    So, nun kann man seinen canvas je nach Wunsch alle 25ms neu bemalen und das auch noch per Reaktion auf irgendwas. Die Reaktion eines Objekts würde ich an dieses anhängen. Wie, erkläre ich dann beim nächsten Mal. Möglicherweise kann dies etwas länger dauern. Ich hab auch sowas wie Familie und die hat ab jetzt frei..

    Kritik und Diskussion sind wie immer erwünscht.
     
    Luise Lustig bedankt sich.
  2. DocJunioR, 16.07.2009 #2
    DocJunioR

    DocJunioR Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    56
    Erhaltene Danke:
    6
    Registriert seit:
    25.06.2009
    Bevor noch jemand mosert: Der Code aus diesem Teil ist streckenweise einigen Quellen aus dem Internet entlehnt. Prinzipiell aber nicht einfach abgeschrieben, sondern entsprechend an mein Gedankengut angepasst.
     
  3. swordi, 16.07.2009 #3
    swordi

    swordi Gewerbliches Mitglied

    Beiträge:
    3,389
    Erhaltene Danke:
    441
    Registriert seit:
    09.05.2009
    threads ist eine allgemeine lösung

    es gibt in android noch handler. ich hab schonmal darüber etwas updaten lassen. arbeiten im prinzip wie threads, nur halt ein wenig anders aufgebaut.

    kann aber keine vergleiche ziehen, was besser ist
     
  4. DocJunioR, 16.07.2009 #4
    DocJunioR

    DocJunioR Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    56
    Erhaltene Danke:
    6
    Registriert seit:
    25.06.2009
    hatte sie mir im Vorfeld zu diesem Teil nochmal angesehen. Thematisch sind sie zum Verarbeiten von Nachrichten, ansonsten könnte man sie möglicherweise auch nutzen. :) kannst sie ja mal probieren und das Ergebnis posten. Interessiert mich auch
     
    Zuletzt bearbeitet: 16.07.2009
  5. swordi, 16.07.2009 #5
    swordi

    swordi Gewerbliches Mitglied

    Beiträge:
    3,389
    Erhaltene Danke:
    441
    Registriert seit:
    09.05.2009
    ich habe sie schon als "art" thread benutzt. wenn ich zeit hab, kann ich das ungefähr mal hier rein posten. muss aber im moment meinen umzug organisieren
     
  6. DocJunioR, 16.07.2009 #6
    DocJunioR

    DocJunioR Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    56
    Erhaltene Danke:
    6
    Registriert seit:
    25.06.2009
    hat zeit. ich werd eh so weiter machen- bin unverbesserlich.

    btw. hat schonmal wer es-opengl genauer angeschaut?
     
  7. Lemonbaby, 23.07.2009 #7
    Lemonbaby

    Lemonbaby Neuer Benutzer

    Beiträge:
    17
    Erhaltene Danke:
    0
    Registriert seit:
    13.07.2009
    Handler dienen der Implementierung eines Messaging-Systems
    und haben mit Threads nicht mehr zu tun, als das letztere sie
    zur Kommunikation nutzen können.

    Bitte keine Äpfel und Birnen durcheinanderwerfen...
     
  8. swordi, 23.07.2009 #8
    swordi

    swordi Gewerbliches Mitglied

    Beiträge:
    3,389
    Erhaltene Danke:
    441
    Registriert seit:
    09.05.2009
    ja sicher sind sie für ein messaging system gedacht, aber man kann sie so verwenden wie auch threads.

    ob das jetzt resourcen technischen besser ist, sei mal dahingestellt.
     
  9. Lemonbaby, 23.07.2009 #9
    Lemonbaby

    Lemonbaby Neuer Benutzer

    Beiträge:
    17
    Erhaltene Danke:
    0
    Registriert seit:
    13.07.2009
    android.os.Handler != android.os.HandlerThread

    In einem anderen Thread beschwerte sich völlig zurecht ein
    User darüber, dass hier Entwicklungsthemen sehr verwirrend
    bis unverwertbar angehandelt werden. Eine gewisse sprach-
    liche Präzision würde hier die Dinge deutlich verbessern. Du
    selber magst wissen, wovon Du redest. Sinn dieses Forums
    ist aber meiner Meinung nach, auch Usern, die ihre ersten
    Schritte in Java machen, eine Hilfe zu sein und tiefere Ein-
    blicke in fortgeschrittene Themen der Entwicklung zu geben.
    Dazu muss auch mal bereit sein, etwas weiter auszuholen,
    um nicht nur in reines Fachgesimpel zwischen erfahrenen
    Entwicklern zu verfallen. Je mehr Details man verständlich
    beschreibt, desto größer ist die Zielgruppe...
     
  10. DocJunioR, 23.07.2009 #10
    DocJunioR

    DocJunioR Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    56
    Erhaltene Danke:
    6
    Registriert seit:
    25.06.2009
    uuuh baby, baby its a wild world... ;)
    mädels, zerkloppt euch nicht gegenseitig deswegen. er mensch ist nunmal unpräzise. Verallgemeinerung ist immerhin die Stärke deuronaler Verdrahtungen...
     
    MrPermanent bedankt sich.
  11. DocJunioR, 23.07.2009 #11
    DocJunioR

    DocJunioR Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    56
    Erhaltene Danke:
    6
    Registriert seit:
    25.06.2009
    ... und meine schwäche ist eindeutig das einhändig tippen und gleichzeitige anziehen von schuhen an kleinstkindern..
     

Diese Seite empfehlen