Monday, August 09, 2010

C'était bien ça ...

J'avais pris une approche un peu trop "frileuse" en choisissant d'exécuter l'expression accollée à un changement de niveau avant le changement de niveau lui-même. Cela signifie en particulier que l'action "changer le niveau" aura le dernier mot quoi que l'expression puisse tenter de faire, rendant impossible des construction du genre si (vies=0) alors gameover() sinon réessaie(ce_niveau).

Let's put it somehow back in perspective. First, my friend Pierrick suggested that the amount of apples to defend against would be based on the #level we're in. Then I realised that some tweaking was required to let the game engine distinguish "you're dead. try again?" from "well done! next level!". That tweaking took the form of a GobExpression attached to the action "level(greenX.cmd)", which compensated the automatic "level++" incrementation I added in the game script.

In that setting, it should have been fairly simple to "code" the game over. When the hitpoints counter reach zero, it automatically executes the action "level(greenX.cmd)" and evaluate the expression "level--" to restore balance in the world. Unfortunately, I coded that a bit timidly by evaluating the expression first, and launching the new level next. The side effect is that when I replaced "level--" by "level--; lives--", the effect of 'lives reached zero. Game over. launch level0' were immediately undone by the setNextLevel("greenX.cmd") that took place afterwards. Although that looks odd, I am allowed to swap them to get it fixed, as the "setNextLevel" just stores the level's name and the actual world destruction / loading / re-creation cycle is deferred and happens between regular "game frames".

Pretty neat, uh ? no matter how many GOBs try to trigger world termination : they won't testimony it anyway because it happens out of their timespace. It's just a pity I couldn't get this sorted out last Saturday (I should have typed "cvs commit" before I powered down that workstation for the week-end) and I only know how my alpha-tester reacts in face of an endless challenge.


En réalité, exécuter setNextLevel() en premier est correct parce qu'il s'agit d'une opération qui se déclenche à retardement. Pour raisons techniques, il n'est pas possible de changer de niveau (ce qui inclus une destruction de tous les objets en cours pour reconstruire le nouveau niveau à partir du script donné) pendant la phase "animation/détection de collision" qui provoque en cascade l'exécution des actions.

L'important, c'est que le problème est réglé: on peut donc être "game over" dans Apple Assault.

PS: En général, j'évite de m'étendre sur ce genre de graissage d'engrenages, mais peut-être que ça permettra de me l'ancrer un peu plus définitivement dans la caboche. Quelqu'un a une cheville de 8 à me prêter ?

No comments: