Précédent   Forum du club des développeurs et IT Pro > Applications > Développement 2D, 3D et Jeux > API graphiques > SFML
SFML Forum d'entraide sur l'API SFML
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 15/04/2012, 16h20   #1
Nizar89
Invité de passage
 
Homme
Étudiant
Inscription : avril 2012
Messages : 4
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2012
Messages : 4
Points : 1
Points : 1
Par défaut Problème d'affichage de Sprite

Bonjour à tous!

Dans le cadre d'un projet étudiant, je dois réaliser un petit JDR. Je n'en suis qu'aux prémisses, mais j'ai déjà un problème .

(Avant de lire la suite, gardez à l'esprit que je suis un débutant, et mon erreur est surement évidente)

J'ai créer une classe Ecran:
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
class Ecran
 
{
    public:
 
           Ecran (Carte& p_carte, int p_longueur, int p_hauteur); // Créer l'écran, en fonction de la carte et de la taille passé en paramètre
           void boucle_evenement();
           void redessiner_case (int p_x, int p_y); //permet de redessiner une case en particulier
    private:
 
            void charger_carte ();
            void definir_ecran (int p_longueur, int p_hauteur);
            void ini_sprites ();
 
            sf::RenderWindow mon_ecran;
            sf::Sprite eau;
            sf::Sprite herbe;
            sf::Sprite lave;
            sf::Sprite pierre;
            sf::Sprite rocher;
            sf::Sprite sable;
            sf::Sprite terre;
            sf::Sprite vide;
 
            sf::Image f_imeau;
            sf::Image f_imherbe;
            sf::Image f_imlave;
            sf::Image f_impierre;
            sf::Image f_imrocher;
            sf::Image f_imterre;
            sf::Image f_imsable;
            sf::Image imvide;
 
 
 
 
            Carte* ma_carte;
 
};
Les images et les sprites mis en private, ça me parait bien moche, mais je n'ai pas trouvé d'autre solution.

Dans le constructeur:
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
Ecran::Ecran(Carte& p_carte, int p_longueur, int p_hauteur)
{
    definir_ecran(p_longueur, p_hauteur);
 
    ini_sprites();
 
    ma_carte = &p_carte;
 
    charger_carte();
 
    while (mon_ecran.IsOpened())
{
    sf::Event Event;
    while (mon_ecran.GetEvent(Event))
    {
        // Fenêtre fermée
        if (Event.Type == sf::Event::Closed)
            mon_ecran.Close();
 
        // Touche 'echap' appuyée
        if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
            mon_ecran.Close();
    }
}
}
Oui, la boucle d'évènement est un gros copié-collé du tuto . Je ne l'ai rajouté que pour tester l'affichage, elle devrait être supprimé quand j'aurais réglé le problème.

J'initialise mes sprites ici:
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
void Ecran::ini_sprites()
{
 
 
 
 
 
    if (!f_imeau.LoadFromFile("data/texture/eau.png"))
   {
    std::cout << "ERREUR LORS DU CHARGEMENT DE LA TEXTURE EAU";
   }
   // Après initialisation de l'image, on charge les sprites en fonction de l'image voulu
   // On répète cette étape pour chaque Sprite.
   eau.SetImage(f_imeau);
   eau.Resize(50.f,50.f);
 
   if (!f_imherbe.LoadFromFile("data/texture/herbe.png"))
   {
    std::cout << "ERREUR LORS DU CHARGEMENT DE LA TEXTURE HERBE";
   }
   herbe.SetImage(f_imherbe);
   herbe.Resize(50.f,50.f);
 
   if (!f_imlave.LoadFromFile("data/texture/lave.png"))
   {
    std::cout << "ERREUR LORS DU CHARGEMENT DE LA TEXTURE LAVE";
   }
   lave.SetImage(f_imlave);
   lave.Resize (50.f,50.f);
 
   if (!f_impierre.LoadFromFile("data/texture/pierre.png"))
   {
    std::cout << "ERREUR LORS DU CHARGEMENT DE LA TEXTURE PIERRE";
   }
   pierre.SetImage(f_impierre);
   pierre.Resize(50.f,50.f);
 
   if (!f_imrocher.LoadFromFile("data/texture/rocher.png"))
   {
    std::cout << "ERREUR LORS DU CHARGEMENT DE LA TEXTURE ROCHER";
   }
   rocher.SetImage(f_imrocher);
   rocher.Resize(50.f,50.f);
 
   if (!f_imterre.LoadFromFile("data/texture/terre.png"))
   {
    std::cout << "ERREUR LORS DU CHARGEMENT DE LA TEXTURE TERRE";
   }
   terre.SetImage(f_imterre);
   terre.Resize(50.f,50.f);
 
   if (!f_imsable.LoadFromFile("data/texture/sable.png"))
   {
    std::cout << "ERREUR LORS DU CHARGEMENT DE LA TEXTURE SABLE";
   }
   sable.SetImage(f_imsable);
   sable.Resize(50.f,50.f);
 
   vide.SetColor(sf::Color(105, 105, 105));
   vide.Resize(50.f,50.f);
 
}
Le "resize" ne devrait pas être nécessaire, mais je voulais vérifier que le problème ne venait pas de là

Pour finir, la fonction qui doit dessiner les Sprites:
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
void Ecran::charger_carte()
{
    int i,j;
 
 
 
 
    for (i=0;i<(*ma_carte).recup_ymax();i++)
    {
        for (j=0;j<(*ma_carte).recup_xmax();j++)
        {
             if ((*ma_carte).recup_case(j,i) == 1)
             {
 
                 herbe.SetPosition (j*50,i*50);
                 mon_ecran.Draw(herbe);
             }
             else if ((*ma_carte).recup_case(j,i) == 2)
             {
                 pierre.SetPosition (j*50,i*50);
                 mon_ecran.Draw(pierre);
             }
             else if ((*ma_carte).recup_case (j,i) == 3)
             {
                 terre.SetPosition (j*50,i*50);
                 mon_ecran.Draw(terre);
             }
             else if ((*ma_carte).recup_case(j,i) == 4)
             {
                 sable.SetPosition (j*50,i*50);
                 mon_ecran.Draw(sable);
             }
             else if ((*ma_carte).recup_case(j,i) == 21)
             {
 
                 eau.SetPosition (j*50,i*50);
                 mon_ecran.Draw(eau);
             }
             else if ((*ma_carte).recup_case(j,i) == 22)
             {
                 lave.SetPosition (j*50,i*50);
                 mon_ecran.Draw(eau);
             }
             else if ((*ma_carte).recup_case(j,i) == 23)
             {
                 rocher.SetPosition(i*50,j*50);
                 mon_ecran.Draw(rocher);
             }
             else
             {
                vide.SetPosition(j*50,i*50);
 
                mon_ecran.Draw(vide);
 
             }
        }
    }
}
J'ai vérifié, il rentre dans l'un des if au moment où il doit le faire.

Mon problème, c'est que je n'ai aucun Warning ni message d'erreur, mais qu'à la place d'une fenêtre dessiné, j'ai un écran blanc.

Des idées?

Merci
Nizar89 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2012, 08h20   #2
LittleWhite
Responsable 2D/3D/Jeux


 
Avatar de LittleWhite
 
Homme Alexandre Laurent
Ingénieur développement logiciels
Inscription : mai 2008
Messages : 10 777
Détails du profil
Informations personnelles :
Nom : Homme Alexandre Laurent
Localisation : France

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

Informations forums :
Inscription : mai 2008
Messages : 10 777
Points : 43 046
Points : 43 046
Bonjour,

L'erreur que je vois, c'est avoir mis la boucle événementielle dans le constructeur de Ecran. En effet, cela voudrait dire que vous bloquez l'initialisation de votre jeu à la construction de la classe Ecran. Une boucle événementielle, c'est un peu comme une boucle infinie.
En théorie, il faut mettre cette boucle, dans le main, après la construction / initialisation des éléments. Plus précisément, il faut faire une boucle de jeu, dans laquelle on affiche les élements, on met à jour les éléments et on vérifie les entrées (événements).
__________________
Vous souhaitez participer à la rubrique 2D / 3D / Jeux ? Contactez-moi
La rubrique a aussi un blog !

Ma page sur DVP
Mon Portfolio

Qui connaît l'erreur, connaît la solution.
LittleWhite est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2012, 13h52   #3
Nizar89
Invité de passage
 
Homme
Étudiant
Inscription : avril 2012
Messages : 4
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2012
Messages : 4
Points : 1
Points : 1
Merci pour la réponse .

Citation:
L'erreur que je vois, c'est avoir mis la boucle événementielle dans le constructeur de Ecran. En effet, cela voudrait dire que vous bloquez l'initialisation de votre jeu à la construction de la classe Ecran. Une boucle événementielle, c'est un peu comme une boucle infinie.
Je sais bien, et j'ai d'ailleurs mis la boucle d'évènement juste pour tester. Mais, en théorie, ça devrait quand même marcher, non? J'initialise tout avant l'appel à la boucle, ici:

Code :
1
2
3
4
5
6
7
definir_ecran(p_longueur, p_hauteur);
 
    ini_sprites();
 
    ma_carte = &p_carte;
 
    charger_carte();
Je n'ai pas accès à mon pc maintenant, je changerais le code ce soir.
Nizar89 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2012, 14h55   #4
Kaamui
Membre expérimenté
 
Homme Clément
ingénieur d'étude et de développement
Inscription : novembre 2011
Messages : 432
Détails du profil
Informations personnelles :
Nom : Homme Clément
Localisation : France, Vienne (Poitou Charente)

Informations professionnelles :
Activité : ingénieur d'étude et de développement
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2011
Messages : 432
Points : 585
Points : 585
Bonjour,

tes images sont détruites avant que tu les affiches. Alors à la place il t'affiche un carré blanc.

Si tu manipule des pointeurs à la place, tu n'auras plus le problème.

Et pour la boucle d'évènement dans le constructeur écran, non ça ne peut pas marcher. Tu veux manipuler et dessiner dans une fenêtre que tu n'a pas fini de créer !
Kaamui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2012, 19h05   #5
Nizar89
Invité de passage
 
Homme
Étudiant
Inscription : avril 2012
Messages : 4
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2012
Messages : 4
Points : 1
Points : 1
Citation:
Envoyé par Kaamui Voir le message
Bonjour,

tes images sont détruites avant que tu les affiches. Alors à la place il t'affiche un carré blanc.

Si tu manipule des pointeurs à la place, tu n'auras plus le problème.
C'est visiblement le cas, mais j'avoue ne pas comprendre pourquoi: j'ai volontairement déclaré les images et les sprites comme faisant partit de l'objet (ce ne sont pas des variables locales) pour qu'ils ne soient pas détruit à chaque sortit de fonction.
Ya quelque chose dans la POO qui doit m'échapper complètement :/



Citation:
Et pour la boucle d'évènement dans le constructeur écran, non ça ne peut pas marcher. Tu veux manipuler et dessiner dans une fenêtre que tu n'a pas fini de créer !
Ah oui vu comme ça .

J'ai enlever la boucle d'évènement du constructeur, mais j'ai toujours le même problème (je suppose donc que ça vient du fait que les images sont détruites).
Mon code ressemble à ça du coup:
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
Ecran::Ecran(Carte& p_carte, int p_longueur, int p_hauteur)
{
    definir_ecran(p_longueur, p_hauteur);
 
    ini_sprites();
 
    ma_carte = &p_carte;
 
 
    charger_carte();
 
 
}
 
void Ecran::boucle_evenement()
{
 
        while (mon_ecran.IsOpened())
{
    sf::Event Event;
    while (mon_ecran.GetEvent(Event))
    {
        // Fenêtre fermée
        if (Event.Type == sf::Event::Closed)
            mon_ecran.Close();
 
        // Touche 'echap' appuyée
        if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
            mon_ecran.Close();
 
    }
}
 
}
Et pour le main:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include "include/Carte.h"
#include "include/AffichageSFML.h"
#include <string.h>
 
using namespace std;
 
int main (void)
{
 
Carte test("cartetest");
test.test_reg();
 
Ecran ScreenTest(test, 800,600);
ScreenTest.boucle_evenement();
return 0;
 
}
EDIT:
Citation:
Plus précisément, il faut faire une boucle de jeu, dans laquelle on affiche les élements, on met à jour les éléments et on vérifie les entrées (événements)
.

Juste pour préciser que c'est prévu, mais que je cherche pour l'instant juste à voir si l'affichage de la carte marche ^^
Merci
Nizar89 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2012, 08h59   #6
Nizar89
Invité de passage
 
Homme
Étudiant
Inscription : avril 2012
Messages : 4
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2012
Messages : 4
Points : 1
Points : 1
Problème résolu!
J'avais oublié le mon_ecran.display

Merci pour le coup de main .
Nizar89 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 19h39.


 
 
 
 
Partenaires

Hébergement Web