[C-Engine] n°7 : Création de plusieurs monstres
Posté le 30/04/2016 17:47
Hey, aujourd'hui nous allons créer plusieurs monstres de deux types. Des Goombas et des Koopas. Un classique de Mario facile à reproduire.
Etape 1 : Mettre à jour votre projet
Parce que je suis gentil et que je ne veux pas vous faire réécrire tout le code du projet, je vous fournis le projet déjà terminé.
Le lien du projet :
-ici-
Ce projet a été scindé en plusieurs fichiers .cpp et .h , pour séparer les différentes class qui existe ( les scripts ). Cette division permet de rendre le projet plus clair et permet de la débuguer plus facilement. Vous trouvez donc dans le dossier projet deux class que vous ne connaissez pas, qui sont la class Goomba et la class Koopa. Ces 2 fichiers sont les scripts qui permettent d'animer les monstres. Pour l'instant les .cpp sont vides mais nous allons bientôt les remplir.
Les autres fichiers contiennent du code que vous avez déjà écrit, vous pouvez le regarder car il est commenté.
La map et le tileset ont changé car les monstres que j'ai créés étaient trop gros pour le décor. J'ai aussi agrandi la map et les blocs pour simplifier le tout.
Si vous le voulez, vous pouvez complier ce projet pour avoir un aperçu des différents objets et de la map.
Etape 2 : Création du Goomba
Nous pouvons commencer par créer le Goomba qui est le personnage le plus simple, le fichier "projet.cpp" contient déjà la définition de l'objet ainsi que ces sprites. L'objet est lié au script IaGoomba donc il ne reste qu'à compléter le script.
Pour commencer, possons nous la question : " Que fait un Goomba dans sa vie ? "
- Il marche toujours tout droit dans une direction.
- Il change de direction lorsqu'il rencontre un mur.
- Il change de direction lorsqu'il est au bord d'un trou.
- Il meurt lorsque nous l'écrasons.
- Il est stupide.
Il ne reste qu'à traduire ces affirmations en code.
Pour la première affirmation , j'ai créé dans la définition de la class IaGoomba une variable direction de type int.
- Lorsqu'elle est égale à 0, il ne bouge pas.
- Lorsqu'elle est égale à 1, il se déplace vers la droite.
- Lorsqu'elle est égale à 2, il se déplace vers la gauche.
Nous voulons qu'au départ, le Goomba se déplace vers la gauche. Dans la fonction Start(), il suffit d'initialiser la variable direction à 0.
Ensuite le reste du code sera à insérer dans la fonction Update.
Pour le déplacement, il suffit d'utiliser un switch ( un dérivé de if ) qui permet de traiter aux cas par cas les événements.
switch(direction)
{
case 1 : Move(1,0); break;
case 2 : Move(-1,0); break;
default : break;
}
Ensuite pour ajouter des yeux au goomba pour qu'il puisse identifier les éléments du décor et réagir en conséquence nous allons utiliser la fonction, de la class Rigibody, CollisionDecor.
if(GetObject()->GetRigibody()->CollisionDecor(GetX() + 1,GetY()) || !GetObject()->GetRigibody()->CollisionDecor(GetX() + 1,GetY() - 1))direction = 2;
Toutes ces conditions sont réalisées seulement si le goomba se déplace vers la droite. La première condition vérifie si le goomba n'est pas face à un mur , la deuxième si en face de lui il n'y a pas un trou. Dans les deux cas on demande au goomba de changer de direction.
Voici le code lorsque le goomba se déplace vers la gauche.
if(GetObject()->GetRigibody()->CollisionDecor(GetX() - 1,GetY()) || !GetObject()->GetRigibody()->CollisionDecor(GetX() - 1,GetY() - 1))direction = 1;
Pour finir, il reste qu'à vérifier que le goomba ne ce fait pas écraser avec la fonction OCollisionTag.
Object * Buffer = GetObject()->CollisionTagO("J1");
if(Buffer != NULL)
{
if(Buffer->GetTransforms()->GetY() > GetY() + 8 )
{
GetEngine()->DelObject(GetObject());
}
}
Tout d'abord nous récupérons un pointeur sur le joueur qui touche le goomba s'il est touché par le joueur sinon le pointeur est NULL.
Ensuite nous vérifions si le joueur se trouve ou non au-dessus du goomba, si oui alors on supprime le goomba.
Attention : La suppression de l'objet qui lié à un script dans le script auquel il est lié peut entrainer une erreur système. La cause est que si l'objet est supprimé dans le script et qu'ensuite dans le script une fonction fait appel à l'objet, cette fonction créera une erreur car l'objet n'existe plus.
Pour éviter l'erreur je vous conseille de placer la destruction de l'objet en fin de fonction.
Vous pouvez maintenant compiler le projet, le goomba se déplace et réagit aux murs et aux trous.
Etape 3 : Création du Koopa
Maintenant les choses vont devenir plus difficiles. Nous allons animer un monstre un peu plus complexe.
Pour commencer, posons-nous la question : " Que fait un Koopa dans sa fucking empty life ? "
- Il marche toujours tout droit dans une direction.
- Il change de direction lorsqu'il rencontre un mur.
- Il change de direction lorsqu'il est au bord d'un trou.
- Lorsque nous l'écrasons il se met en coquille.
- En coquille, le joueur peut le déplacer en tapant dedans.
Ce monstre possède deux animations :
- l'animation de marche
- l'animation lorsqu'il se renferme dans sa coquille.
Il va donc posséder deux états que nous allons identifier par une variable booléenne qui se trouve dans le .hpp.
C'est la variable shell qui est égale :
- à false lorsque le Koopa marche
- à true lorsque le Koopa se renferme dans sa coquille.
Nous allons donc séparer le code de la fonction Update en 2 parties.
if(!shell)
{
// Le code lorsqu'il n'est pas dans sa carapace.
}
else
{
// Le code lorsqu'il est dans sa carapace.
}
Tout comme pour le Goomba, nous pouvons replacer le script de déplacement dans chaqu'une des parties.
if(GetObject()->GetRigibody()->CollisionDecor(GetX() + 1,GetY()) || !GetObject()->GetRigibody()->CollisionDecor(GetX() + 1,GetY() - 1))direction = 2;
if(GetObject()->GetRigibody()->CollisionDecor(GetX() - 1,GetY()) || !GetObject()->GetRigibody()->CollisionDecor(GetX() - 1,GetY() - 1))direction = 1;
switch(direction)
{
case 1 : Move(1,0); break;
case 2 : Move(-1,0); break;
default : break;
}
Pour la première partie et ...
if(GetObject()->GetRigibody()->CollisionDecor(GetX() + 1,GetY()))direction = 2;
if(GetObject()->GetRigibody()->CollisionDecor(GetX() - 1,GetY()))direction = 1;
switch(direction)
{
case 1 : Move(1,0); break;
case 2 : Move(-1,0); break;
default : break;
}
pour la deuxième. La condition pour détécter le vide est enlevé dans la deuxième partie car la carpace n'identifie pas les trous.
Ensuite nous pouvons aussi dans chacune des parties demander à l'objet d'utiliser la bonne animation avec SetIt(). SetIt(0) pour la première et SetIt(1) pour la deuxième.
Pour finir, nous allons détecter si le joueur touche le Koopa.
Object * Buffer = GetObject()->CollisionTagO("J1");
if(Buffer != NULL)
{
if(Buffer->GetTransforms()->GetY() > GetY() + 8 )
{
shell = true;
direction = 0;
if(Buffer->GetTransforms()->GetX() + 8 < GetX() + 3 )direction = 1;
if(Buffer->GetTransforms()->GetX() + 8 > GetX() + 6 )direction = 2;
Buffer->GetRigibody()->GetBody()->velocity.y = 0;
}
}
C'est le code pour la première partie.
Le début vous connaissez, ensuite nous donnons true à shell. Puis on identifie dans quelle direction doit aller la coquille.
Pour la deuxième partie le code est un peu modifié.
Object * Buffer = GetObject()->CollisionTagO("J1");
if(Buffer != NULL)
{
shell = true;
direction = 0;
if(Buffer->GetTransforms()->GetX() + 8 < GetX() + 3 )direction = 1;
if(Buffer->GetTransforms()->GetX() + 8 > GetX() + 6 )direction = 2;
Buffer->GetRigibody()->GetBody()->velocity.y = 0;
}
Mettre la velocity en y du joueur permet de simuler un contact entre le joueur et la coquille.
Une fois le code entièrement écrit vous pouvez compiler, et la magie , tout s'anime.
Merci d'avoir suivi ce tutoriel et rendez-vous au prochain tuto sur les GUIs.
Etape 4 : Pour aller plus loin...
Vous pouvez, dans le script du Koopa, faire que lorsque le Koopa est dans sa coquille depuis plus de 8 secondes, il reviens dans sa forme original.
Fichier joint
Citer : Posté le 30/04/2016 20:07 | #
hepepep ton lien "ici" au début n'est pas valide
tu croyais t'en sortir comme ça x)
Citer : Posté le 30/04/2016 20:31 | #
Il le fera une fois tout terminé je pense
Citer : Posté le 30/04/2016 21:01 | #
A oui, c'est la pièce jointe
- Kirby's DreamLand : Gobe , Gobe , Gobe !!!
- L'invasion Seanchans : Détruit la flotte ennemis a bord du "Danseur des vagues".