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 :

Déplacer ennemis pacman


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4
    Par défaut Déplacer ennemis pacman
    J'ai appris le C il y a pas longtemps et j'avais auparavant des bonnes notions en html et en php, ce qui m'a aidé un peu. J'ai donc décidé de me lancer dans un Pacman. Tout allait bien jusqu'à ce que je veuille déplacer les ennemis. J'ai pondu ce code après d'intenses réflexions en cours de français mais il fait ramer mon programme et je comprends pas pourquoi. Je précise que sans le code ci-après le programme marche à la perfection (mis à part l'ennemi qui ne bouge pas ).
    Précisions :
    - pour l'instant je ne déplace qu'un ennemi chaque chose en son temps
    - Mon code est composé de 2 parties : une désigne au pif un sens de déplacement (HAUT / BAS ou GAUCHE / DROITE) qui regarde où est mon perso et qui déplace l'ennemi si il peut, et une autre qui prends le relais si on a pas pu en trouvant une autre direction.

    Voila mon code :
    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
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    void deplacerEnnemis(int carte[][NB_BLOCS_HAUTEUR], SDL_Rect *posE, SDL_Rect *posJ)
    {
    int nombreAleatoire = 0, directionTrouvee = 0, recommencerBoucle = 1, i = 0;
    srand(time(NULL));     // Gestion de nombres aléatoires
     
    nombreAleatoire = rand()%2;
     
    while(recommencerBoucle = 1)
    {
        i++;
        switch (nombreAleatoire)
        {
            case 0:
                if(posE->y > posJ->y) // Le joueur est plus bas
                {
                    if(carte[posE->x][posE->y - 1] != MUR)
                    {
                        posE->y--;
                        directionTrouvee = 1;
                        recommencerBoucle = 0;
                        break;
                    }
                    else
                    {
                        nombreAleatoire = !nombreAleatoire;
                        break;
                    }
                }
     
     
                if (posE->y < posJ->y) // Le joueur est plus haut
                {
                    if(carte[posE->x][posE->y + 1] != MUR)
                    {
                        posE->y++;
                        directionTrouvee = 1;
                        recommencerBoucle = 0;
                        break;
                    }
                    else
                    {
                        nombreAleatoire = !nombreAleatoire;
                        break;
                    }
                }
     
     
                else
                {
                    nombreAleatoire = !nombreAleatoire;
                    break;
                }
     
     
            case 1:
                if(posE->x > posJ->x) // Le joueur est à gauche
                {
                    if(carte[posE->x - 1][posE->y] != MUR)
                    {
                        posE->x--;
                        directionTrouvee = 1;
                        recommencerBoucle = 0;
                        break;
                    }
                    else
                    {
                        nombreAleatoire = !nombreAleatoire;
                        break;
                    }
                }
     
     
                if (posE->x < posJ->x)// Le joueur est à droite
     
                {
                    if(carte[posE->x + 1][posE->y] != MUR)
                    {
                        posE->x++;
                        directionTrouvee = 1;
                        recommencerBoucle = 0;
                        break;
                    }
                    else
                    {
                        nombreAleatoire = !nombreAleatoire;
                        break;
                    }
                }
     
     
                else
                {
                    nombreAleatoire = !nombreAleatoire;
                    break;
                }
     
        }
    if(i > 1)
    recommencerBoucle = 0;
    }
     
     
     
    if (directionTrouvee = 0)
    {
        while (directionTrouvee = 0)
        {
            nombreAleatoire = rand()%4;
     
            switch (nombreAleatoire)
            {
                case HAUT:
                if (posE->y - 1 < 0) // Si l'ennemi dépasse l'écran, on recommence
                    break;
                if (carte[posE->x][posE->y - 1] == MUR) // S'il y a un mur, on recommence
                    break;
     
                    // Si on arrive là, c'est qu'on peut déplacer l'ennemi !
                    posE->y--;
                    directionTrouvee = 1;
                    break;
     
                case BAS:
                if (posE->y + 1 >= NB_BLOCS_HAUTEUR) // Si l'ennemi dépasse l'écran, on recommence
                    break;
                if (carte[posE->x][posE->y + 1] == MUR) // S'il y a un mur, on recommence
                    break;
     
                    // Si on arrive là, c'est qu'on peut déplacer l'ennemi !
                    posE->y++;
                    directionTrouvee = 1;
                    break;
     
                case GAUCHE:
                if (posE->x - 1 < 0) // Si l'ennemi dépasse l'écran, on recommence
                    break;
                if (carte[posE->x - 1][posE->y] == MUR) // S'il y a un mur, on recommence
                    break;
     
                    // Si on arrive là, c'est qu'on peut déplacer l'ennemi !
                    posE->x--;
                    directionTrouvee = 1;
                    break;
     
                case DROITE:
                if (posE->x + 1 >= NB_BLOCS_LARGEUR) // Si l'ennemi dépasse l'écran, on recommence
                    break;
                if (carte[posE->x + 1][posE->y] == MUR) // S'il y a un mur, on recommence
                    break;
     
                    // Si on arrive là, c'est qu'on peut déplacer l'ennemi !
                    posE->x++;
                    directionTrouvee = 1;
                    break;
            }   // Fin du swich
        }   // Fin du while
    }   // Fin du if
    }

    Je précise que je suis en 2nde donc les trucs de vecteurs et tout euh o_O quoi.
    J'ai cherché une solution à mon pb mais j'ai fini par préferer poster mon code directement comme j'en trouvais pas. Merci de vos réponses

  2. #2
    Membre expérimenté
    Profil pro
    Dev
    Inscrit en
    Décembre 2007
    Messages
    191
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Décembre 2007
    Messages : 191
    Par défaut
    mais il fait ramer mon programme et je comprends pas pourquoi.
    Alors essayons de voir où il rame et on comprendra :

    je suppose que ton programme est une boucle :

    - bouger le perso
    - bouger le (les) ennemis


    et donc depuis que tu as mis ce code ça rame. Donc c'est surement en effet le code que tu as posté. Maintenant qu'est ce qui peut faire "ramer" un programme ?

    (et d'abord comment rame t'il? il est juste 10 fois plus lent ? 100 fois plus ? des fois ça va des fois non ? il finit par s'arreter ? )

    A part une boucle qui fait du "report indeterminé" je ne vois pas quel pourrait etre le problème. Vérifie soigneusement tes boucles, je m'y met aussi pour voir mais je te garantie pas que j'aurais le courage de tout vérifier

    Je précise que je suis en 2nde donc les trucs de vecteurs et tout euh o_O quoi.
    Je pense pas qu'il y ait besoin de vecteurs.

  3. #3
    Membre expérimenté
    Profil pro
    Dev
    Inscrit en
    Décembre 2007
    Messages
    191
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Décembre 2007
    Messages : 191
    Par défaut
    Bon alors c'est pas la première car tu la fais deux fois max:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    while(recommencerBoucle = 1)
    {
       i++;
       ...
     
       if ( i > 1) recommencerBoucle = 0;
    }
    par contre la deuxième pourrait poser problème.

    Tu te bases sur le fait qu'il y a forcément un passage pour un ennemi à gauche, en haut, à droite ou en bas. mais tu choisis toujours au hasard. Il est donc tout a fait possible d'obtenir 50 fois de suite la mauvaise direction. alors on peut etre certain que ça va pas prendre des heures non plus (quoiqu'il y a une probabilité non nulle pour que ...), mais évidemment, par rapport au code tout simple pour déplacer le perso, il y a tout d'un ocup beaucoup d'instructions.

    Je suppose qu'à l'affichage ça "saccade" ?

    Solution : changer le système : si la direction aléatoire est pas bonne, faire :

    direction = (direction + 1) % 4 pour obtenir la direction d'après au lieu de regénerer un nombre aléatoire.

    bien sur ça y perd en "choix aléatoire" et semble peut etre un peu trop prévisible, mais tu le fais deja dans la premiere boucle, de façon maitrisée avec le compteur.

    Mais c'est mieux que de devoir faire des dizaines de fois la boucle pour trouver un chemin.

  4. #4
    Membre chevronné Avatar de corentin59
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 462
    Par défaut
    sinon, pourquoi mettre de l'aléatoire ? Il me semble qu'il est plus simple de comparer la position du joueur et celle de l'ennemi et de faire en sorte que l'ennemi aille vers le joueur. Pour cela, une idée serait de calculer la distance euclidienne entre les deux points J (joueur) de coordonnées (x,y) et E (ennemi), de coordonnées (a,b) :

    d=sqrt((x-a)^2+(y-b)^2)

    Tu calcules les 4 distances possibles après un éventuel déplacement de l'ennemi (gauche, droite, haut et bas par rapport à sa position actuelle) et tu choisis le mouvement qui rapproche le plus l'ennemi du joueur.

    Si deux mouvements sont équivalents, tu peux choisir l'un ou l'autre aléatoirement.
    Si aucun déplacement ne le rapproche, et ben tu le laisses en place

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4
    Par défaut
    Bon alors après des petits tests :
    - Avec les 2 boucles mon programme se lance normalement avec le menu mais lorque j'appuie sur espace (appel de la fonction jeu), il ne me blitte rien, ne veut pas que je déplace la fenetre ni que je quitte le programme... Bref on dirait vraiment un pb de boucle infinie quoi.

    - Avec seulement la première boucle , rien ne l'affiche comme avec les 2 boucles (IDEM si je mets une valeur fixe à nombreAleatoire).

    - Avec seulement la 2eme boucle (direction aléatoire), le programme charge tout mais ne déplace pas mon perso (je pense pas que ça ait qqch à voir).

    J'en conclus donc que c'est la première boucle qui foire. J'ai pas compris ce que tu me propose corentin59 mais je pense que c'est un peu trop dur pour moi (ça fait que depuis 1 semaine que je sais ce que c'est un int lol)

  6. #6
    Membre chevronné Avatar de Pierre Maurette
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 283
    Par défaut
    Citation Envoyé par Pacorabanix Voir le message
    Bon alors c'est pas la première car tu la fais deux fois max:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    while(recommencerBoucle = 1)
    {
       i++;
       ...
     
       if ( i > 1) recommencerBoucle = 0;
    }
    Non ...
    Avec == au lieu de =, peut-être...

  7. #7
    Membre expérimenté
    Profil pro
    Dev
    Inscrit en
    Décembre 2007
    Messages
    191
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Décembre 2007
    Messages : 191
    Par défaut
    Citation Envoyé par Pierre Maurette Voir le message
    Non ...
    Avec == au lieu de =, peut-être...
    Arg oui.

    Merci de l'avoir remarquée

    c'est tellement horrible ces confusions = / ==

    ça devrait résoudre le problème...

  8. #8
    Membre éprouvé Avatar de siegfried64
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    78
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Maroc

    Informations forums :
    Inscription : Novembre 2007
    Messages : 78
    Par défaut
    juste une question , tu utilise SDL_WaitEvent ou SDL_PollEvent ?

  9. #9
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par BJ 13 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void deplacerEnnemis(int carte[][NB_BLOCS_HAUTEUR], SDL_Rect *posE, SDL_Rect *posJ)
    {
    int nombreAleatoire = 0, directionTrouvee = 0, recommencerBoucle = 1, i = 0;
    srand(time(NULL));     // Gestion de nombres aléatoires
     
    nombreAleatoire = rand()%2;
    <...>
    Ton principal problème de codage est que srand() est mal placé.

    http://emmanuel-delahaye.developpez.com/notes.htm#rand

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4
    Par défaut
    J'avais oublié ça merci beaucoup mais mon pb n'est pas résolu malgré ça...

    Sinon pour Pacorabanix ma fonction jeu peut se résumer en 3 grosses parties :
    - En cas d'un évènement on bouge le perso (==> déplacerJoueur)
    - Au bout de 100 ms on déplace l'ennemi (==> déplacerEnnemi)
    - On blitte le tout

    Je mets le 2ème point çi dessous car c'est peut-être ça aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    tempsActuel = SDL_GetTicks();
        if (tempsActuel - tempsPrecedent > 100)
        {
            tempsPrecedent = tempsActuel;
            deplacerEnnemis(carte, &positionEnnemi, &positionJoueur);
        }
        else /* Si ça fait moins de 1 sec depuis le dernier tour de boucle, on endort le programme le temps qu'il faut */
        {
            SDL_Delay(100 - (tempsActuel - tempsPrecedent));
        }

  11. #11
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par BJ 13 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SDL_Delay(100 - (tempsActuel - tempsPrecedent));
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SDL_Delay(100 - tempsActuel + tempsPrecedent);
    => tu vas gagner quelques micro secondes (la gestion d'un calcul avec parenthèses)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Déplacer un Pacman en continu
    Par lenas_tshaleb dans le forum Android
    Réponses: 4
    Dernier message: 01/02/2015, 22h50
  2. déplacer un fichier
    Par bourinator dans le forum C
    Réponses: 9
    Dernier message: 24/09/2003, 20h29
  3. Réponses: 5
    Dernier message: 24/04/2003, 22h08
  4. Déplacer la sélection d'une ligne dans un stringgrid
    Par jer64 dans le forum Composants VCL
    Réponses: 5
    Dernier message: 14/03/2003, 00h57
  5. TChart : déplacer un point
    Par Nicolas dans le forum C++Builder
    Réponses: 3
    Dernier message: 06/11/2002, 18h05

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