Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Collisions pixel près  (Lu 2034 fois)

0 Membres et 1 Invité sur ce sujet

Tyr

  • Newbie
  • *
  • Messages: 23
    • Voir le profil
Collisions pixel près
« le: Juillet 21, 2013, 01:21:51 am »
Bonjour !
Je programme un petit jeu de plateforme, et dans le cadre du développement de celui-ci, j'utilise depuis peu un système de collisions au pixel près (qui est, si mes souvenirs sont exacts, quelque part dans la doc), dont voici la méthode supposée me dire s'il y a ou non collision entre deux sprites, ainsi que la classe associée.
Je dois faire en sorte d'empêcher le héros (qui correspond à mon sprite 1, dirons-nous) de passer à travers la map (dont le sprite correspond au sprite 2, pour rester dans ce même esprit).

class BitmaskManager {


        public:

                ~BitmaskManager()
                {
                        map<const Texture*, Uint8*>::const_iterator end = Bitmasks.end();
                        for (map<const Texture*, Uint8*>::const_iterator iter = Bitmasks.begin(); iter != end; iter++)
                                delete [] iter->second;
                }

                Uint8 GetPixel (const Uint8* mask, const Texture* tex, unsigned int x, unsigned int y)
                {
                        if (x > tex->getSize().x || y > tex->getSize().y)
                                return 0;

                        return mask[x + y * tex->getSize().x];
                }

                Uint8* GetMask (const Texture* tex)
                {
                        Uint8* mask;
                        map<const Texture*, Uint8*>::iterator pair = Bitmasks.find(tex);

                        if (pair == Bitmasks.end())
                        {
                                Image img = tex->copyToImage();
                                mask = CreateMask(tex, img);
                        }
                        else mask = pair->second;

                        return mask;
                }

                Uint8* CreateMask (const Texture* tex, const Image& img)
                {
                        Uint8* mask = new Uint8[tex->getSize().y * tex->getSize().x];

                        for (unsigned int y = 0; y < tex->getSize().y; y++)
                        {
                                for (unsigned int x = 0; x < tex->getSize().x; x++)
                                        mask[x + y * tex->getSize().x] = img.getPixel(x, y).a;
                        }

                        Bitmasks.insert(pair<const Texture*, Uint8*>(tex,mask));

                        return mask;
                }

        private:

                map<const Texture*, Uint8*> Bitmasks;
        };
       
        BitmaskManager Bitmasks;
 
        // Retourne true s'il y a collision entre deux pixels tels que alpha > 0
        bool pixelPerfectCollision(const Sprite& Object1, const Sprite& Object2, Uint8 AlphaLimit)
        {
                FloatRect Intersection;

                if (Object1.getGlobalBounds().intersects(Object2.getGlobalBounds(), Intersection))
                {
                        IntRect O1SubRect = Object1.getTextureRect();
                        IntRect O2SubRect = Object2.getTextureRect();

                        Uint8* mask1 = Bitmasks.GetMask(Object1.getTexture());
                        Uint8* mask2 = Bitmasks.GetMask(Object2.getTexture());

                        // Loop through our pixels
                        for (int i = (int) Intersection.left; i < Intersection.left+Intersection.width; i++)
                        {
                                for (int j = (int) Intersection.top; j < Intersection.top + Intersection.height; j++)
                                {
                                        Vector2f o1v = Object1.getInverseTransform().transformPoint((float) i, (float) j);
                                        Vector2f o2v = Object2.getInverseTransform().transformPoint((float) i, (float) j);
 
                                        // Make sure pixels fall within the sprite's subrect
                                        if (o1v.x > 0 && o1v.y > 0 && o2v.x > 0 && o2v.y > 0 &&
                                                o1v.x < O1SubRect.width && o1v.y < O1SubRect.height &&
                                                o2v.x < O2SubRect.width && o2v.y < O2SubRect.height) {

                                                        if (Bitmasks.GetPixel(mask1, Object1.getTexture(), (int) o1v.x + O1SubRect.left, (int) o1v.y + O1SubRect.top) > AlphaLimit &&
                                                                Bitmasks.GetPixel(mask2, Object2.getTexture(), (int) o2v.x + O2SubRect.left, (int) o2v.y + O2SubRect.top) > AlphaLimit)
                                                                return true;
                                        }
                                }
                        }
                }
                return false;
        }

Jusqu'ici, tout baigne. Cependant, j'aimerais trouver les coordonnées du point de collision, afin de faire reculer ou avancer le héros en fonction du côté par lequel il rentre en collision avec la map.
Il y a bien une fonction getCollisionRect, mais je ne comprends pas trop son fonctionnement, et ne sais pas trop si elle pourrait ou non être la clé de mon problème.

Merci d'avance !