Wednesday, June 10, 2009

Non, ça n'ira pas...

Je bricole ces derniers jours la partie du GameEngine qui permettra d'appeler du code C++ à partir des transitions : les GunFactories (essentiellement parce que c'est une généralisation du mécanisme destiné à permettre aux sprites de tirer d'autres sprites). Comme premier test, évidemment, j'essaie de créer une action externe capable de charger un nouveau niveau (ou de recharger le niveau en cours).

Je voulais gérer tout ça directement depuis le GameScript, mais ça ne marche pas... Ca ne peut pas marcher. Le GameScript ignore d'où lui proviennent les lignes du script, et il contient tout l'état en cours du niveau. Tant que le GameScript existe, les sprites se déplacent, se collisionnent, etc. On n'a pas envie que Bilou se fasse toucher alors qu'il vient de finir le niveau.
Je dois remonter plus haut dans la logique du programme, et faire de "l'inter-niveau" un état de fonctionnement indépendant (c'est à dire une fenêtre différente, vu la structure que j'ai donnée à mon "GuiEngine").

At some point, i want my little scripts to be able to invoke some more sophisticated C++ code. It is clearly needed to fire lasers, for instance. The C++ code will create the new GOB, adjust its location, register it and so on. It will also be useful to trigger sound effects or any kind of graphic effect you can think of in response to collisions or "level events". But most of all, samy is my hero I need it to load levels in-game.

Yet, it isn't as straightforward as i thought it'd be in first place. I need an intermediate "state" where the loading is already taking place but the game's logic is suspended. Something like an IntermissionWindow where i can play a little animation while the script is being parsed, etc. Morukutsu uses something similar (a StateManager pattern) in Inside the Machine, and i have such a "menu -> level1 -> intermission -> level1 (you'll better watch your steps this time) -> intermission -> level2" system in my "Gui Engine" used in SEDS and LEDS. So despite I find it weird to involve the GuiEngine within the game, that's actually the way to go.

  • LevelGun.shoot() modifies some state in GameScript that indicates a new level should be run and that's level2
  • it will then send an event to the GameWindow that in turns activate IntermissionWindow
  • by leaving one window, we invoke cleanup such as killing the gamescript and so on.
  • We're on intermission window. we can play a little animation, showing the score or a "retry/abort" question. Some background loading could happen here, though i not quite don't know how exactly.
  • When the level is ready, we return to GameWindow where the gobs are actually instanciated, the level music launched and game control restored.
It requires a little more thinking as the GameScript will actually be shared by both windows (in order to do some preloading). I think i could live with something that do all loading in the GameWindow.

Grosso modo LevelLoaderGun.shoot() devra provoquer qqch comme GuiEngine::setwindow(intermissionWindow), qui nous mettrait un (retry / exit to main menu)

Dans "Inside the Machine", Morukutsu nous avait fait quelque-chose dans cette veine-là via son "state manager". Bref, il y a un peu de re-design à faire mais je n'ai pas encore le recul nécessaire.

edit: c'est fait. Voir LoadingWindow dans game.cxx et LevelGun dans guns.cxx

No comments: