Précédent   Forum du club des développeurs et IT Pro > C et C++ > C++
C++ Forum d'entraide technique sur le langage C++. Avant de poster -> F.A.Q C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 07/01/2013, 16h32   #1
magik-boubou666
Invité de passage
 
Homme
Lycéen
Inscription : janvier 2013
Messages : 2
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Lycéen

Informations forums :
Inscription : janvier 2013
Messages : 2
Points : 1
Points : 1
Par défaut Problème d'exécution d'un script Python

Salut à tous !

Alors voici mon problème :

Dans le cadre du développement d'un jeu de rôle en 2 dimensions vue du dessus (style premiers Final Fantasy), j'ai décidé d'ajouter un système permettant de lancer des actions du genre dialogue par le biais de scripts python.

Pour cela, j'ai utilisé Python 2.7 et me suis appuyé sur un tuto trouvé sur un autre site.

C'est là que les choses se sont compliquées. En effet, mes fonctions pour exécuter des commandes python et des fichiers python fonctionnent parfaitement, la fonction de dialogue codée en C++ fonctionne également lorsqu'elle est appelée dans mon code C++ mais, lorsque je passe par le biais de ma fonction de dialogue par le script Python, elle fonctionne une fois parfaitement avant de planter au second appel (j'ai cherché l'endroit du plantage avec le debugger, à coup d'écriture de message dans le fichier stderr mais il semble que le programme sorte de la fonction de dialogue en l'exécutant entièrement et plante sans même rappeler la fonction de dialogue (même sa fonction Py_Object*).

Je vous laisse donc cet aperçu de mon code car, ayant cherché longuement l'erreur, je ne suis pas parvenu à la trouver. (Il est d'ailleurs arrivé une fois que la fonction de dialogue s'exécute une deuxième fois avant de planter)


Le code complet des fonctions exécutant les scripts python :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
// Execute une commande
void exec(char *cmd)
{
    PyRun_SimpleString(cmd);
}
 
// appelle un fichier de script
bool call(char *fileName) // Type bool pour s'assurer de l'execution du script
{	    
    PyObject *fichier=PyFile_FromString(fileName,"r");
    if(fichier==NULL)
        return false;
    PyRun_SimpleFile(PyFile_AsFile(fichier),fileName);
    Py_DECREF(fichier);
    return true;
}

Le code complet de la fonction dialogue :

Code :
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
 
// fonction de dialogue c++
void dialog(SDL_Surface *perso, string txt, int feeling)
{
 
    SDL_Color couleur = {255, 255, 255};
    TTF_Font *police = TTF_OpenFont("Font\\vgafix.ttf", 12);
    SDL_Surface *text = NULL;
    SDL_Surface *text2 = NULL;
    SDL_Surface *interface = IMG_Load("Game\\Interface\\interface_dialog.bmp");
    SDL_Surface *cloneEcran = SDL_CreateRGBSurface (SDL_HWSURFACE, LARGEUR_FENETRE, HAUTEUR_FENETRE, RESOLUTION, 0, 0, 0, 0);
    bool continuer = true;
    int i = 0;
    string txt2, txt3;
    bool pass = false, nextLine = false;
 
    position.x = 0;
    position.y = 0;
    SDL_BlitSurface(ecran, NULL, cloneEcran, &position);
 
    SDL_SetAlpha(interface, SDL_SRCALPHA, 192);
 
    for (i = 0 ; txt[i] != '\0' && pass == false ; i++)
    {
        SDL_PollEvent(&event);
 
        switch (event.type)
        {
                case SDL_QUIT:
                    exit(EXIT_SUCCESS);
                    break;
 
                case SDL_KEYDOWN:
                    switch (event.key.keysym.sym)
                    {
                        case SDLK_RETURN:
                            pass = true;
                            for (i = i ; txt[i] != '\0' ; i++)
                            {
                                if (nextLine == false && txt[i] == '#')
                                {
                                    nextLine = true;
                                    i++;
                                }
 
                                if (i < 125 && nextLine == false)
                                {
                                    txt2 += txt[i];
                                }
 
                                else
                                {
                                    txt3 += txt[i];
                                }
                            }
                            break;
 
                        case SDLK_SYSREQ :
                            SDL_WM_IconifyWindow();
                            break;
                    }
                    break;
        }
 
        if (nextLine == false && txt[i] == '#')
        {
            nextLine = true;
            i++;
        }
 
        if (txt [i] != '\0')
        {
            if (i < 125 && nextLine == false)
            {
                txt2 += txt[i];
            }
 
            else
            {
                txt3 += txt[i];
            }
 
            text = TTF_RenderUTF8_Blended(police, txt2.c_str(), couleur);
 
            if (i >= 125 || nextLine == true)
            {
                text2 = TTF_RenderUTF8_Blended(police, txt3.c_str(), couleur);
            }
 
            freeScreen();
 
            position.x = 0;
            position.y = 0;
            SDL_BlitSurface(cloneEcran, NULL, ecran, &position);
 
            position.x = 0;
            position.y = 0;
            SDL_BlitSurface(interface, NULL, ecran, &position);
 
            if (perso != NULL)
            {
                position.x = 20;
                position.y = (interface->h - perso->h) / 2;
                SDL_BlitSurface(perso, NULL, ecran, &position);
            }
 
            position.x = 150;
            position.y = (interface->h / 2 - text->h) / 2;
            SDL_BlitSurface(text, NULL, ecran, &position);
 
            if (i >= 125 || nextLine == true)
            {
                position.x = 150;
                position.y = interface->h / 2 + text2->h ;
                SDL_BlitSurface(text2, NULL, ecran, &position);
            }
 
            SDL_Flip(ecran);
 
            SDL_FreeSurface(text);
 
            if (i >= 125  || nextLine == true)
            {
                SDL_FreeSurface(text2);
            }
        }
    }
 
    text = TTF_RenderUTF8_Blended(police, txt2.c_str(), couleur);
 
    if (i >= 125 || nextLine == true)
    {
        text2 = TTF_RenderUTF8_Blended(police, txt3.c_str(), couleur);
    }
 
    while (continuer)
    {
 
        while(SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                    case SDL_QUIT:
                        exit(EXIT_SUCCESS);
                        break;
 
                    case SDL_KEYDOWN:
                        switch (event.key.keysym.sym)
                        {
                            case SDLK_RETURN:
                                continuer = false;
                                break;
 
                            case SDLK_SYSREQ :
                                SDL_WM_IconifyWindow();
                                break;
                        }
                        break;
            }
        }
 
                freeScreen();
 
                position.x = 0;
                position.y = 0;
                SDL_BlitSurface(cloneEcran, NULL, ecran, &position);
 
                position.x = 0;
                position.y = 0;
                SDL_BlitSurface(interface, NULL, ecran, &position);
 
                if (perso != NULL)
                {
                    position.x = 20;
                    position.y = (interface->h - perso->h) / 2;
                    SDL_BlitSurface(perso, NULL, ecran, &position);
                }
 
                position.x = 150;
                position.y = (interface->h / 2 - text->h) / 2;
                SDL_BlitSurface(text, NULL, ecran, &position);
 
                if (i >= 125 || nextLine == true)
                {
                    position.x = 150;
                    position.y = interface->h / 2 + text2->h ;
                    SDL_BlitSurface(text2, NULL, ecran, &position);
                }
 
                SDL_Flip(ecran);
    }
 
    TTF_CloseFont(police);
 
    SDL_FreeSurface(text);
 
    if (i >= 125 || nextLine == true)
    {
        SDL_FreeSurface(text2);
    }
 
    SDL_FreeSurface(interface);
 
    SDL_FreeSurface(cloneEcran);
}
 
// fonction appelant la fonction dialogue par le biais de Python
PyObject *Py_dialog(PyObject *self,PyObject *args)
{
    string str, str2;
    int feeling;
    SDL_Surface *img = NULL;
 
    PyArg_ParseTuple(args,"ssi",&str, &str2, &feeling);
 
    if (str != "NULL")
    {
        str = "Game\\Face\\" + str + " face.bmp";
        img = IMG_Load(str.c_str());
    }
 
    dialog(img, str2, feeling);
 
    if (img != NULL)
    {
        SDL_FreeSurface(img);
    }
 
    return Py_BuildValue("i", 1);
}

Et pour finir le script python en question :

Code :
1
2
3
4
5
6
7
8
 
#- coding: cp1252 -*-
from script import *
 
dialog ("ash", "Un texte pour faire parler un personnage !", 0)
dialog ("ash", "Un autre texte de test (qui n'a été affiché qu'une seule fois ?", 0)
dialog ("ash", "Encore du texte pour faire parler un personnage .", 0)
dialog ("ash", "Toujours du texte pour faire parler un personnage . . .", 0)
Voila, en espérant que vous pourrez m'aider !
magik-boubou666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/03/2013, 14h01   #2
magik-boubou666
Invité de passage
 
Homme
Lycéen
Inscription : janvier 2013
Messages : 2
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Lycéen

Informations forums :
Inscription : janvier 2013
Messages : 2
Points : 1
Points : 1
Bon je sais que ce sujet commence un peu à dater mais je tiens à ajouter quelques précisions avant de clore les sujet définitivement

Tout d'abord, pour dire que je n'ai pas trouvé la réponse au problème mais une alternative qui tient bien la route d'après ce que j'ai déjà testé (incorporation d'un interpréteur codé directement par moi en C++ dans le projet en question).

Ensuite, pour dire que j'ai mis l'interpréteur que j'ai codé en ligne au cas où certaines personnes rencontrent le même genre de problème et qu'elles ne veulent pas se prendre la tête pendant plusieurs heures à retourner le problème dans tous les sens comme je l'ai fait !

Sur ce, voila l'adresse : http://pom-and-dragon.zxq.net/DLK_Script_Engine.php.
Il s'agit seulement d'un squelette à compléter (pour l'instant du moins mais le principe restera le même) donc ne vous étonnez pas si le programme na fait rien quand vous l'utilisez. Récupérez le code source sans le main.cpp et incluez-le dans votre projet. Le reste devrait suivre
magik-boubou666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/03/2013, 10h15   #3
leternel
Expert Confirmé
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 361
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : juin 2007
Messages : 1 361
Points : 2 877
Points : 2 877
Merci d'être revenu pour nous en faire profiter!
__________________
Mes principes de bases du codeur qui veut pouvoir dormir:
  • Une variable de moins est une source d'erreur en moins.
  • Un pointeur de moins est une montagne d'erreurs en moins.
  • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
  • La plus sotte des questions est celle qu'on ne pose pas.
Pour faire des graphes, essayez yEd.
leternel est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 17h45.


 
 
 
 
Partenaires

Hébergement Web