• beyond tellerrand – play. Register Now!
Zurück   Flashforum > Flash > ActionScript > Softwarearchitektur und Entwurfsmuster

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 15-06-2010, 10:36   #1 (permalink)
Neuer User
 
Registriert seit: Jun 2010
Beiträge: 4
Pure Mvc Game Loop

Hallo zusammen,

Ich entwickle seit einiger Zeit meine Spiele mit PureMvc As3.
Leider bin ich mir nicht ganz sicher, wie man den GameLoop am besten integriert.
Im Moment habe ich einen EnterFrame im ApplicationMediator View, der eine ON_ENTER_FRAME Notification sendet und damit einen Controller GameLoopCommand auslöst. Der GameLoopController berechnet die erste Zeit mit getTime(), fragt dann die Collisions ab und bewegt den Player. Danach berechnet er die vergangene Zeit und speichert diese in den TimeProxy.
Ich bekomme nur bei dieser Methode oft framedrops, daher habe ich die Befürchtung, dass dieser Weg zu rechenintensiv ist.
Meine Frage ist ob das so s.u. überhaupt dem MVC Prinzip entspricht? oder doch eher der EnterFrame TICK aus dem TimerProxy kommen sollte und intressierte Mediator die TICK Notification verarbeiten lassen, statt alles im Controller zu verarbeiten.

PHP-Code:
facade.registerCommand(ApplicationFacade.ON_ENTER_FRAMEGameLoopCommand); 
Im Main View den EnterFrame Bang adden
PHP-Code:

    
public class ApplicationMediator extends Mediator implements IMediator
    
{
        public static const 
NAME:String "ApplicationMediator";
        
        public function 
ApplicationMediatorviewComponent:Sprite)
        {
            
trace(this+" construct() "+viewComponent);
            
superNAMEviewComponent);
        }
        
        
override public function listNotificationInterests():Array
        {
            return [ 
                        
ApplicationFacade.START_GAME
                    
]
        }
        
        
override public function handleNotification(notification:INotification):void
        
{
            switch( 
notification.getName() )
            {
                case 
ApplicationFacade.START_GAME:
                     
viewComponent.stage.addEventListener(Event.ENTER_FRAMEonEnterFrame);
                break;
                }
        }
                
        private function 
onEnterFrame(e_:Event):void {
            
sendNotification(ApplicationFacade.ON_ENTER_FRAME);
        }
    }

Im Controller Zeit berechnen, Controller für die Gamelogic aufrufen und Zeit speichern
PHP-Code:
public class GameLoopCommand extends SimpleCommand implements ICommand{
        
override public function execute(notification:INotification):void
        
{
            var 
_timeProxy:TimeProxy facade.retrieveProxy(TimeProxy.NAME) as TimeProxy;

            
// zeit die seit dem letzten aufruf des controllers vergangen ist
            
if (_timeProxy.lastTime == 0_timeProxy.lastTime getTimer();
            var 
timeDiff:int getTimer()-_timeProxy.lastTime;
            
_timeProxy.lastTime += timeDiff;
            
            
//Game Logic Check Walls, Move Hero, Move Enemy etc... 
            
sendNotification(ApplicationFacade.MOVE_HEROtimeDiff);
            
sendNotification(ApplicationFacade.CHECK_COLLISIONS);
            
            
//Zeit im Proxy speichern
            
_timeProxy.time=getTimer();
        }

Zeit im Model von ms in String wandeln und den View updaten
PHP-Code:
    public class TimeProxy extends Proxy implements IProxy
    
{
        public static const 
NAME:String "TimerProxy";
        private var 
_time Number;
        private var 
_lastTime:int=0;        
        public function 
TimeProxy()
        {
            
super NAME);
        }
        
        public function 
set time(ms_:int):void
        
{            
            
_time=ms_;
            if(
_time<=0)
                
sendNotification(ApplicationFacade.GAME_OVER);
            else
                
sendNotification(ApplicationFacade.UPDATE_TIMEtimeString(_time));
        }
        
        public function 
get time():int
        
{
            return 
_time;
        }
        public function 
get lastTime():int{
            return 
_lastTime;
        }
        
        public function 
set lastTime(ms_:int):void{
            
_lastTime=ms_;
        } 

Geändert von casualistics (15-06-2010 um 10:45 Uhr)
casualistics ist offline   Mit Zitat antworten
Alt 15-06-2010, 12:59   #2 (permalink)
mushroom powered
 
Benutzerbild von b.asile
 
Registriert seit: Jun 2005
Ort: Amsterdam
Beiträge: 2.649
Du darfst die dein MVC Konstrukt nicht verkomplizieren,
dann wirst du nie fertig und/oder im Fall von Flash,
bekommst du Probleme mit der Performance.

In verschiedenen Faellen ist es sinnvoll Logik im View zu halten,
wie zb. bei dem EnterFrame.
Da wuerde ich deinen Model + Controller in den View stopfen,
da der EnterFrame ja wahrscheinlich nicht von allzu grossem Belang fuer andere Models/Views ist.
Notifications wuerde ich dann auf GAME_START/GAME_END etc. eingrenzen.

Ich orientiere mich immer an der BusinessLogic: Business logic - Wikipedia, the free encyclopedia ,
was bei mir in die MVC Struktur kommt.
__________________
[ WHEN THE GOING GETS WEIRD THE WEIRD TURN PRO ]

devboy.org
b.asile ist offline   Mit Zitat antworten
Alt 15-06-2010, 13:17   #3 (permalink)
Perverted Hermit
 
Benutzerbild von Omega Psi
 
Registriert seit: Mar 2004
Ort: Delmenhorst
Beiträge: 11.856
Es ist wichtig zwischen dem Verhalten einer Komponente, das nur die Komponente selbst interessieren sollte und der Applikationslogik zu unterscheiden. b.asile hat schon ganz recht mit dem was er sagt: die Komponente arbeitet weitestgehend autark und spricht nur über definierte Schnittstellen und Events mit anderen Komponenten/der Applikation (respektive via Mediator).
Omega Psi ist offline   Mit Zitat antworten
Alt 15-06-2010, 19:45   #4 (permalink)
Neuer User
 
Registriert seit: Jun 2010
Beiträge: 4
Danke für eure Ansätze. Ganz habe ich es leider nicht verstanden, vorallem bei der Platzierung von Business und Applicationslogic. wie b.asile sagt alles in den View, seh ich nicht ganz ein. Die Zeit muss in mehreren Views erreichbar sein, deswegen würde ich die gerne in ein Model packen. Meine Überlegung ist folgende:

-TimerProxy:
Beinhaltet Timer oder EnterFrame und sendet TICK.
als Datensatz hat der die Zeit in ms.
BusinessLogic z.B. Manipulation der Zeit von ms zu TimeString

-ToggleTimerCommand
ApplicationLogic:
Manipulation des TimerProxy, schaltet den Timer/EnterFrame an oder aus.

-ViewMediator
Ist am Tick intressiert.
ApplicationLogic z.B. checkCollisions oder pause_btn --> ToggleTimerCommand

So würde man doch eine strikte Trennung und Autarkie der Komponenten erreichen. Seht ihr das auch so?
casualistics ist offline   Mit Zitat antworten
Alt 16-06-2010, 07:26   #5 (permalink)
ehemals dr.ache
 
Benutzerbild von malthoff
 
Registriert seit: Sep 2001
Ort: Unterhaching/München
Beiträge: 510
Die bisherigen Antworten gehen auf deine Befürchtung bereits ein und zeigen mögliche andere Lösungen. Du sagst, Du hast Framedrops. Also scheint das Zwischenschalten von PureMVC Notifications deinen EnterFrame Berechnungen nicht gut zu tun.

Daher war der Ansatz, dieses Geschehen direkt im View zu behandeln, um dein Framedrop Problem zu umgehen. Sicherlich entspricht dein Vorgehen einer eindeutigeren Trennung aber mit welchen Ergebnis?

Wenn Du eine Anwendung hast, in der es nicht auf Performance ankommt, wäre dein Vorgehen strikter und vielleicht besser. Aber in diesem Falle ist es wohl vorzuziehen, die rechenintensiven Prozesse beieinander zu halten.

Es spricht ja nichts dagegen, dass die Zeit per Notification auch an andere Komponenten geschickt wird, bei denen ein Framedrop nicht zu Problemen führt. Da die Zeit aber tatsächlich nur beim laufenden Spiel von Bedeutung ist, kann sie ruhig auch da gehalten werden. MVC keine Doktrin, sondern 'eine Möglichkeit' es gut aufzubauen.
malthoff ist offline   Mit Zitat antworten
Alt 16-06-2010, 08:16   #6 (permalink)
Perverted Hermit
 
Benutzerbild von Omega Psi
 
Registriert seit: Mar 2004
Ort: Delmenhorst
Beiträge: 11.856
Ich würde zum Beispiel nicht verstehen, warum ein Timer ins Model soll, wenn es doch dazu dienen soll, die View zu steuern. Dann gehört das Ding entweder in einen Controller/Mediator oder direkt in die View wenn es Verhalten implementiert.

Es macht natürlich einen extrem aufgeräumten Eindruck, aber verkompliziert die Interaktion der Komponenten ungemein. Was aber noch viel wichtiger ist. Ein Timer ist ist ausgelagerte Funktionalität, die aber keinen Zustand der Applikation oder einer Komponente persitiert/abbildet. Das wäre mein Argument gegen eine solche Struktur.
Omega Psi ist offline   Mit Zitat antworten
Alt 16-06-2010, 11:19   #7 (permalink)
Neuer User
 
Registriert seit: Jun 2010
Beiträge: 4
Danke für das Feedback.
@Dr.Ache: Die FrameDrops resultieren auf jeden Fall aus den CHECK_COLLISIONS und MOVE_HERO Notifications, die verarbeite ich auch in Commands wobei ich jedesmal die Positionen aus einen HeroProxy und einen ObstacleProxy gegeneinander prüfe und neu schreibe, das ist wahrscheinlich zu viel. Das werde ich nun in den betroffenen Mediators abfragen, um die rechenintensiven Prozesse beieinander zu halten.

@Omega Psi: Der currentCount des Timers/EnterFrames stellt den Zustand, in jedem Fall einen Datensatz der Applikation dar und verdient einen Platz im Model. Den Timer ansich könnte man aus dem Model nehmen in einer eigenen Utility/Manager Klasse unterbringen.

Was ich noch nicht ganz einsehe, warum die Interaktion der Komponenten kompliziert wird? Sieht doch so einfach aus

Timer -->setTime--> TimerProxy-->update--> Mediator

Geändert von casualistics (16-06-2010 um 11:22 Uhr)
casualistics ist offline   Mit Zitat antworten
Alt 17-06-2010, 19:57   #8 (permalink)
Neuer User
 
Registriert seit: Jun 2010
Beiträge: 4
Auf den Timer im Model bin ich gekommen, weil ich mich daran orientiert habe:
Making a Flash Game using PureMVC
Move the Cheese: A non-Flex Actionscript example of a PureMVC Multicore Application | ActionScript 3 Design Patterns

Aber Ihr habt recht. Ich nutze jetzt PureMvc eigentlich nur zur Verwaltung Application Stati (Intro/Outro, Start/Stop Game) und der BusinessLogic, z.B. Level.xml laden, parsen und im Proxy speichern. Im View liegt dann GameTimer, GameLogic und InputController etc... Bei GameOver wird dann erst die Score und der Timercount via Notification im GameProxy gespeichert.
So wird ein Schuh draus Danke für den Schubs in die richtige Richtung.

Geändert von casualistics (17-06-2010 um 19:58 Uhr)
casualistics ist offline   Mit Zitat antworten
Alt 18-06-2010, 21:49   #9 (permalink)
ehemals dr.ache
 
Benutzerbild von malthoff
 
Registriert seit: Sep 2001
Ort: Unterhaching/München
Beiträge: 510
Den Blog verfolge ich auch seit langer Zeit und finde den Inhalt sehr lesenswert. Ich kenne keine bessere und intensivere Behandlung des Themas Design Pattern in Actionscript.

Was das Beispiel angeht liegt der Schwerpunkt mehr auf der betonten Benutzung von Pattern - hat eher theoretischen Wert. Oder besser gesagt: Es ist auf dein Beispiel nicht direkt übertragbar, da es performancelastig ist. Ein Spiel ohne kostbare Algorithmen wäre sicherlich so umsetzbar gewesen.
malthoff ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Stichworte
as3, gameloop, gametimer, puremvc

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
pure AS 2.0 components negttid Softwarearchitektur und Entwurfsmuster 6 30-09-2005 16:36
loop..loop..loop -> keyframe ->loop2..lopp2... Mtron Flash MX 1 19-04-2005 09:24
FormGenerator [MX] [pure AS] Hamster2k ActionScript 1 3 29-09-2003 07:52
Pure Data beachmeat Flash Media Server 2 16-04-2003 03:02
Pure Verzweifelung TobiS Flash 4 und Flash 5 2 30-09-2001 20:14


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:18 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele