'Maxima' est un framework développé en ActionScript 3.0 et conçu pour la mise en place d'architectures de jeux vidéos Flash Based avec support de l'API 3D Molehill.

Flash

AIR

Molehill support

Le but de ce framework est de faciliter la mise en place de l'architecture d'un jeu vidéo.
On note que dans un jeu il y a souvent le même schéma : Splash screen, écran principal avec différentes sous-rubriques, le jeu, écran de pause, écran de score, un chargement de ressources à tout moment...

Maxima fournit la logique d'enchaînement de ces éléments. Il faut d'abord référencer toutes les classes de l'architectures, et au fur et à mesure que l'on avancera dans l'architecture, un système de navigation permettra d'aller à l'élément suivant ou précédent ou vers un élément particulier en gérant automatiquement un système d'historique.
Lorsque l'on va d'un élément vers un autre, la framework exécute la méthode de sortie onExit() dans l'élément courant. Il est tout à fait possible d'ajouter divers effets de transitions, car une fois la méthode mère appelée, c'est à ce moment que le framework exécutera la méthode d'entrée onEntry() dans le nouvel élément courant.
Les éléments de l'architecture sont instanciés et supprimés automatiquement par le framework lorsqu'ils sont appelés par le système de navigation. Concernant ces classes, la surcharge est obligatoire puisque tous les éléments de bas niveaux sont abstraits.

Le GameContext définit la couche basse du jeu, écoute les évènements nécessaires du Stage et permet l'ajout d'éléments.
Il étend plusieurs classes qui elles contiennent plusieurs outils, méthodes et informations concernant le framework et le player Flash.

Pour ce qui est de l'état général du jeu, le GameContext remplacera le Stage car il se chargera d'écouter les informations de ce dernier afin de les traiter à sa manière et de diffuser entre autres des évènements comme :
- le redimensionnement dynamique de la fenêtre du jeu
- l'activation et la désactivation du focus du jeu
- les interactions avec les périphériques externes (clavier, souris...)
- la gestion des erreurs au cours de l'exécution
- la création et la destruction des éléments de l'architecture
- l'ajout et la destruction de composants
- le rendu en temps réel
Toutes ces informations seront traitées et diffusées sous forme d'évènements personnalisés tels que : GameEvent, GameErrorEvent, GameInputEvent, DirectInputEvent, NavigationSystemEvent...

Le GameContext impose des méthodes pour gérer les composants, sans avoir besoin de créer les instances au préalable, il faut simplement passer en paramètres les différentes classes et le GameContext se charge de créer les instances et les dépendances.

Le GameContext donne également accès à un RenderEngine basé sur l'évènement Event.EnterFrame. Il calcul en temps réel le framerate, la mémoire consommée, le temps écoulé et envoi des évènements lors d'actions sur son lancement, son arrêt et son rafraichissement.
Il est accessible depuis le GameContext via un accesseur et contrôlable de cette manière : this.renderEngine.start().
Il suffit ensuite d'écouter RenderEngineEvent.ON_RENDER pour pouvoir rafraîchir des éléments en temps réel.
Un accesseur heartbeatFunction permet de passer en paramètre une méthode qui sera automatiquement invoquée toutes les secondes.

Tous ces éléments contiennent des méthodes communes, notamment de construction et de destruction qui doivent obligatoirement être surchargées afin de garantir un cycle de vie optimal pour l'application.

Des utilitaires tels qu'une console de log, une machine à état et des opérations sur les objets Array, Math, Object, RegExp, String sont également disponibles dans le framework.

Création du contexte depuis la classe Main.

                    private function setupGame():void {
                      _game = new MyGame();
                      _game.contextView = this;
                      
                      _game.setup();
                    }
                

Exemple de classe : la classe MyGame avec les méthodes nécessaires.

                  package artcustomer.com.citrusmaxima.api {
                    import artcustomer.maxima.context.*;
                    import artcustomer.maxima.events.*;
                    
                    
                    public class MyGame extends Context {
                      
                      
                      public function MyGame() {
                        super();
                      }
                      
                      
                      /**
                       * Setup instance. Set params before call this method.
                       */
                      override public function setup():void {
                        super.setup();

                        this.scoreEngine.setManager(GameScoreManager);
                        this.gameEngine.setGlobalLoader(GameAssetsLoader, 'gameAssetsLoader');
                        this.gameEngine.setView(SplashScreenView, 'splashScreenView');
                        this.gameEngine.setGame(GameDisplay, 'gameDisplay');
                        
                        this.start();
                      }
                      
                      /**
                       * Destroy instance.
                       */
                      override public function destroy():void {
                        super.destroy();
                      }
                    }
                  }
                

Ajouter un contrôle depuis une classe héritant de AbstractEngineInteractiveObject (un élément intéractif visuel comme DisplayView).

                  /**
                   * @private
                   */
                  private function setControls():void {
                    var builder:ControlTableBuilder = new ControlTableBuilder();
                    var table:ControlTable;
                    
                    builder.addControl(ControlType.KEYBOARD, '32');
                    builder.addControl(ControlType.MOUSE, 'click');
                    table = builder.assemble();
                    
                    this.mapControl(ControlActions.VALIDATE, table);
                    
                    builder.destroy();
                  }
                  
                  /**
                   * On control released.
                   * 
                   * @param control
                   */
                  override protected function onControlReleased(control:IGameControl):void {
                    switch (control.action) {
                      case(ControlActions.VALIDATE):
                        break;
                        
                      default:
                        break;
                    }
                  }
                

Charger un asset depuis une classe héritant de GlobalLoader.

                /**
                 * @private
                 */
                private function loadLogo():void {
                  this.queueAsset('assets/images/content/splash_logo.jpg', 'splash_logo', 'logos');
                  this.load('Logo');
                }
                
                /**
                 * AssetsLoaderEvent.LOADING_PROGRESS Callback.
                 * 
                 * @param e
                 */
                override protected function onCompleteLoading(e:AssetsLoaderEvent):void {
                  switch (e.description) {
                    case('Logo'):
                      break;
                      
                    default:
                      break;
                  }
                }
                

Naviguer dans la timeline.

                /**
                 * @private
                 */
                private function goForward():void {
                  this.context.instance.gameEngine.navigationSystem.timelineForward();
                }
                
                /**
                 * @private
                 */
                private function goBack():void {
                  this.context.instance.gameEngine.navigationSystem.timelineBack();
                }
                

Jouer un son.

                  override public function setup():void {
                    super.setup();                    
					
                    this.sfxEngine.playStreamOnChannel('sound.mp3', 0);
                  }
                

Exemples d'implémentations du framework Maxima.

Mine Sweeper

Consultez l'AsDoc en ligne.
Téléchargez le package d'extensions.
Téléchargez le package Flash de Maxima version 0.8.0.0.
Accéder au repository de Maxima sur Github.