Le moteur 3d ECO
IA simple

Mossy est un exemple de jeu mélangeant les décors en 2d et le personnage en 3d. Il montre l'utilisation d'une intelligence artificielle simple. La différence avec les scènes animées des jeux (moment de dialogue par exemple) est que chaque élément (personnage ou décoration) possède un fichier qui lui est propre, et tout se déroule en parallèle.
mise à jour à venir...
Explications :
L'IA est gérée par la classe Tia, conjointement avec le module modJeu/Mia. Le principe est le suivant :

La classe Tia charge le fichier associé à l'élément (perso, mécanisme, aide, …) selon le format de ligne : code ligne/action-verbe/paramètres/branchement oui-non.
Voici une partie du code pour le personnage d'arrière-plan (modJeu/common_jeu.h)
{ "000|fin|null|000|000"},
{ "001|tps|3|002|000"},
{ "002|ani|ani marche 999|003|000"},
…
{ "011|mvt|0.05 / 22.47 8 1|012|000"},
{ "012|del|null|000|000"}
La première ligne est toujours une ligne neutre, on se branchera sur elle en cas d'erreur ou quand le cycle d'IA de l'élément est terminé (dernière ligne, le lien « oui » branche sur la ligne « 000 »). Notez que le numéro de ligne est en fait une clef, elles n'ont donc pas besoin de se suivre rigoureusement. Le lien « 002 » de la deuxième ligne va se brancher sur la ligne avec le code « 002 ».
À chaque cycle de jeu, la classe Tia vérifie s'il y a une instruction en attente et, le cas échéant, se branche sur la fonction correspondante. Le code « tps » (deuxième ligne), par exemple, indique une demande de pause. Tant qu'elle n'est pas terminée, c'est la fonction ia_pause qui sera appelée (ici pendant 3 secondes). Ensuite le lien nous mène vers la ligne ayant le code « 002 ». Ce sera cette fois une animation qui sera lancée.
Tout cela est géré dans le module modJeu/Mia, par la fonction ia_tactique (Maide pour le tuto) :
for (size_t i = 0; i < perso2d.size(); i++)
{
switch(perso2d[i].tactique.getAction())
{
//case AIA_NULL:
// break;
case AIA_TPS:
ia_perso2d_tps(i);
break;
Et voici l'action « pause » :
// 001|tps|0|002|000
void TmodJeu::ia_perso2d_tps(size_t ref)
{
std::string str;
uint64_t tps;
// >>> initialise et bloque l'initialisation de l'action
if (perso2d[ref].tactique.getValue_bool() == 0)
{
perso2d[ref].tactique.setValue_bool(1);
// >>> utilise les valeurs de Tia pour stocker le temps de pause
// >>> on choisi donc d'utiliser un uint_64
str = perso2d[ref].tactique.getParam();
tps = ECO_strToInt(str);
perso2d[ref].tactique.setValueT64(ECO_getTicks() + (tps*1000) );
}
// >>> quand le temps est écoulé, passe à la ligne suivante
// >>> ne pas oublier de remettre les valeurs à zéro
if (ECO_getTicks() > perso2d[ref].tactique.getValueT64())
{
perso2d[ref].tactique.setLigne(perso2d[ref].tactique.getLien1());
perso2d[ref].tactique.razValues();
}
}
Autre exemple : ici c'est l'élément aide qui est appelé ; la ligne est la suivante :
{"level_0", "001|msg|aide.png 0 0 640 64 / 200 64 / 5000|002|000"},

Vous pouvez aller voir le fichier modJeu/donnees/aide.png.le morceau d'image est bien en 0,0 avec 640 pixels de large et 64 de haut. Ensuite vient la position d'affichage (en mode classique ; vous pouvez donc utiliser une capture d'écran pour positionner vos éléments). L'image est affichée 5 secondes (on peut aussi utiliser des cycles, par exemple, ici : 50 fps * 5 = 250 ; à vous de faire comme vous préférez).
Notez que l'on peut ajouter un paramètre pour, soit passer directement à la ligne suivante, soit attendre la fin du temps d'affichage.
Voici un autre exemple :
{"level_0", "020|obj|qte_jaune conteneur ***|021|000"},
{"level_0", "021|msg|aide.png 192 64 192 64 / 1600 370 / 5000|000|000"},

Il n'y a pas de règle sur les paramètres à utiliser. Ici j'ai décidé que le verbe « obj » servait à déterminer si un objet (le chapeau) avait comme conteneur une référence (ici détruit).
Le cycle d'ia se poursuit donc jusqu'à ce que le personnage du joueur se soit approché du chapeau jaune (en bas à droite dans l'écran de jeu), ce qui détruit le chapeau (grâce à un test de collision) ; le chapeau prend donc le code conteneur = « détruit » (le code conteneur détermine qui possède l'objet : null, le code du perso, ou détruit.
Le test est donc validé, on passe à la ligne « 021 », affichage de l'image.
Enfin, pourquoi un branchement oui-non ? Et bien, par exemple, si votre personnage avait un choix, entre un chapeau rouge et un chapeau jaune, la suite du fichier serait différente.
On peut aussi considérer un personnage n'ayant plus assez de points de vie pour une action « oui », et se branchant sur la tactique « non » (fuir ? ).