Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Vos tutoriels et astuces


Index du Forum » Vos tutoriels et astuces » [C-Engine] n°6 : Ajout d'un objectif
Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

[C-Engine] n°6 : Ajout d'un objectif

Posté le 14/04/2016 17:22

Si vous possédez une version ultérieur à celle du 14 / 04, ce tuto nécessite une mise à jours du C-Engine,

Etape 1 : Création de la pièce.

Pour commencer , commençons par créer la pièce. Vous savez le faire donc je vous donne tout de suite le code.

Les sprites :

const unsigned char Po1[]={0x1e,0x0,0x21,0x0,0x40,0x80,0x8c,0x40,0x88,
0x40,0x88,0x40,0x8c,0x40,0x40,0x80,0x21,0x0,0x1e,0x0};
    const unsigned char Po2[]={0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70};

    Sprite S_Coins1(Po1,10,10);
    Sprite S_Coins2(Po2,5,10,3,0);

    Sprite S_Coins[]={S_Coins1,S_Coins2};
    Animation A_Coins(S_Coins,2,150);


La déclaration de l'objet :
Object * Coins = new Object;
    Coins->GetTransforms()->SetXY(100,14);
    Coins->GetRender()->SetRender(A_Coins);
    Coins->AffectTag("Coins");


La fonction AffectTag() permet de nommer l'objet, utile pour plu-tard.

N'oubliez pas de l'associer au moteur.
Game.AddObject(Coins);


Etape 2 : Mise en place dans le script du joueur.

Ensuite, nous voulons que lorsque le joueur touche la pièce, elle soit détruite.

Dans le script du joueur, nous allons tout d'abord commencer par la condition qui est "si le joueur touche la pièce " qui dans le C-Engine s'écrit :
if(GetObject()->CollisionTag("Coins");// Pas définitif
{

}


Nous retrouvons le tag que nous avions donné à la pièce.

Maintenant il faut détruire la pièce, pour cela il nous faut l'adresse en mémoire de la pièce, déclarons donc une variable qui peut stocker une adresse d'objet que nous allons nommer Buffer.
Object * Buffer; // Cette ligne n'est pas définitive


Ensuite nous allons utiliser utiliser une fonction qui renvoie une adresse en mémoire du premier objet portant le tag donné en paramètre qui touche le joueur.

Object * Buffer = GetObject()->CollisionTagO("Coins");//A placer à la fin du script du joueur.


Si le joueur ne touche pas de pièce alors Buffer est égale à NULL sinon il possède l'adresse de la pièce. Nous pouvons donc tester la valeur de Buffer pour connaitre si le joueur touche la pièce.

if(Buffer != NULL) // A mettre à la suite de la déclaration de Buffer.
    {
      
    }


Ensuite nous allons détruire la pièce, si le joueur touche la pièce, avec la commande suivante :
GetEngine()->DelObject(Buffer);


Vous pouvez essayer de compiler, normalement lorsque vous touchez la pièce elle disparaît.


Etape 3 : Ajout d'un score et script GUI.

Maintenant que nous avons détruit la pièce, nous pouvons rajouter un score et une gui.

Pour la GUI, il faut créer un nouveau script que vous nommerez GUI et qui contiendrerra une variable pour stocker le score comme ceci.
class GUI: public Script
{
    public:
    void Start();
    void Update();
    void AddCoins(int v);

    int coins;
};


Cette class possède une fonction pour augmenter le score. Elle est très basic.

void GUI::AddCoins(int v)
{
    coins += v;
}


Dans la fonction Start(), nous allons initialiser à 0 le score.
void GUI::Start()
{
    coins = 0;
}


Après avoir réalisé ceci, vous pouvez créer l'affichage que vous voulez pour afficher le score.

Il existe la fonction PrintV(x,y,v) qui affiche un nombre en x y de valeur v.
Pour écrire du texte je vous conseille PrintMini(x,y,"Votre Texte",0).

Personnellement, j'ai choisi un cadre avec à l'intérieur écrit "Score:".
Voici le code:

void GUI::Update()
{
    ML_rectangle(-1,-1,128,7,1,ML_BLACK,ML_WHITE);
    PrintMini(5,1,"Score :",0);
    PrintV(35,1,coins);
}


Pour finir nous allons lié le script du joueur à la GUI en rajoutant ceci à la déclaration de la class Control.
class Control: public Script
{
    public:
    void Update();
    GUI * S_GUI;
};


Dans la condition où la pièce est détruite vous pouvez rajouter 1 point au score affiché.
S_GUI->AddCoins(1);


Pour finir, il faut dans la fonction Jeu créer la GUI puis la lié au moteur et au script du joueur.
GUI * S_GUI = new GUI; // à placer après la déclaration du niveau.
    Game.AffectScript(*S_GUI);

    ScriptPerso->S_GUI = S_GUI;


Vous pouvez compiler, le score est affiché et la pièce ajout 1 point au score.

Je met à disposition les sources du projet que j'ai obtenu -ici-

Etape 4 : Allez plus loin.....

Maintenant que vous pouvez créer des pièces, créer un timeur dans la class GUI qui débute à 30 puis qui toutes les secondes diminue de 1.

UpdateEverySecond() vous aidera, cette fonction est identique à Update mais elle est appelé qu'une fois par seconde.

Ensuite fixez un objectif de 10 pièces au joueur. Et si il n'a pas ramassé toutes les pièces avant la fin du chrono alors il perd et le jeu quitte sinon il gagne.

Vous pouvez bien sur agrandir la map.

La fonction GetEngine()->StopGame() vous aidera et pour l'affichage de l'écran de fin de partie vous pouvez faire:

if(le joueur a perdu)
{
        ML_clear_vram();
        PrintMini(20,30,"Perdu",0);
        ML_display_vram();
        Sleep(500);

        GetEngine()->StopGame();
}


Bonne chance pour ce petit test, envoyer moi en MP vos réponses.

Fichier joint


Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

Citer : Posté le 26/04/2016 16:09 | #


Est ce que quelqu'un a réalisé la partie "Aller plus loin " ?
It's Show Time !!!
Mes Jeux :
- Street Fighter : Pour les accrocs du free-fight.
- Kirby's DreamLand : Gobe , Gobe , Gobe !!!
- L'invasion Seanchans : Détruit la flotte ennemis a bord du "Danseur des vagues".


< Le recoin du C-Engine >
Lephenixnoir En ligne Administrateur Points: 24227 Défis: 170 Message

Citer : Posté le 30/04/2016 15:43 | #


Je me suis permis de couper une ligne contenant des sprites pour éviter de déformer la mise en page
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Ninestars Hors ligne Membre Points: 2461 Défis: 24 Message

Citer : Posté le 08/05/2016 23:28 | #


Pourquoi le scipt pour tester la collision n'est pas associé à la pièce ?
Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

Citer : Posté le 09/05/2016 07:54 | #


C est pour éviter trop de calcul, ici la fonction GetObject avec le tag pièce est appellée une seule fois par frame alors que si on le met sur la pièce, elle serait appellée plusieurs fois par frame. Après c'est tout à fait envisageable.
It's Show Time !!!
Mes Jeux :
- Street Fighter : Pour les accrocs du free-fight.
- Kirby's DreamLand : Gobe , Gobe , Gobe !!!
- L'invasion Seanchans : Détruit la flotte ennemis a bord du "Danseur des vagues".


< Le recoin du C-Engine >
Ninestars Hors ligne Membre Points: 2461 Défis: 24 Message

Citer : Posté le 09/05/2016 13:48 | #


Pourquoi elle serait appelé plusieurs fois par frames ?
Si c'est dans la fonction update, cette fonction est appelé une fois par frame.
(J'ai pas essayé, j'ai juste lu tes tutos )

Par ce que ça me parait plus logique. Je ne suis plus certain, mais il me semble que c'est toi qui te base sur rpg maker. Et bien, il n'y a aucun script associé au héros. On ne vérifie pas si la héros touche la pièce, mais si la pièce touche le héros. Ça permet de faire des copier coller facilement.
Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

Citer : Posté le 09/05/2016 17:48 | #


Oui mais si il y a plusieurs pièces, chacune des pièces va vérifier si elle touche le joueur alors que ici on vérifie une seule fois si le joueur touche une pièce. Sur un Pc, on peut négliger les calculs mais sur calculatrice, si il y a 250 pièces ça commence à faire beaucoups de calcul.
It's Show Time !!!
Mes Jeux :
- Street Fighter : Pour les accrocs du free-fight.
- Kirby's DreamLand : Gobe , Gobe , Gobe !!!
- L'invasion Seanchans : Détruit la flotte ennemis a bord du "Danseur des vagues".


< Le recoin du C-Engine >
Ninestars Hors ligne Membre Points: 2461 Défis: 24 Message

Citer : Posté le 09/05/2016 19:10 | #


D'accord, mais je ne comprends pas comment tu peux vérifier si le héros touche une ou des pièce(s) sans faire le test de collision pour toutes les pieces...
Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

Citer : Posté le 09/05/2016 19:11 | #


En gros si il touche une pièce il arrête de chercher. Et puis ça m'évite de mettre un script sur les pièces.
It's Show Time !!!
Mes Jeux :
- Street Fighter : Pour les accrocs du free-fight.
- Kirby's DreamLand : Gobe , Gobe , Gobe !!!
- L'invasion Seanchans : Détruit la flotte ennemis a bord du "Danseur des vagues".


< Le recoin du C-Engine >
Ninestars Hors ligne Membre Points: 2461 Défis: 24 Message

Citer : Posté le 09/05/2016 19:25 | #


Faire ça ne réduit en rien le nombre de calculs.
Uniquement à LA frame où la héros touche une pièce le calcul s'arrete plus tôt. Plus tôt de combien ? Aucune idée, c'est plus ou moins aléatoire. Tout le reste du temps tu fais le test de collision pour toutes les pièces.
Si tu veux gagner vraiment en perf, tu fais les test une frame sur trois, vu la vitesse du héros, on ne risque pas de louper une pièce
Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

Citer : Posté le 09/05/2016 19:37 | #


Oui après chacun peut optimiser le C-Engine, je donne les bases puis vous faites évoluer le projet. Je suis content que quelqu’un propose quelque chose qui ne soit pas " J'ai une erreur". Si tu veux mettre le test de collision sur la pièce tu peux très bien le faire car tout est déjà dans les tutos.
It's Show Time !!!
Mes Jeux :
- Street Fighter : Pour les accrocs du free-fight.
- Kirby's DreamLand : Gobe , Gobe , Gobe !!!
- L'invasion Seanchans : Détruit la flotte ennemis a bord du "Danseur des vagues".


< Le recoin du C-Engine >
Lephenixnoir En ligne Administrateur Points: 24227 Défis: 170 Message

Citer : Posté le 10/05/2016 19:07 | #


Fife86 a écrit :
En gros si il touche une pièce il arrête de chercher.

Imaginons, disons, un jeu en 2D en vue de dessus, où l'on peut faire apparaître (par exemple en tuant des mobs) des objets en drop, qui se placent à n'importe quelle position (au pixel) en attendant qu'on les ramasse.
Avec ce comportement, même si deux objets sont théoriquement à portée du joueur, un seul sera ramassé. Dommage, non ?
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

Citer : Posté le 10/05/2016 19:18 | #


Oui mais la frame d'après c'est à dire environ 20 ms plus tard, l'autre objet est ramassé.

Ajouté le 10/05/2016 à 19:20 :
Et puis il y a plusieurs façon de faire, il est possible de créer sa propre fonction qui renvoi un tableau d'adresse de tout les objets ayant le tag "tag", et étant proche de à 10 pixels.
It's Show Time !!!
Mes Jeux :
- Street Fighter : Pour les accrocs du free-fight.
- Kirby's DreamLand : Gobe , Gobe , Gobe !!!
- L'invasion Seanchans : Détruit la flotte ennemis a bord du "Danseur des vagues".


< Le recoin du C-Engine >
Lephenixnoir En ligne Administrateur Points: 24227 Défis: 170 Message

Citer : Posté le 11/05/2016 17:13 | #


Fife86 a écrit :
Oui mais la frame d'après c'est à dire environ 20 ms plus tard, l'autre objet est ramassé.

Un défaut structurel ne peux pas être masqué par un effet de vitesse, c'est assez aberrant ! Bon allez, je suis chiant : rien ne dit qu'à la fin de ce jeu tu pourras pas avoir 100 items en drop en même temps. (Enfin, je crois que tu as compris x) ).

Fife86 a écrit :
Et puis il y a plusieurs façon de faire, il est possible de créer sa propre fonction qui renvoi un tableau d'adresse de tout les objets ayant le tag "tag", et étant proche de à 10 pixels.

Tu disais que l'arrêt de la recherche se faisait pour des raisons d'optimisation non ? S'il faut comparer des chaînes de caractères pour trouver des tags pour chaque objet, la vitesse en prend un coup bien plus grand... Et puis ce serait plus lourd que d'attribuer des scripts (de simples pointeurs) aux objets, par ailleurs.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Dark storm En ligne Labélisateur Points: 11634 Défis: 176 Message

Citer : Posté le 11/05/2016 17:18 | #


+1 pour Lephe. C'est pas parce que le jeu fonctionne bien pour toi que c'est pareil pour tout le monde x)
Finir est souvent bien plus difficile que commencer. — Jack Beauregard

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 70 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd