Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 9 sur 9

Discussion: Problème de vue

  1. #1
    Invité de passage
    Homme Profil pro
    Inscrit en
    novembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : novembre 2012
    Messages : 11
    Points : 0
    Points
    0

    Par défaut Problème de vue

    Bonjour,

    Pour me faire la main, j'essaie (comme beaucoup, je pense) de faire un petit jeu basé sur un niveau de S Mario Bros. J'ai fait une map en tile mapping, et rajouter un sprite de Mario. Avant de passer à l'étape de l'animation, j'aimerai que la vue soit centré sur Mario (qu'elle le suive quand il se déplace). Ca fait plusieurs heures que j'essaie des trucs différents, mais rien à faire, Mario se déplace tout seul. Je pense qu'il y a un problème dans la récupération de la position de mario, ou de sa transmission à la vue. Je précise que j'utilise la SFML; j'ai volontairement mis ce sujet dans le forum C++ général, car je suis débutant en général, et mon problème ne se situe pas forcément dans l'utilisation de la SFML.

    Quoi qu'il en soit, voici mon code :

    Mario.cpp

    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
    #include <iostream>
    #include "Mario.hpp"
     
    using namespace std;
    using namespace sf;
     
    Mario::Mario(float x, float y, int vitesse) : _X(x), _Y(y), m_vitesse(vitesse)
    {
         if (!imgMario.LoadFromFile("mariobros.png"))
        {
            cerr << "Erreur pendant le chargement de mariobros.png"<< endl;
        }
        else
        {
            imgMario.CreateMaskFromColor(Color::White);
            mario.SetImage(imgMario);
            mario.SetSubRect(IntRect(0, 0, 43, 86));
            mario.SetPosition(_X, _Y);
            mario.SetCenter(43, 86);
        }
    }
     
    float Mario::GetX() const
    {
        return _X;
    }
     
    float Mario::GetY() const
    {
        return _Y;
    }
     
    void Mario::Deplacement(Direction direction)
    {
        if (direction == DROITE)
        {
            mario.Move(m_vitesse, 0);
        }
        if (direction == GAUCHE)
        {
            mario.Move(-m_vitesse, 0);
        }
    }
     
    Sprite Mario::GetSprite()
    {
        return mario;
    }

    Mario.hpp

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #ifndef MARIO_HPP_INCLUDED
    #define MARIO_HPP_INCLUDED
    #include <SFML/Graphics.hpp>
     
    class Mario
    {
        public :
            Mario(float x, float y, int vitesse);
            enum Direction {DROITE, GAUCHE};
     
            void Deplacement(Direction direction);
            sf::Sprite GetSprite();
            float GetX() const;
            float GetY() const;
     
     
        private :
            float _X, _Y;
            float m_vitesse;
            sf::Image imgMario;
            sf::Sprite mario;
     
    };

    main.cpp

    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
    #include <iostream>
    #include <SFML/Graphics.hpp>
    #include "Mario.hpp"
    #include <cstdlib>
     
    #define LARGEUR_TILE 60
    #define HAUTEUR_TILE 60
     
    #define NOMBRE_TILES_HAUTEUR 14
    #define NOMBRE_TILES_LARGEUR 25
     
    using namespace std;
    using namespace sf;
     
    const Vector2f WINDOW_SIZE(800, 600);
     
     
    char* table [] ={
    "00000000000000000000000000",
    "00000000000000000000000000",
    "00000000000000000000000000",
    "00000000000000000000000000",
    "10000000011111000000000000",
    "00000000000000000000000000",
    "00000000000000000000000000",
    "00000000000000000000000000",
    "00000002222002222000000000",
    "00340000000000000000000000",
    "00560000000000000000077777",
    "00560000000000000000777777",
    "77777777777777777007777777",
    "77777777777777777007777777"};
     
     
    void afficher(RenderWindow &App, Image &tileset, char** table)
    {
     
        App.Clear();
        Sprite tileSource;
        tileSource.SetImage(tileset);
     
        for (int i = 0; i < NOMBRE_TILES_LARGEUR; i++)
        {
            for (int j = 0; j < NOMBRE_TILES_HAUTEUR; j++)
            {
                tileSource.SetSubRect(IntRect((table[j][i] - '0') * LARGEUR_TILE, 0, (table[j][i] - '0')*LARGEUR_TILE+LARGEUR_TILE, HAUTEUR_TILE));
     
                tileSource.SetPosition(i * LARGEUR_TILE, j * HAUTEUR_TILE);
     
                App.Draw(tileSource);
            }
     
        }
    }
     
    int main(int argc, char *argv[])
    {
     
     
     
        RenderWindow App(VideoMode(WINDOW_SIZE.x,WINDOW_SIZE.y, 32), "TileMapping");
        App.SetFramerateLimit(60);
        Image tileset;
     
        if (!tileset.LoadFromFile("tilesetMario.bmp"))
        {
            cerr <<"Erreur lors du chargement de tilesetMario.bmp" << endl;
        }
     
        Mario supMario (200, 640, 9) ;
     
        Vector2f demiTaille(WINDOW_SIZE.x /2, WINDOW_SIZE.y /2);
        Vector2f centre (supMario.GetX(), supMario.GetY());
        View vue (centre, demiTaille);
        App.SetView(vue);
     
        while (App.IsOpened())
        {
     
            Event event;
            while (App.GetEvent(event))
            {
                if((event.Type == Event::KeyPressed && event.Key.Code == Key::Escape)
    					|| event.Type == Event::Closed)
    			{
    				App.Close();
    			}
            }
            vue.SetCenter(supMario.GetX(), supMario.GetY());  // La vue est centrée sur mario, mais ça ne fonctionne pas. Problème de récupération de la position de mario?
            const Input& input = App.GetInput();
     
            if (input.IsKeyDown(Key::Left))
            {
                supMario.Deplacement(Mario::GAUCHE);
     
            }
            if (input.IsKeyDown(Key::Right))
            {
                supMario.Deplacement(Mario::DROITE);
            }
     
     
            App.Clear();
            tileset.SetSmooth(false);
            afficher(App, tileset, table);
            App.Draw(supMario.GetSprite());
            App.Display();
        }
        return EXIT_SUCCESS;
    }

    Je ne me suis pas encore penché sur l'aspect poo (je pense nottement à faire une classe Map), je veux d'abord faire bouger cette vue en même temps que mario.

    Merci d'avance !

  2. #2
    Membre émérite
    Inscrit en
    décembre 2008
    Messages
    533
    Détails du profil
    Informations forums :
    Inscription : décembre 2008
    Messages : 533
    Points : 866
    Points
    866

    Par défaut

    J'ai l'impression que tes attributs _X et _Y font doublon avec les coordonnées déjà intégrées à l'objet sf::Sprite mario. Ces dernières doivent a priori évoluer correctement si SFML fait son boulot, mais _X et _Y ne sont pas mises à jour... Donc la caméra se base sur un couple de coordonnées qui n'évoluent pas.

    GetX() devrait plutôt retourner une référence sur mario.getX(), ou équivalent, idem pour GetY(). _X et _Y sont donc à supprimer.

    Mieux : Mario devrait hériter de sf::Sprite, ce qui semblerait logique en terme de POO : Mario EST un sprite.

  3. #3
    Responsable 2D/3D/Jeux

    Avatar de LittleWhite
    Homme Profil pro Alexandre Laurent
    Ingénieur développement logiciels
    Inscrit en
    mai 2008
    Messages
    16 707
    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 : 16 707
    Points : 86 133
    Points
    86 133

    Par défaut

    Bonjour,

    Citation Envoyé par cob59 Voir le message
    Mieux : Mario devrait hériter de sf::Sprite, ce qui semblerait logique en terme de POO : Mario EST un sprite.
    Techniquement, je verrais plus une agrégation.

    Point de vue POO encore, une classe Map et une classe Camera sont un avantage aussi.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for (int i = 0; i < NOMBRE_TILES_LARGEUR; i++)
        {
            for (int j = 0; j < NOMBRE_TILES_HAUTEUR; j++)
            {
                tileSource.SetSubRect(IntRect((table[j][i] - '0') * LARGEUR_TILE, 0, (table[j][i] - '0')*LARGEUR_TILE+LARGEUR_TILE, HAUTEUR_TILE));
     
                tileSource.SetPosition(i * LARGEUR_TILE, j * HAUTEUR_TILE);
     
                App.Draw(tileSource);
            }
     
        }
    Je pense que c'est ici que je ferai les décalage lié à la camera (décalage des coordonnées).
    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.

  4. #4
    Invité de passage
    Homme Profil pro
    Inscrit en
    novembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : novembre 2012
    Messages : 11
    Points : 0
    Points
    0

    Par défaut

    Dans un premier temps, j'ai réglé le problème en actualisant les coordonnés de _X et _Y de mario dans ma boucle (donc déjà, merci pour votre aide).
    Ensuite, je ne suis pas vraiment au point avec la notion d'héritage (je n'ai pas encore le réflexe, je ne vois pas toujours précisément ce que ça peut m'apporter), et je n'ai carrément aucune idée de ce qu'est l'agrégation. Le but du jeu étant non pas de faire un vrai jeu, mais bien d'apprendre à programmer tout en ayant un minimum de résultat, je vais de ce pas aller me mettre au point dans les cours.
    Faire une classe map et une classe camera, j'y avait déjà pensé, mais chaque chose en son temps, sinon j'ai trop de chose à gérer en même temps : une fois que j'ai vu comment ça marche niveau algos, je peux optimiser tout ça.

    Au niveau de la vue, il y a un autre problème que je n'arrive pas à régler, c'est d'empêcher la vue de "sortir" de l'écran, d'arriver à la bloquer quand elle arrive sur le bord. Je pense qu'il faut un truc du genre "si la vue touche le bord de l'image, elle doit se décentrer de Mario", ou bien "si mario dépasse tel endroit en abcisse, la vue se décentre", mais j'ai un peu de mal à mettre ça en place, surtout que beaucoup de tutos et cours sur la 2d sont avec la SDL en C(ce que je ne connais pas).

    En tous cas, je vous remercie ; en plus de m'aider à résoudre mon problème, vous me donner des pistes plus pédagogiques qui m'aident à mettre le cours en pratique.

    Merci!

  5. #5
    Membre émérite
    Inscrit en
    décembre 2008
    Messages
    533
    Détails du profil
    Informations forums :
    Inscription : décembre 2008
    Messages : 533
    Points : 866
    Points
    866

    Par défaut

    Citation Envoyé par LittleWhite Voir le message
    Techniquement, je verrais plus une agrégation.
    En voyant sa classe, on peut dire que Mario est un type de Sprite, muni en plus d'une vitesse et d'une image propre, donc pourquoi ne pas en hériter ?

    Je ne connais pas SFML, mais je vois que sf::Sprite::~Sprite() n'est pas virtuel, donc je me rends compte qu'il n'est pas prévu qu'on en hérite. Mais je me demande naïvement pourquoi.

  6. #6
    Responsable 2D/3D/Jeux

    Avatar de LittleWhite
    Homme Profil pro Alexandre Laurent
    Ingénieur développement logiciels
    Inscrit en
    mai 2008
    Messages
    16 707
    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 : 16 707
    Points : 86 133
    Points
    86 133

    Par défaut

    Même si c'est pour apprendre autant chercher à tirer sur le langage plutot que se résigner à faire au plus simple (ou au plus C). Donc je dirai, go pour les classes à go go (enfin Map et Camera).

    (Ainsi que d'utiliser le C++11 aussi )

    Maintenant, l'aggrégation, c'est le nom technique, pour juste dire que Mario n'hérite pas de sf::Sprite mais possède une instance de sf::Sprite, comme vous l'avez fait. Pourquoi c'est mieux, car l'héritage bloquerai le changement de l'API de vue (SFML), d'une. De deux, car Mario, c'est un sprite, oui, mais ça pourrait être une animation, ou encore une vidéo, ou je ne sais pas quoi d'autre. L'héritage, dans la théorie de responsabilité unique et autre ne servirai qu'à étendre les fonctionnalité des Sprite au niveau de la vue (par exemple : ZoomableSprite) (et non ajouter des fonctionnalités lié aux Acteurs du jeu).
    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.

  7. #7
    Invité de passage
    Homme Profil pro
    Inscrit en
    novembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : novembre 2012
    Messages : 11
    Points : 0
    Points
    0

    Par défaut

    Je me suis un peu embrouillé avec l'héritage, finalement j'ai laissé comme c'était. Je suis ravi d'apprendre que c'est mieux
    Sinon je suis d'accord pour les classes, je voulais juste vérifier mes algos avant, pour éviter d'y rajouter des "erreurs de POO".

    Par contre, j'ai un autre problème sur un projet de la même ambition. C'est un petit jeu de shoot du genre Space Invaders, toujours avec la SFML. J'ai mis en pratiques quelques petites choses que j'ai apprises, mais je me heurte à un problème plus compliqué (et google ne peut pas grand chose pour moi) : Comment faire pour tirer?
    C'est ennuyeux de ne pas savoir tirer pour faire un jeu de shoot.
    ne sachant pas trop comment m'y prendre, j'ai commencé à implémenter une classe Projectile de la même manière qu'un personnage qui se déplace depuis un point donné, mais ça me paraît un peu limite (et en plus jusqu'à présent ça marche pô ).
    J'ai lu qu'il faudrait faire une classe héritée de sf:: Drawable, mais je n'en sais pas plus (du coup je ne suis pas plus avancé). Ou bien faut il que je me penche sur les animations de sprites ?

    Merci à vous

  8. #8
    Responsable 2D/3D/Jeux

    Avatar de LittleWhite
    Homme Profil pro Alexandre Laurent
    Ingénieur développement logiciels
    Inscrit en
    mai 2008
    Messages
    16 707
    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 : 16 707
    Points : 86 133
    Points
    86 133

    Par défaut

    Une classe Projectile me semble une bonne idée. Après, il faudra peut être aussi une classe World, qui gère la mise à jour des éléments du jeu (méthode update()). Je vous conseille de créer une nouvelle discussion, pour ce problème en particulier (et non surchargé une discussion de plusieurs sujets distincts)
    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.

  9. #9
    Invité de passage
    Homme Profil pro
    Inscrit en
    novembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : novembre 2012
    Messages : 11
    Points : 0
    Points
    0

    Par défaut

    Ok. Merci à vous !

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •