Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème de collisions...

La bête noire des programmeurs !

    8 mars 2008 à 16:17:52

    Bonjour à tous les zéros :) .

    Je suis ici car j'ai un problème de collisions dans un projet que je suis en train de faire... J'ai donc besoin de votre aide pour résoudre mon problème.

    Donc, pour résumer, je travaillais sur un petit projet, mais venu le moment des collisions, un problème est survenu : quand il y a collision, par exemple, à gauche et en haut en même temps, le personnage se fait "téléporter" un peu à côté...
    Je sais plus ou moins d'où viens le problème, mais je suis incapable de le résoudre.

    Voici donc les sources, ainsi qu'un exécutable pour Windows (pour les Linuxiens, je n'ai pas eu le temps de passer sous Ubuntu) :

    main.cpp
    1. #include <iostream>
    2. #include <sstream>
    3. #include <list>
    4. #include <SFML/Graphics.hpp>
    5. #include "ImageManager.h"
    6. #include "Object.h"
    7. #include "Building.h"
    8. #include "Personnage.h"
    9. // Permet de transformer facilement un int en un std::string
    10. std::string IntToString(int i){
    11.     std::ostringstream oss;
    12.     oss << i;
    13.     return oss.str();
    14. }
    15. // Permet de transformer facilement un float en un std::string
    16. std::string FloatToString(float i){
    17.     std::ostringstream oss;
    18.     oss << i;
    19.     return oss.str();
    20. }
    21. int main()
    22. {
    23.     // Create the main window
    24.     sf::RenderWindow App(sf::VideoMode(800, 600, 32), "Evo - by. Schnafon", sf::Style::Close);
    25.     App.SetBackgroundColor(sf::Color(0, 255, 255));
    26.     App.OptimizeForNonOpenGL(true);
    27.     App.SetFramerateLimit(60);
    28.     // Le personnage
    29.     Personnage Per("Schnaf", "Personnage.png", 100, 100, 200.f, 100, 100);
    30.     // Une petite image, juste pour le fun...
    31.     sf::Sprite Img(ImageManager::GetImage("skyblog7.jpg"));
    32.     Img.Move(App.GetWidth()/2-Img.GetWidth()/2, App.GetHeight()/2-Img.GetHeight()/2);
    33.     // Tous les boutons de construction (disparaitra lors de la création le la classe "Button")
    34.     sf::Sprite Maison_btn(ImageManager::GetImage("Maison1_btn.png"));
    35.     Maison_btn.SetPosition(App.GetWidth()/2-(32*2), App.GetHeight()-Maison_btn.GetHeight()-10);
    36.     sf::Sprite Barricade_btn(ImageManager::GetImage("Barricade1_btn.png"));
    37.     Barricade_btn.SetPosition(App.GetWidth()/2-32, App.GetHeight()-Maison_btn.GetHeight()-10);
    38.     sf::Sprite Barricade2_btn(ImageManager::GetImage("Barricade2_btn.png"));
    39.     Barricade2_btn.SetPosition(App.GetWidth()/2, App.GetHeight()-Maison_btn.GetHeight()-10);
    40.     sf::Sprite Barricade3_btn(ImageManager::GetImage("Barricade3_btn.png"));
    41.     Barricade3_btn.SetPosition(App.GetWidth()/2+32, App.GetHeight()-Maison_btn.GetHeight()-10);
    42.     // Les bâtiments
    43.     std::list<Building> B;
    44.     // Ajout de quelques bâtiments de base pour les testes
    45.     B.push_back(Building());
    46.     B.back().Create(0, "Maison1.png", 300, 250, "Maison", 600);
    47.     B.push_back(Building());
    48.     B.back().Create(0, "Barricade1.png", 400, 500, "Barricade", 1200);
    49.     B.push_back(Building());
    50.     B.back().Create(0, "Barricade1.png", 472, 500, "Barricade", 1200);
    51.     int batiment = 0;
    52.     const sf::Input& Input = App.GetInput();
    53.     bool Running = true;
    54.     while (Running)
    55.     {
    56.         // Instance temporaire de la maison à construire
    57.         sf::Image *bi;
    58.         if(batiment == 1)
    59.             bi = &ImageManager::GetImage("Maison1.png");
    60.         if(batiment == 2)
    61.             bi = &ImageManager::GetImage("Barricade1.png");
    62.         if(batiment == 3)
    63.             bi = &ImageManager::GetImage("Barricade2.png");
    64.         if(batiment == 4)
    65.             bi = &ImageManager::GetImage("Barricade3.png");
    66.         float mpX = 0;
    67.         float mpY = 0;
    68.         if(batiment > 0){
    69.             mpX = Input.GetMouseX()-bi->GetWidth()/2;
    70.             mpY = Input.GetMouseY()-bi->GetHeight()/2;
    71.         }
    72.         sf::Event Event;
    73.         while (App.GetEvent(Event))
    74.         {
    75.             if (Event.Type == sf::Event::Closed)
    76.                 Running = false;
    77.             if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
    78.                 Running = false;
    79.             // Si on fait un clique gauche...
    80.             if ((Event.Type == sf::Event::MouseButtonReleased) && (Event.MouseButton.Button == sf::Mouse::Left)){
    81.                 // ...Et qu'on clique dans la zone boutons, on annule le bâtiment sélectionné...
    82.                 if(Input.GetMouseY() > App.GetHeight()-(32+10))
    83.                     batiment = 0;
    84.                 // ...Sinon, si un bâtiment est sélectionné, alors on l'ajoute à la liste
    85.                 if(batiment > 0){
    86.                     B.push_back(Building());
    87.                     if(batiment == 1)
    88.                         B.back().Create(0, "Maison1.png", mpX, mpY, "Maison", 600);
    89.                     if(batiment == 2)
    90.                         B.back().Create(0, "Barricade1.png", mpX, mpY, "Barricade", 1200);
    91.                     if(batiment == 3)
    92.                         B.back().Create(0, "Barricade2.png", mpX, mpY, "Barricade", 1200);
    93.                     if(batiment == 4)
    94.                         B.back().Create(0, "Barricade3.png", mpX, mpY, "Porte Barricadée", 1200, -1, false);
    95.                     batiment = 0;
    96.                 }
    97.                 // ...Sinon, si on clique sur un bouton, on sélectionne le bâtiment correspondant
    98.                 else{
    99.                     if(Input.GetMouseX() > Maison_btn.GetLeft()
    100.                     && Input.GetMouseX() < Maison_btn.GetLeft()+Maison_btn.GetWidth()
    101.                     && Input.GetMouseY() > Maison_btn.GetTop()
    102.                     && Input.GetMouseY() < Maison_btn.GetTop()+Maison_btn.GetHeight())
    103.                         batiment = 1;
    104.                     if(Input.GetMouseX() > Barricade_btn.GetLeft()
    105.                     && Input.GetMouseX() < Barricade_btn.GetLeft()+Barricade_btn.GetWidth()
    106.                     && Input.GetMouseY() > Barricade_btn.GetTop()
    107.                     && Input.GetMouseY() < Barricade_btn.GetTop()+Barricade_btn.GetHeight())
    108.                         batiment = 2;
    109.                     if(Input.GetMouseX() > Barricade2_btn.GetLeft()
    110.                     && Input.GetMouseX() < Barricade2_btn.GetLeft()+Barricade2_btn.GetWidth()
    111.                     && Input.GetMouseY() > Barricade2_btn.GetTop()
    112.                     && Input.GetMouseY() < Barricade2_btn.GetTop()+Barricade2_btn.GetHeight())
    113.                         batiment = 3;
    114.                     if(Input.GetMouseX() > Barricade3_btn.GetLeft()
    115.                     && Input.GetMouseX() < Barricade3_btn.GetLeft()+Barricade3_btn.GetWidth()
    116.                     && Input.GetMouseY() > Barricade3_btn.GetTop()
    117.                     && Input.GetMouseY() < Barricade3_btn.GetTop()+Barricade3_btn.GetHeight())
    118.                         batiment = 4;
    119.                 }
    120.             }
    121.             // Si on fait un clique droit on désélectionne le bâtiment
    122.             if ((Event.Type == sf::Event::MouseButtonReleased) && (Event.MouseButton.Button == sf::Mouse::Right)){
    123.                 batiment = 0;
    124.             }
    125.         }
    126.         // Si on appuis sur une des touches de mouvement, on fait se déplacer le personnage
    127.         if(Input.IsKeyDown(sf::Key::Q)){
    128.             Per.MoveX(false);
    129.         }if(Input.IsKeyDown(sf::Key::D)){
    130.             Per.MoveX(true);
    131.         }if(Input.IsKeyDown(sf::Key::Z)){
    132.             Per.MoveY(false);
    133.         }if(Input.IsKeyDown(sf::Key::S)){
    134.             Per.MoveY(true);
    135.         }
    136.         // On teste la collision avec les bâtiments
    137.         for(std::list<Building>::iterator it = B.begin(); it != B.end(); it++){
    138.             Per.Collision((*it));
    139.         }
    140.         // On applique l'image stupide et inutile :D
    141.         App.Draw(Img);
    142.         // On affiche les bâtiments
    143.         for(std::list<Building>::iterator it = B.begin(); it != B.end(); it++){
    144.             (*it).Draw(App);
    145.             // Si la souris est au-dessus d'un bâtiment, on affiche son proprio ainsi que le nom du bâtiment
    146.             if(Input.GetMouseX() > (*it).GetX()
    147.             && Input.GetMouseX() < (*it).GetX()+(*it).GetW()
    148.             && Input.GetMouseY() > (*it).GetY()
    149.             && Input.GetMouseY() < (*it).GetY()+(*it).GetH()){
    150.                 sf::String str((*it).GetName() + std::string(" de ") + Per.GetName(), "tahoma.ttf", 10.f);
    151.                 str.SetColor(sf::Color(0, 0, 0));
    152.                 sf::FloatRect strRect = str.GetRect();
    153.                 str.SetLeft(((*it).GetX()+(*it).GetW()/2) - (strRect.GetWidth()/2));
    154.                 str.SetTop((*it).GetY() - 20);
    155.                 App.Draw(str);
    156.             }
    157.         }
    158.         // On affiche le personnage
    159.         Per.Draw(App);
    160.         // Si un bâtiment est sélectionné, on l'affiche au curseur de la souris
    161.         if(batiment > 0){
    162.             sf::Sprite bspr;
    163.             bspr.SetPosition(mpX, mpY);
    164.             if(batiment == 1)
    165.                 bspr.SetImage(ImageManager::GetImage("Maison1.png"));
    166.             if(batiment == 2)
    167.                 bspr.SetImage(ImageManager::GetImage("Barricade1.png"));
    168.             if(batiment == 3)
    169.                 bspr.SetImage(ImageManager::GetImage("Barricade2.png"));
    170.             if(batiment == 4)
    171.                 bspr.SetImage(ImageManager::GetImage("Barricade3.png"));
    172.             bspr.SetColor(sf::Color(255, 255, 255, 128));
    173.             App.Draw(bspr);
    174.         }
    175.         // Et enfin, on affiche les boutons
    176.         App.Draw(Maison_btn);
    177.         App.Draw(Barricade_btn);
    178.         App.Draw(Barricade2_btn);
    179.         App.Draw(Barricade3_btn);
    180.         // Display window on screen
    181.         App.Display();
    182.     }
    183.     // Superssion de la mémoire utilisée par l'ImageManager
    184.     ImageManager::Delete();
    185.     // C'est bon, tout s'est bien passé
    186.     return EXIT_SUCCESS;
    187. }


    Object.h
    1. #ifndef DEF_OBJECT
    2. #define DEF_OBJECT
    3. #include <SFML/Graphics.hpp>
    4. /// Object
    5. /// Classe de base pour toutes sortes d'objets du terrain (bâtiments, joueurs, ...)
    6. class Object{
    7. public:
    8.     // Constructeur de base de la classe
    9.     Object(void);
    10.     // Constructeur de la classe
    11.     // Les valeurs correspondent aux variables de la classe
    12.     // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    13.     Object(std::string Name, std::string Image, float X, float Y, int PVmax, int PV = -1, bool Collision = true);
    14.     // Constructeur de copie de la classe
    15.     Object(const Object &o);
    16.     // Constructeur de copie de la classe
    17.     Object & operator=(const Object &o);
    18.     // Post-constructeur de la classe
    19.     // Les valeurs correspondent aux variables de la classe
    20.     // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    21.     void Create(std::string Name, std::string Image, float X, float Y, int PVmax, int PV = -1, bool Collision = true);
    22.     // Accesseur vers "mName"
    23.     std::string GetName(void) const;
    24.     // Accesseur vers "mPVmax"
    25.     int GetPVmax(void) const;
    26.     // Accesseur vers "mPV"
    27.     int GetPV(void) const;
    28.     // Accesseur vers "mX"
    29.     float GetX(void) const;
    30.     // Accesseur vers "mY"
    31.     float GetY(void) const;
    32.     // Accesseur vers la taille en largeur du bâtiment
    33.     float GetW(void) const;
    34.     // Accesseur vers la taille en hauteur du bâtiment
    35.     float GetH(void) const;
    36.     // Accesseur vers mCollision
    37.     bool GetCollision() const;
    38.     // Teste de collision
    39.     bool CheckCollision(float left, float right, float top, float bottom) const;
    40.     // Fonction d'affichage de l'objet
    41.     // Window : Une référence vers la fenêtre
    42.     void Draw(sf::RenderWindow &Window);
    43. protected:
    44.     // Sprite pour l'affichage
    45.     sf::Sprite mImage;
    46.     // Image de la barre indiquant les PV
    47.     sf::Image mPVImage;
    48.     // Position en abcisse (X)
    49.     float mX;
    50.     // Position en ordonnée (Y)
    51.     float mY;
    52.     // Nom
    53.     std::string mName;
    54.     // Points de vie max
    55.     int mPVmax;
    56.     // Points de vie
    57.     int mPV;
    58.     // Indique s'il y a collision avec l'objet
    59.     bool mCollision;
    60. };
    61. #endif


    Object.cpp
    1. #include "Object.h"
    2. #include "ImageManager.h"
    3. // Constructeur de base de la classe
    4. Object::Object(void)
    5. {
    6.     mX = 0;
    7.     mY = 0;
    8.     mName = "";
    9.     mPVmax = 0;
    10.     mPV = 0;
    11.     mCollision = true;
    12. }
    13. // Constructeur de la classe
    14. // Les valeurs correspondent aux variables de la classe
    15. // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    16. Object::Object(std::string Name, std::string Image, float X, float Y, int PVmax, int PV, bool Collision)
    17. {
    18.     Create(Name, Image, X, Y, PVmax, PV, Collision);
    19. }
    20. // Constructeur de copie de la classe
    21. Object::Object(const Object &o)
    22. {
    23.     mX = o.mX;
    24.     mY = o.mY;
    25.     mName = o.mName;
    26.     mPVmax = o.mPVmax;
    27.     mPV = o.mPV;
    28.     mCollision = o.mCollision;
    29.     mImage = o.mImage;
    30.     mPVImage.Create(40, 5, sf::Color(255, 255, 255));
    31. }
    32. // Constructeur de copie de la classe
    33. Object & Object::operator=(const Object &o)
    34. {
    35.     mX = o.mX;
    36.     mY = o.mY;
    37.     mName = o.mName;
    38.     mPVmax = o.mPVmax;
    39.     mPV = o.mPV;
    40.     mCollision = o.mCollision;
    41.     mImage = o.mImage;
    42.     mPVImage.Create(40, 5, sf::Color(255, 255, 255));
    43.     return *this;
    44. }
    45. // Post-constructeur de la classe
    46. // Les valeurs correspondent aux variables de la classe
    47. // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    48. void Object::Create(std::string Name, std::string Image, float X, float Y, int PVmax, int PV, bool Collision)
    49. {
    50.     mX = X;
    51.     mY = Y;
    52.     mName = Name;
    53.     mPVmax = PVmax;
    54.     mPV = (PV < 0 || PV > mPVmax) ? mPVmax : PV;
    55.     mCollision = Collision;
    56.     mImage.SetImage(ImageManager::GetImage(Image));
    57.     mPVImage.Create(40, 5, sf::Color(255, 255, 255));
    58. }
    59. // Accesseur vers "mName"
    60. std::string Object::GetName(void) const
    61. {
    62.     return mName;
    63. }
    64. // Accesseur vers "mPVmax"
    65. int Object::GetPVmax(void) const
    66. {
    67.     return mPVmax;
    68. }
    69. // Accesseur vers "mPV"
    70. int Object::GetPV(void) const
    71. {
    72.     return mPV;
    73. }
    74. // Accesseur vers "mX"
    75. float Object::GetX(void) const
    76. {
    77.     return mX;
    78. }
    79. // Accesseur vers "mY"
    80. float Object::GetY(void) const
    81. {
    82.     return mY;
    83. }
    84. // Accesseur vers la taille en largeur du bâtiment
    85. float Object::GetW(void) const
    86. {
    87.     return mImage.GetWidth();
    88. }
    89. // Accesseur vers la taille en hauteur du bâtiment
    90. float Object::GetH(void) const
    91. {
    92.     return mImage.GetHeight();
    93. }
    94. // Accesseur vers mCollision
    95. bool Object::GetCollision() const
    96. {
    97.     return mCollision;
    98. }
    99. // Teste de collision
    100. bool Object::CheckCollision(float left, float right, float top, float bottom) const
    101. {
    102.     if( bottom <= GetY() )
    103.         return false;
    104.     if( top >= GetY() + GetH() )
    105.         return false;
    106.     if( right <= GetX() )
    107.         return false;
    108.     if( left >= GetX() + GetW() )
    109.         return false;
    110.     return true;
    111. }
    112. // Fonction d'affichage de l'objet
    113. // Window : Une référence vers la fenêtre
    114. void Object::Draw(sf::RenderWindow &Window)
    115. {
    116.     float PV = static_cast<float>(mPV);
    117.     float PVmax = static_cast<float>(mPVmax);
    118.     mImage.SetPosition(mX, mY);
    119.     sf::Sprite spr(mPVImage);
    120.     spr.SetSubRect(sf::IntRect(0, 0, static_cast<int>(PV/PVmax*mPVImage.GetWidth()), mPVImage.GetHeight()));
    121.     spr.SetColor(sf::Color(static_cast<int>(255-PV/PVmax*255), static_cast<int>(PV/PVmax*255), 0));
    122.     spr.SetPosition(mX+mImage.GetWidth()/2-mPVImage.GetWidth()/2, mY-mPVImage.GetHeight());
    123.     Window.Draw(mImage);
    124.     Window.Draw(spr);
    125. }


    Building.h
    1. #ifndef DEF_BUILDING
    2. #define DEF_BUILDING
    3. #include <SFML/Graphics.hpp>
    4. #include "Object.h"
    5. /// Building
    6. /// Gestion simple des bâtiments
    7. class Building : public Object{
    8. public:
    9.     // Constructeur de base de la classe
    10.     Building(void);
    11.     // Constructeur de la classe
    12.     // Les valeurs correspondent aux variables de la classe
    13.     // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    14.     Building(int Owner, std::string Image, float X, float Y, std::string Name, int PVmax, int PV = -1, bool Collision = true);
    15.     // Post-constructeur de la classe
    16.     // Les valeurs correspondent aux variables de la classe
    17.     // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    18.     void Create(int Owner, std::string Image, float X, float Y, std::string Name, int PVmax, int PV = -1, bool Collision = true);
    19.     // Fonction d'affichage du bâtiment
    20.     // Window : Une référence vers la fenêtre
    21.     void Draw(sf::RenderWindow &Window);
    22.     // Fonction de réparation/constructiondu bâtiment
    23.     // PV : Les PV gagnés
    24.     void Build(int PV);
    25.     // Fonction d'attaque bâtiment
    26.     // PV : Les PV perdus
    27.     void Attack(int PV);
    28.     // Accesseur vers "mOwner"
    29.     int GetOwner() const;
    30. protected:
    31.     // Id du personnage ayant contruit le bâtiment
    32.     int mOwner;
    33.     // Indique si le bâtiment est en construction
    34.     bool mInConstruction;
    35. };
    36. #endif


    Building.cpp
    1. #include "Building.h"
    2. // Constructeur de base de la classe
    3. Building::Building(void) :
    4. Object()
    5. {
    6.     mOwner = -1;
    7.     mInConstruction = false;
    8. }
    9. // Constructeur de la classe
    10. // Les valeurs correspondent aux variables de la classe
    11. // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    12. Building::Building(int Owner, std::string Image, float X, float Y, std::string Name, int PVmax, int PV, bool Collision)
    13. {
    14.     Create(Owner, Image, X, Y, Name, PVmax, PV, Collision);
    15. }
    16. // Post-constructeur de la classe
    17. // Les valeurs correspondent aux variables de la classe
    18. // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    19. void Building::Create(int Owner, std::string Image, float X, float Y, std::string Name, int PVmax, int PV, bool Collision)
    20. {
    21.     Object::Create(Name, Image, X, Y, PVmax, PV, Collision);
    22.     mOwner = Owner;
    23.     mInConstruction = (mPV < mPVmax);
    24.     mPVImage.Resize(80, mPVImage.GetHeight(), sf::Color(255, 255, 255));
    25. }
    26. // Fonction d'affichage du bâtiment
    27. // Window : Une référence vers la fenêtre
    28. void Building::Draw(sf::RenderWindow &Window)
    29. {
    30.     float PV = static_cast<float>(mPV);
    31.     float PVmax = static_cast<float>(mPVmax);
    32.     if(mInConstruction){
    33.         int alpha = static_cast<int>(PV/PVmax*128);
    34.         alpha = (alpha <= 128) ? alpha : 128;
    35.         mImage.SetColor(sf::Color(255, 255, 255, 127+alpha));
    36.     }else
    37.         mImage.SetColor(sf::Color(255, 255, 255, 255));
    38.     Object::Draw(Window);
    39. }
    40. // Fonction de réparation/constructiondu bâtiment
    41. // PV : Les PV gagnés
    42. void Building::Build(int PV)
    43. {
    44.     mPV += PV;
    45.     if(mPV > mPVmax)
    46.         mPV = mPVmax;
    47.     if(mPV < 0)
    48.         mPV = 0;
    49.     if(mInConstruction && mPV == mPVmax)
    50.         mInConstruction = false;
    51. }
    52. // Fonction d'attaque bâtiment
    53. // PV : Les PV perdus
    54. void Building::Attack(int PV)
    55. {
    56.     mPV -= PV;
    57.     if(mPV > mPVmax)
    58.         mPV = mPVmax;
    59.     if(mPV < 0)
    60.         mPV = 0;
    61. }
    62. // Accesseur vers "mOwner"
    63. int Building::GetOwner() const
    64. {
    65.     return mOwner;
    66. }


    Personnage.h
    1. #ifndef DEF_PERSONNAGE
    2. #define DEF_PERSONNAGE
    3. #include <SFML/Graphics.hpp>
    4. #include "Object.h"
    5. class Personnage : public Object{
    6. public:
    7.     // Constructeur de base de la classe
    8.     Personnage(void);
    9.     // Constructeur de la classe
    10.     // Les valeurs correspondent aux variables de la classe
    11.     // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    12.     Personnage(std::string Name, std::string Image, float X, float Y, float Speed, int PVmax, int PV = -1);
    13.     // Post-constructeur de la classe
    14.     // Les valeurs correspondent aux variables de la classe
    15.     // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    16.     void Create(std::string Name, std::string Image, float X, float Y, float Speed, int PVmax, int PV = -1);
    17.     // Déplace le personnage sur l'axe X
    18.     // Dir : Si false, déplace à gauche, sinon à droite
    19.     void MoveX(bool Dir);
    20.     // Déplace le personnage sur l'axe Y
    21.     // Dir : Si false, déplace en haut, sinon en bas
    22.     void MoveY(bool Dir);
    23.     // Teste la collision entre le personnage et un Object
    24.     // o : L'objet avec lequel la fonction doit tester la collision
    25.     void Collision(const Object &o);
    26.     // Fonction d'affichage du personnage
    27.     // Window : Une référence vers la fenêtre
    28.     void Draw(sf::RenderWindow &Window);
    29. protected:
    30.     // La vitesse du personnage (pixel par seconde)
    31.     float mSpeed;
    32.     // La vélocitée actuelle en X
    33.     float mVX;
    34.     // La vélocitée actuelle en Y
    35.     float mVY;
    36.     // L'image (de l'animation de mouvement) actuelle
    37.     int mFrame;
    38.     // Un sf::Clock pour l'animation de mouvement
    39.     sf::Clock mClock;
    40. };
    41. #endif


    Personnage.cpp
    1. #include "Personnage.h"
    2. // Constructeur de base de la classe
    3. Personnage::Personnage(void) :
    4. Object(),
    5. mSpeed(0),
    6. mVX(0),
    7. mVY(0),
    8. mFrame(0)
    9. {
    10. }
    11. // Constructeur de la classe
    12. // Les valeurs correspondent aux variables de la classe
    13. // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    14. Personnage::Personnage(std::string Name, std::string Image, float X, float Y, float Speed, int PVmax, int PV)
    15. {
    16.     Create(Name, Image, X, Y, Speed, PVmax, PV);
    17. }
    18. // Post-constructeur de la classe
    19. // Les valeurs correspondent aux variables de la classe
    20. // Note : Si "PV" est négatif (valeur par défaut), mPV sera égal à mPVmax
    21. void Personnage::Create(std::string Name, std::string Image, float X, float Y, float Speed, int PVmax, int PV)
    22. {
    23.     mSpeed = Speed;
    24.     mVX = 0;
    25.     mVY = 0;
    26.     mFrame = 0;
    27.     Object::Create(Name, Image, X, Y, PVmax, PV, true);
    28.     mImage.SetSubRect(sf::IntRect(0, 0, static_cast<int>(mImage.GetWidth()/4), static_cast<int>(mImage.GetHeight()/4)));
    29. }
    30. // Déplace le personnage sur l'axe X
    31. // Dir : Si false, déplace à gauche, sinon à droite
    32. void Personnage::MoveX(bool Dir)
    33. {
    34.     mVX = (Dir) ? mSpeed : -mSpeed;
    35.     int psizex = static_cast<int>(mImage.GetWidth());
    36.     int psizey = static_cast<int>(mImage.GetHeight());
    37.     if(!Dir)
    38.         mImage.SetSubRect(sf::IntRect(psizex*mFrame, psizey*1, psizex*(mFrame+1), psizey*2));
    39.     if(Dir)
    40.         mImage.SetSubRect(sf::IntRect(psizex*mFrame, psizey*2, psizex*(mFrame+1), psizey*3));
    41. }
    42. // Déplace le personnage sur l'axe Y
    43. // Dir : Si false, déplace en haut, sinon en bas
    44. void Personnage::MoveY(bool Dir)
    45. {
    46.     mVY = (Dir) ? mSpeed : -mSpeed;
    47.     int psizex = static_cast<int>(mImage.GetWidth());
    48.     int psizey = static_cast<int>(mImage.GetHeight());
    49.     if(!Dir)
    50.         mImage.SetSubRect(sf::IntRect(psizex*mFrame, psizey*3, psizex*(mFrame+1), psizey*4));
    51.     if(Dir)
    52.         mImage.SetSubRect(sf::IntRect(psizex*mFrame, psizey*0, psizex*(mFrame+1), psizey*1));
    53. }
    54. // Teste la collision entre le personnage et un Object
    55. // o : L'objet avec lequel la fonction doit tester la collision
    56. void Personnage::Collision(const Object &o)
    57. {
    58.     if(mCollision && o.GetCollision()){
    59.         float meL = GetX();
    60.         float meT = GetY();
    61.         float meR = meL + GetW();
    62.         float meB = meT + GetH();
    63.         float oL = o.GetX();
    64.         float oT = o.GetY();
    65.         float oR = oL + o.GetW();
    66.         float oB = oT + o.GetH();
    67.         if(CheckCollision(oL, oR, oT, oB)){
    68.             // collision gauche
    69.             if(meL < oL) {
    70.                 mX = oL - GetW();
    71.             }
    72.             // collision droite
    73.             if(meR > oR) {
    74.                 mX = oR;
    75.             }
    76.         }
    77.         if(CheckCollision(oL, oR, oT, oB)){
    78.             // collision haut
    79.             if(meT < oT) {
    80.                 mY = oT - GetH();
    81.             }
    82.             // collision bas
    83.             if(meB > oB) {
    84.                 mY = oB;
    85.             }
    86.         }
    87.     }
    88. }
    89. // Fonction d'affichage du personnage
    90. // Window : Une référence vers la fenêtre
    91. void Personnage::Draw(sf::RenderWindow &Window)
    92. {
    93.     mX += mVX*Window.GetFrameTime();
    94.     mY += mVY*Window.GetFrameTime();
    95.     if(mClock.GetElapsedTime() > 0.1f){
    96.         mFrame++;
    97.         mClock.Reset();
    98.     }
    99.     mVX = 0.f;
    100.     mVY = 0.f;
    101.     Object::Draw(Window);
    102. }


    Note : Le fichier ImageManager.h n'a rien à voir avec le problème, c'est pour cela que je ne l'ai pas mis.


    D'avance merci ;) .
    • Partager sur Facebook
    • Partager sur Twitter
      9 mars 2008 à 13:56:28

      Peut-tu donner moins de code, celui qui pose problème? Personne ne veut lire 650 lignes de code.
      • Partager sur Facebook
      • Partager sur Twitter

      Problème de collisions...

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown