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 : 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
 
// 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 : 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
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 !