IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

isset() en PHP / equivalent en C++ ?


Sujet :

C++

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2010
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 104
    Points : 102
    Points
    102
    Par défaut isset() en PHP / equivalent en C++ ?
    Bonjour.

    J'aimerais savoir s'il existe une fonction en C++ qui permet de vérifier si une variable est initialisé ou non.
    En PHP, cette fonction existe, il s'agit de isset() qui renvoie un bolléen. Qu'en est-il du C++ ?

    Si une telle fonction n'existe pas, comment l'implémenter ?

    Merci.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Non. C'est pour ça que tu dois les initialiser à leur définition. Que veux-tu faire exactement ?

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2010
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 104
    Points : 102
    Points
    102
    Par défaut
    En fait, je réalise un jeu en 2D style Bomberman, avec la SDL.

    Lorsqu'une bombe est posé (collage d'une surface bombe avec SDL_BlitSurface), il faut un délai d'environ 3 secondes avant qu'elle n'explose (collage d'une surface explosion avec SDL_BlitSurface par dessus la surface bombe).

    Voici ce qu'on m'a conseillé :
    La bombe est un ojbet qui a un membre "startTime" qui est le timestamp du moment ou tu a laché la bombe.
    A chaque itération (ou N itérations) de ta boucle de jeu, tu vérifie si ce startTime + 3000 est supérieur au timestamp actuel, si c'est le cas, tu explose la bombe.
    Je trouve la formulation pas très compréhenssible mais ça m'a donné l'idée de stocker le timestamp de la création de l'objet bombe dans un de ses attributs (startTime par exemple).

    Ensuite et à chaque autre ittération de la boucle de jeu, on vérifie que le timestamp actuel est supérieur ou égal à startTime + 3000 (en ms). Si VRAI alors on fait explosé la bombe.

    Le problème c'est qu'à chaque boucle de jeu, j'initialise startTime à time(0) donc le timestamp actuel, du coup ma vérification me renvoie toujours FAUX puisque c'est comme si je faisait if(time(0) >= time(0)+3000) ; et ma bombe n'explose jamais.

    De ce fait, il me faut une fonction (celle de isset en php) qui de permette de faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (startTime n'est pas initialisé)
    alors int startTime = time(0);
    sinon ne rien faire
    J'espère que je suis assez clair.

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    C'est plutôt un problème de conception. Il faut que tu initialises ta variable au moment où tu 'poses' la bombe. Pas en permanence. Je pense qu'il faut plus travailler sur ton design plutôt que de chercher une astuce du langage.

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2010
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 104
    Points : 102
    Points
    102
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Il faut que tu initialises ta variable au moment où tu 'poses' la bombe. Pas en permanence. Je pense qu'il faut plus travailler sur ton design plutôt que de chercher une astuce du langage.
    Oui effectivement c'est ce que je cherche à faire.
    Mais qu'entends tu par travailler sur mon deisgn ? Je ne vois pas de quelle manière ça pourrait régler mon problème.

    Au niveau de la conception, lorsqu'on presse la touche espace, ça appelle la fonction constructrice Bombe de la classe Bombe. Il y a une méthode explose que doit etre appellé automatiquement 3 secondes plus tard.
    Que revoir de ma conception.

    Désolé, je dois avouer que je me suis un peu perdu avec ce détail.

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    startTime devrait être initialisé dans le constructeur de Bombe si cela correspond à fonction constructrice.
    Bref, peux-tu poster une version simplifier de ton code pour avoir plus d'éléments (pas 42 fichiers car je n'aurais pas le courage de les lire )

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2010
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 104
    Points : 102
    Points
    102
    Par défaut
    Voilà ma classe bombe (appelée avec un évènement clavier).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #include "StdAfx.h"
     
    class Bombe
    {
    	private:
    		int etendu;
    		SDL_Surface *bombe;
    		SDL_Rect positionBombe;
    		int startTime;
     
    	public:
    		//constructeur de la classe Bombe, création surface.
    		Bombe(SDL_Surface*);	
    	protected: 
    		void explose(SDL_Surface*, SDL_Surface*);
    };
     
    //constructeur de Fenetre (meme nom que la classe)
    Bombe::Bombe(SDL_Surface* ecran) {
     
    	if(isset(startTime) != 1) { startTime = time(0); } // Là ça colle pas !!!
     
    	//chargement de la bombe
    	bombe = IMG_Load("image/bombe.png");
    		//positionnement de la bombe à l'endroit du joueur
    		positionBombe.x = 150; //sera egal à getPosJoueur() lorsque la classe Joueur sera codée;
    		positionBombe.y = 150;
     
    	SDL_BlitSurface(bombe, NULL, ecran, &positionBombe); //collage
    	SDL_Flip(ecran);
     
    	//délai de 3 secondes
    	if (startTime != time(0))
    	{
    		explose(bombe, ecran);
    	}
    }
     
    void Bombe::explose(SDL_Surface* bomb, SDL_Surface *ecran) {
     
    	SDL_Surface* explosion = NULL;
    	SDL_FillRect(bomb, NULL, SDL_MapRGB(bomb->format,195,195,195));
     
    	explosion = IMG_Load("image/explosion.png");
     
    	//ensemble de "for" permettant de dessiner les explosions (les collisions ne sont pas encore gérées) (étendu des déga de la bombe)
    	SDL_Rect posEXP;
    	for (int i=0; i<3; i++)
    	{
    			posEXP.x = positionBombe.x + i*TAILLE_BLOC;
    			posEXP.y = positionBombe.y;
    		SDL_BlitSurface(explosion, NULL, ecran, &posEXP);
    	}
     
    	for (int j=0; j<3; j++)
    	{
    			posEXP.x = positionBombe.x;
    			posEXP.y = positionBombe.y + j*TAILLE_BLOC;
    		SDL_BlitSurface(explosion, NULL, ecran, &posEXP);
    	}
     
    	for (int i=0; i>-3; i--)
    	{
    			posEXP.x = positionBombe.x + i*TAILLE_BLOC;
    			posEXP.y = positionBombe.y;
    		SDL_BlitSurface(explosion, NULL, ecran, &posEXP);
    	}
     
    	for (int j=0; j>-3; j--)
    	{
    			posEXP.x = positionBombe.x;
    			posEXP.y = positionBombe.y + j*TAILLE_BLOC;
    		SDL_BlitSurface(explosion, NULL, ecran, &posEXP);
    	}
     
    	SDL_Flip(ecran);
     
    }
    Ensuite je réalise que je ne comprend pas vraiment le terme (que j'utilisais en plus), de "ma boucle de jeu". Il s'agit de cette boucle ?
    ---->
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    	while(continuer)
    	{
    	SDL_WaitEvent(&even);	//On attend et on récupère l'evement.
    		switch(even.type)	//Type d'evenement.
    		{
    		    case SDL_QUIT:			//croix rouge.
    		        continuer = 0;
    			case SDL_KEYDOWN:		//Appui d'une touche
    				switch (even.key.keysym.sym) //variable où est stoqué la touche appuyée
    				{
    					case SDLK_ESCAPE: 
    						continuer = 0;
    						break;
    					case SDLK_RETURN:
    						jouer(ecran);
    						break;
    				}
    			break;
    		}
    		//effacage de l'écran
                    //collage
                    //mise à jour de l'affichage
    	}
    Je n'ai pas encore codé les évènements claviers. Je me pose d'ailleurs la question, devrai-je les coder dans cette boucle ( haut,bas,gauche,droite pour déplacer un joueur par ex) ou recréer une boucle "quelques part" avec un SDL_WaitEvent dedant?

    Merci 3DArchi de prendre un peu de tps pour m'aider.
    Si tu as besoin de plus d'info...

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Doudoupe Voir le message
    Ensuite je réalise que je ne comprend pas vraiment le terme (que j'utilisais en plus), de "ma boucle de jeu". Il s'agit de cette boucle ?
    Je ne sais pas si les jeux se font encore sur ce schéma là, mais effectivement, c'est à ce genre de boucle que je pensais. Boucle qui ressemble grosso modo à ce que tu présentes :
    while(1) :
    -> lire entrees
    -> traiter entrees
    -> construire affichage
    -> afficher

    Citation Envoyé par Doudoupe Voir le message
    Je n'ai pas encore codé les évènements claviers. Je me pose d'ailleurs la question, devrai-je les coder dans cette boucle ( haut,bas,gauche,droite pour déplacer un joueur par ex) ou recréer une boucle "quelques part" avec un SDL_WaitEvent dedant?
    Ce qui est sur c'est que tu devrais au - avoir un objet dédié pour ne pas avoir des choux et des carottes dans ta 'boucle de jeu'. Ceci dit, le principe de la boucle est de faire plutôt du polling que de l'évènementiel. C'est à dire qu'au lieu d'attendre la réception d'un message, à chaque déroulement de ta boucle du lis l'état des touches et tu réagis en fonction de cet état. Mais je ne connais pas la SDL et peut être permet-elle plus facilement une approche fonctionnelle. Je t'invite à regarder du côté de la rubrique jeux (qui a un forum SDL) pour avoir plus d'info sur ces aspes


    Citation Envoyé par Doudoupe Voir le message
    Voilà ma classe bombe (appelée avec un évènement clavier).
    Le constructeur d'un objet n'est appelé qu'au moment où l'objet est défini. Il doit retourner un objet valide et prêt à être utilisé. Je pense que ton constructeur en fait trop : il initialise l'objet, il le dessine et il veut gérer le timer. Il devrait s'arrêter à l'initialisation de l'objet. Le rendu et la gestion du timer devrait être orchestrés par le moteur de jeu ci-dessus.

  9. #9
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2010
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 104
    Points : 102
    Points
    102
    Par défaut
    Salut!
    Bon depuis la dernière fois, j'ai remis à neuf mon code de manière structuré, donc j'ai pu résoudre pas mal de problème, et éclaircir des points que je ne comprenais pas trop.

    Bien entendu, j'ai encore quelques soucis. Et ça revient un peu au sujet initial.
    Je vous expose donc la structure de ma boucle de jeu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    [...]
           //Boucle de jeu:
    	continuer = true;
    		bool exist_1 = false; //on l'utilise plus tard, lorsqu'on pose une bombe
    		bool exist_2 = false;
    	while (continuer)
        {
    		SDL_FillRect(surfacePrincipale, NULL, SDL_MapRGB(surfacePrincipale->format, 0, 0, 0)); //efface ecran precedent
    		SDL_BlitSurface(fond, NULL, surfacePrincipale, &posPlateau); //image de fond
    		plateau(); //Blit le plateau (caisses) à partir d'un tableau
     
            SDL_PollEvent(&even);
            switch(even.type)
            {
                case SDL_QUIT:
                    continuer = 0;
                    break;
                case SDL_KEYDOWN:
                    switch(even.key.keysym.sym)
                    {
                          //[...]
                          //Je saute les cas où les joueurs se déplacent
    	              case SDLK_SPACE:
    		         if(joueur1.getNbbombe() > 0) // il reste de bombe au Joueur?
    		         {
                                // exist_1 renvoit donc si une bombe est initialisée ou pas
    			    exist_1 = true; 
    			    //On instancie une bombe nommé bombe1
                                Bombe bombe1(joueur1.getPosition(), joueur1.getPortee());
    			    //On va enlever une bombe au joueur
                                joueur1.setNbbombe(-1);
    			  }
                              break;
                            //[...]
                    }
                    break;
            }
    		/*ici c'est mon problème, car bombe1 n'est initialisé 
                       que dans le cas où l'event est "espace". 
                       Donc plantage à la compilation.
                       la fonction update permettrait de vérifier le statut de la bombe (explosée ou pas)
                       et modifierait egalement existe_1*/
     
    		bombe1.update();
                    // Si la bombe existe je l'affiche
    		if(exist_1) { afficheBombe(bombe1.getPosB()); } 
     
    		afficheJoueur(joueur1.getPosition(), profil1[joueur1.getPA()]); //Blit Joueur1
    		afficheJoueur(joueur2.getPosition(), profil2[joueur2.getPA()]); //Blit Joueur2
    		SDL_Flip(surfacePrincipale);	
    	}
    }
    Le problème est donc dans l'instanciation de bombe1 à l'intérieur d'un case.
    N'étant pas déclaré dans les autres cas d'event, le compilo plante.
    Il faudrait donc que depuis ma boucle de jeu, je puisse accéder à la fonction update (où qu'il soit).
    La fonction update suit ce cheminement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void update()
    {
       //Accède à l'attribut startTime de l'instance bombe1 et le compare
       //au temps actuel (if). Selon le cas, on explose la bombe ou pas.
       //si on explose: exist_1 = false, on affichera l'explosion.
       //sinon on sort sans rien faire
    }
    Où dois-je placer cette méthode?
    Help me please!
    (si points sombres, hésitez pas )

  10. #10
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,

    Visiblement, tu te base sur le fait que ton joueur n'a qu'une quantité "limitée" de bombe...

    Mais pourquoi vouloir faire en sorte qu'il... dispose réellement d'une collection de bombe "pré créées" , il n'en a absolument pas besoin

    Au pire, tout ce qu'il doit garder en mémoire, c'est un moyen de "compter" les bombes qu'il a posées ou celle qu'il a encore en stock, et, lorsque tu veux qu'il en lance une, tu vérifie, simplement, s'il a "atteint son cota" ou non

    S'il a atteint son cota, il ne te fournit pas de bombe, et, s'il ne l'a pas encore atteint, il la crée et te la donne

    Cela donnerait quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Bomb;
    class Joueur
    {
        public:
            /* au début de la partie, il a droit à 40 bombes */
            Joueur(std::string const & name):name_(name),bombs_(40){}
            Bomb* launchBomb();
            int countBombs() const{return bombs_;}
        private:
            /* tout ce qu'il faut, c'est un compteur de bombes */
            int bombs_;
    };
    la fonction launchBomb() prendrait alors une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Bomb * Joueur::launchBomb()
    {
        /* si le compteur est à 0, on ne crée plus de bombe :-P */
        if(bombs_==0)
            return NULL;
        /* autrement, on décrémente le compteur,
         * on crée la bombe et on la renvoie à la fonction appelante 
         */
        bombs_--;
        return new Bomb();   
    }
    Dans la fonction principale, tu peux donc te contenter d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    case SDL_KEYDOWN:
    switch(even.key.keysym.sym)
    {
        case SDLK_SPACE:
            Bomb * b=joueur.launchBomb();
            if( b) // si on a eu une bombe, elle est prête à l'emploi, et son
                   // compte a rebours vient de commencer
            {
                /* on peut donc l'inclure dans la file des bombes que le système
                 * doit gérer
                 */
                bombQueue.push_back(b);
            }
            break;
        /*...*/
    }

  11. #11
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2010
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 104
    Points : 102
    Points
    102
    Par défaut
    Bah en fait pour ma "collection de bombe", c'est pour accéder à soit la bombe 1 soit la bombe 2, pour appeler notamment la fonction update(). Mais j'ai tout de même un compteur de bombe qui vérifie sur le même schéma que toi (launchBomb) si je peux ou pas poser une bombe. Ce n'est pas une bonne solution?
    Le nombre de bombe est de 1 ou 2, lorsqu'une explose, elle est "redonnée" au joueur.

    En ce qui concerne le fait de renvoyer un objet Bombe avec launchBomb, ça a l'air pas mal. Je fais quelques tests.
    ***
    EDIT : Mais c'est pareil, je ne peux pas accéder à l'objet Bomb à l'extérieur de mon switch pour appeler ma fonction update...
    De plus le prototype Bombe* poserBombe(); a l'air de passer à la compilation, mais Bombe * Joueur::poserBombe() {...} est rejeté par le compilo.
    Un problème d'étoile/pointeur ??
    ***

    Et qu'est ce que BombQueue.pushback()?

    merci pour tes réponses

  12. #12
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Points : 2 273
    Points
    2 273
    Par défaut
    Salut,
    BombQueue c'est ta file de bombes.
    C'est ce qui contient toutes les bombes actives et que tu dois parcourir et mettre à jour à chaque loop.
    De mon côté, je passerais l'elapsed time à la méthode update() de Bomb.

    Sinon ceci :
    explosion = IMG_Load("image/explosion.png");

    est mauvais pour les perfs, tu charges un fichier à la volée de manière récurrente. Il faudrait que stockes ça ailleurs et que tu le blittes en tant voulu.

    [edit] et après relecture, tu fais la même chose dans ton constructeur :

    bombe = IMG_Load("image/bombe.png");

    A chaque fois que tu crées une bombe ou qu'elle explose tu charges un fichier.
    Le mieux serait de passer les surfaces dans ton constructeurs ou gérer ça à l'extérieur de la classe.

  13. #13
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2010
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 104
    Points : 102
    Points
    102
    Par défaut
    @ Djakisback:

    Effectivement c'était le gros problème de mon code. Mais j'ai réorganisé mon code (2-3 posts au dessus). Ma boucle de jeu est dans une classe Affichage qui gère l'affichage. Les IMG_Load sont donc appelés une seule fois avant les boucle de jeu.

    Pour BombQueue, je me suis douté que c'était la file des bombes actives (même s'il n'y en a maximum que 2 dedans). Mais d'où vient elle? et comment la coder ?

  14. #14
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Voici à peu près ce que je te proposerais:

    Un joueur doit (outre le fait de gérer ses points de vies et sa position, ce que je ne présente pas ici) décider s'il peut lancer ou non une bombe.

    Tout ce qu'il doit avoir, c'est le nombre de bombe qu'il peut lancer "en même temps" (en fait, le nombre de bombe à lui qui peuvent apparaitre en même temps sur le plateau de jeu).

    Je l'ai arbitrairement défini à 40... à toi de lui donner la valeur qui t'intéresse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    class Bombe;
    class Joueur
    {
        public:
            Joueur(std::string const & n):name_(n),bombs_(40){}
            Bomb * launchBomb();
            int bombCount() const{return bombs_;}
            std::string const & name() const{return name_;}
            void retrieveBomb(){bombs_++;}
        private:
            std::string name_;
            int bombs_;
    };
    La priorité de la bombe(outre le fait de gérer sa position sur le plateau et de pévenir ce dernier au moment où elle explose, ce que je ne présente pas ici), c'est de gérer le moment de son explosion.

    J'ai arbitrairement défini le délai entre sa création et son explosion à 15... à toi de lui donner la valeur qui t'intéresse

    Si, chaque fois qu'une bombe explose, elle doit permettre au joueur qui l'a lancée d'en lancer une nouvelle, elle devra également prévenir ce dernier qu'elle explose, au moment où cela se produit.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Joueur;
    class Bomb
    {
        public:
            Bomb(Joueur * j):joueur_(j),delay_(15){}
            ~Bomb(){explode();}
            int delay() const{return delay_;}
            void elapsed(int time){delay_-=time;}
        private:
            void explode();
            Joueur * joueur_;
    };
    les fonctions membres qui doivent connaitre une autre classe (quand Joueur doit connaitre Bomb et que Bomb doit connaitre Joueur)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Bomb * Joueur::launchBomb()
    {
        if(bombs_==0)
            return NULL;
        bombs_--;
        return new Bomb(this);
    }
    void Bomb::explode()
    {
        joueur_->retrieveBomb();
    }
    la file d'attente de gestion des bombes.

    Elle s'occupe principalement de deux choses:
    1 -de garder une trace de toutes les bombes qui sont, à un instant T, présentes sur le plateau de jeu
    2 -de donner un "tick" à intervalle régulier à chaque bombe (ce tick permet au bombe de calculer le délais avant l'explosion )

    Comme toutes les bombes ont un délai avant l'explosion identique, la première bombe lancée sera... la première à exploser, et donc, la première à quitter la file
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Bomb;
    class BombQueue
    {
        public:
            /* on permet d'ajouter uen bombe à la file */
            void push_back(Bomb * b)
            {
                bombs_.push_back(b);
            }
            void tick();
        private:
            std::list<Bomb*> bombs_;
    };
    la fonction membre tick a besoin de la définition complète de bombe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    void BombQueue::tick()
    {
        std::list<Bomb*>::iterator it=bombs_.begin()
        while(it!=bombs_.end()
        {
            /* on réduit le délais de toutes les bombes */
            (*it)->elapsed(1);
            /* si c'est la première bombe de la liste, elle peut 
             * peut être exploser
             */
            if(it==bombs_.begin())
            {
                if((*it)->delay()<=0)
                {
                    delete (*it);
                    it=bombs_.erase(it);
                }
            }
            /* autrement, on passe à la suivante */
            else
                ++it;
        }
    }
    Et notre fonction main devient donc quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    int main()
    {
        Game game; // le plateau de jeu
        BombQueue bombQueue; // la file d'attente des bombes
        /*... chargement du plateau, création des joueurs, ... */
        while(/*une condition qui teste s'il reste plus de 2 joueurs*/)
        {
            bombQueue.tick();
            case SDL_KEYDOWN:
            switch(even.key.keysym.sym)
            {
                case SDLK_SPACE:
                    Bomb * b=joueur.launchBomb();
                    if( b) // si on a eu une bombe, elle est prête à l'emploi, et
                           // son compte a rebours vient de commencer
                    {
                        /* on peut donc l'inclure dans la file des bombes que le
                         * système doit gérer
                         */
                        bombQueue.push_back(b);
                    }
                    break;
            /*...*/
    }
    L'idée générale est en effet que, une fois que le joueur a lancé une bombe, il perd totalement le contrôle sur celle-ci, et que c'est à la liste d'attente de prendre le relais pour "la suite des événements"

  15. #15
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Points : 2 273
    Points
    2 273
    Par défaut
    En fait, tu peux utiliser un vecteur : http://www.cplusplus.com/reference/stl/vector/ pour stocker tes bombes :

    Sur la pile :
    std::vector<Bombe> bombes;

    Et pour le parcours ça doit donner ça je pense :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    for(i = 0; i < bombes.size(); i++)	{
    	  if(bombes[i].isDestroyed())	{
      		 bombes.erase(i);
    	  }
    	  else	{
    	  		bombes[i].update(elapsedTime);
     
    	  }
    }
    A la fin de ton explosion, tu mets un attribut destroyed à true pour indiquer que la bombe doit être supprimée. Pour ce qui est de l'update, une autre méthode (qui est plus simple a priori) et de stocker la durée plutôt que le startTime. T'initialises par exemple la durée à 1000 ms dans le constructeur de Bombe et dans update :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    update(int elapsedTime) {
    // mise à jour de la durée
    duration -= elapsedTime;
     
    if(duration <= 0) {
    // la bombe explose
     
    }
     
    }

    (Si tu fais des allocations dynamiques, il faudra que tu supprimes également les pointeurs de ton vector)

    Plus d'infos sur les méthodes des vecteurs :
    http://cpp.developpez.com/faq/cpp/?page=STL#STL_vector

    (Je ne sais pas si koala01 avait une idée précise en tête en utilisant une file. Effectivement une file pourrait être intéressante mais dans le cas où tu ne veux pas détruire/recréer tes objets mais les réutiliser.)

    [edit] Bin comme ça, t'auras 2 versions
    Celle de koala01 sera sans aucun doute mieux codée, en revanche je ne comprends pas pourquoi tu veux passer par une Queue personnalisée.

  16. #16
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Citation Envoyé par Djakisback Voir le message
    En fait, tu peux utiliser un vecteur : http://www.cplusplus.com/reference/stl/vector/ pour stocker tes bombes :

    Sur la pile :
    std::vector<Bombe> bombes;
    La classe vector ne serait pas intéressante dans le cas présent...

    En effet, il faut savoir que la classe vector est en interne strictement identique à un tableau "C style", avec toutes ses restrictions (entre autres lorsqu'il s'agit de modifier le nombre d'éléments qu'il contient, même si cela se fait de manière amortie).

    Comme on sait que l'on peut utiliser un système FIFO (First In First Out: le premier élément entré est le premier élément à sortir) de par le fait que toutes les bombes ont un délais avant explosion identique, il est largement préférable de choisir une collection qui permet l'ajout d'élément après le dernier élément et le retrait du premier élément.

    La std::queue fournit ces comportements, mais on ne peut normalement pas parcourir les éléments de cette collection sans... retirer à chaque fois le premier.

    C'est la raison pour laquelle je propose d'utiliser la std::list, même si on n'en utilise pas forcément toutes les capacités (entre autres, celles d'insérer un élément "n'importe où" ou celle de parcourir la liste "à reculons")
    (Je ne sais pas si koala01 avait une idée précise en tête en utilisant une file. Effectivement une file pourrait être intéressante mais dans le cas où tu ne veux pas détruire/recréer tes objets mais les réutiliser.)
    Le fait est qu'il me semble plus facile de créer une bombe "à la demande" qui sera d'office correctement initialisée et de la détruire quand on en n'a plus besoin que de commencer par... vérifier si on peut réutiliser une bombe pour décider de la remettre dans un état "cohérent" avec son utilisation, tout simplement

    D'autant plus que, à bien y réfléchir, ce n'est jamais la même bombe que l'on utilise, vu qu'elle a été "physiquement" détruite... on ne va pas commencer à chercher ses morceaux hein

  17. #17
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Points : 2 273
    Points
    2 273
    Par défaut
    Merci pour ces informations précieuses
    Effectivement c'est plus optimisé.

  18. #18
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2010
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 104
    Points : 102
    Points
    102
    Par défaut
    @koala

    Merci beaucoup pour les précisions.
    Je n'ai jamais pensé à faire une classe BombQueue qui gerera toutes mes bombes.
    Je vais donc suivre cette piste. Et voir ça plus en détail ce soir.

  19. #19
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2010
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 104
    Points : 102
    Points
    102
    Par défaut
    Bon ça l'air de concorder mais j'ai des erreurs à la compilation :

    error C2360: l'initialisation de 'b' est ignorée par l'étiquette 'case'

    (et cette erreur à chaque "case" qui suit notre case SPACE.)

    Tu as quelques infos koala ?

  20. #20
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Juste une réponse à la question sur l'erreur de compile
    Une case est une adresse de branchement, et non un bloc d'instructions. C'est pourquoi il est interdit de déclarer une variable dans une case.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
      switch (cas)
      {
        case 0:
          int Compt=0;  // incorrect initialisation dans un case
          ...
        break;
      }
     
      int Compt=0;   // initialisation avant le switch
      switch (cas)
      {
        case 0:
          Compt++;
          ...
        break;
      }
     
      switch (cas)
      {
        case 0:
        {  // le case contient un bloc on peut déclarer Compt qui n'est visible     
           // que dans ce bloc
          int Compt=0;
          ...
        }
        break;
      }
    //
    // Dans le cas présent, il suffit d'écrire
                    if( joueur.launchBomb())
    Voila

Discussions similaires

  1. equivalent de la fonction EXPLODE de php
    Par gyouk dans le forum ASP
    Réponses: 1
    Dernier message: 28/11/2005, 10h49
  2. [XSLT]L'équivalent XSL de isset (php)
    Par xilay dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 16/11/2005, 10h03
  3. [C#] recherche equivalent du readfile() de PHP
    Par MaxiMax dans le forum ASP.NET
    Réponses: 5
    Dernier message: 01/07/2005, 16h41
  4. Quel est l'equivalent de Explode de php ?
    Par reg11 dans le forum Langage
    Réponses: 4
    Dernier message: 29/06/2005, 15h50
  5. equivalence du isset() php en asp
    Par jecht dans le forum ASP
    Réponses: 4
    Dernier message: 13/05/2004, 14h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo