IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SFML Discussion :

Positionnement d'un Sprite 2D : Où doit être l'origine ?


Sujet :

SFML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Août 2009
    Messages : 32
    Par défaut Positionnement d'un Sprite 2D : Où doit être l'origine ?
    Bonsoir,

    L'image suivante représente les 4 images qui compose une de mes animations d'un Sprite.


    Comme on le voit, les rectangles englobant mes 4 Pikachu ne sont pas des mêmes dimensions. Bon OK si pour les images 2 et 4 et pour les images 1 et 3 mais, c'est un hasard en fait.

    Souvent dans ce genre de petits projets (uiui c'est un petit projet), on choisi la facilité avec des images de même dimension. Après tout c'est nous qui créons nos images, on peut les gérer comme on veut.

    Mais j'aimerais dans mon code pouvoir gérer le cas où chaque image de mes animations n'est pas la même.
    Et pour l'instant, c'est mal géré.
    Dans mon appli, un Sprite est affiché avec pour origine le pixel haut-gauche (le point vert ci-dessus). Ce qui cause un décalage des images, d'une animation à l'autre.

    Ce qu'il faudrait faire, c'est considérer le point d'origine au milieu de l'image, autrement dit dessiner l'image à :
    X = Sprite.X - Sprite.LARGEUR/2
    Y = Sprite.Y - Sprite.HAUTEUR/2

    J'ai deux questions avec cette méthode :
    - Faudrait-il calculer ces nouvelles valeurs de X e Y temporairement, juste pour l'affichage, ou considérer ces positions comme définitives ? (en gros, Sprite.X == Affichage.Sprite.X ?)
    - Cette façon de faire peut-être compliquer une future implémentation de la gestion des collisions ?

    Et petite question bonus : Une autre solution ?

    Donc je résumé (parceque bon j'écris, j'écris...) : Comment gérer ce décalage qui a lieu lors de l'animation d'un Sprite, en raison de la différence de dimension des dimensions de chaque image qui la compose ?

    Pour info, je code en C++ avec la SFML, en usant des classes AnimatedSprite, SpriteFrame et SpriteAnimation, des amélioration persos de respectivement sf::Sprite, sf::Rect<int> et std::vector<SpriteFrame>.
    Normalement, ces considérations techniques ne sont pas à prendre en compte, il s'agit de programmation de Sprites en général.

    Bonne soirée,
    Oragon Efreet

  2. #2
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 532
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 532
    Par défaut
    Salut,

    Citation Envoyé par Oragon Efreet Voir le message
    Comme on le voit, les rectangles englobant mes 4 Pikachu ne sont pas des mêmes dimensions. Bon OK si pour les images 2 et 4 et pour les images 1 et 3 mais, c'est un hasard en fait.
    tu vas te casser la tête pour rien...
    il suffit de trouver une taille d'image carrée qui soit le plus grand dénominateur commun possible ( ou plus petit commun multiple ) , tu centres le personnage dessus et hop !
    Par exemple tu peux prendre des images de 128*128 et positionner le personnage au centre dans ton logiciel de dessin ( The GIMP,Paint Shop Pro,PhotoShop...)

    C'est ce que j'ai fait pour mon jeu.
    http://www.developpez.net/forums/d75...apoleoniennes/

    Ce qu'il faudrait faire, c'est considérer le point d'origine au milieu de l'image, autrement dit dessiner l'image à :
    X = Sprite.X - Sprite.LARGEUR/2
    Y = Sprite.Y - Sprite.HAUTEUR/2

    J'ai deux questions avec cette méthode :
    - Faudrait-il calculer ces nouvelles valeurs de X e Y temporairement, juste pour l'affichage, ou considérer ces positions comme définitives ? (en gros, Sprite.X == Affichage.Sprite.X ?)
    Non le plus simple c'est de faire le calcul une seule fois par exemple lors de l'appel du constructeur de Sprite et de stocker les coordonnées du centre dans cette classe/structure Sprite

    Citation Envoyé par Oragon Efreet Voir le message
    Comment gérer ce décalage qui a lieu lors de l'animation d'un Sprite, en raison de la différence de dimension des dimensions de chaque image qui la compose ?
    Pour cela il faut balayer de gauche à droite et de haut en bas l'image et prendre en considérations les pixels non transparents.
    Ensuite tu obtiens une sorte de "masque" une matrice dont il faut déterminer en quelque sorte le barycentre.
    Mais tu risques de te compliquer la vie pour pas grand chose le mieux c'est de centrer le sprite dans l'image dans le logiciel de dessin..

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Août 2009
    Messages : 32
    Par défaut
    Non le plus simple c'est de faire le calcul une seule fois
    Oui bien sûr je ne voyais pas autrement. Inutile de calculer un invariant.

    Donc dans l'idée, tu considères bel est bien un carré commun.

    Mais là où je voulais vraiment en venir, finalement, c'est.
    Mettons la méthode :
    Sprite.Afficher(X, Y);

    Pour toi, (X,Y) est le point au centre, où le point en haut à gauche.
    Dans ton cas, apparement il s'agit du point en haut à gauche.

    Bon je pense que je vais faire comme ça t'façon.

    Merchi

  4. #4
    Membre émérite
    Homme Profil pro
    Inscrit en
    Octobre 2004
    Messages
    398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2004
    Messages : 398
    Par défaut
    Citation Envoyé par Oragon Efreet Voir le message
    Oui bien sûr je ne voyais pas autrement. Inutile de calculer un invariant.

    Donc dans l'idée, tu considères bel est bien un carré commun.

    Mais là où je voulais vraiment en venir, finalement, c'est.
    Mettons la méthode :
    Sprite.Afficher(X, Y);

    Pour toi, (X,Y) est le point au centre, où le point en haut à gauche.
    Dans ton cas, apparement il s'agit du point en haut à gauche.

    Bon je pense que je vais faire comme ça t'façon.

    Merchi
    moi aussi jai pris un carré commun cest plus simple
    tu peux dessiner en haut ou au milieu peu importe, tu sais calculer de toutes facon le centre de ton image donc pas de pb

    le plus chiant en faisant ca, cest pour les coliisions ...
    forcement si le personnage est a la verticale et a lhorizontale, il aura pas les memes dimensions et tu pourras pas te contenter de voir si le sprite est en collision avec un autre ou non ...

  5. #5
    Membre éprouvé Avatar de kain_tn
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 870
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 870
    Par défaut
    Citation Envoyé par Oragon Efreet Voir le message
    Mais là où je voulais vraiment en venir, finalement, c'est.
    Mettons la méthode :
    Sprite.Afficher(X, Y);

    Pour toi, (X,Y) est le point au centre, où le point en haut à gauche.
    Dans ton cas, apparement il s'agit du point en haut à gauche.
    Je pense que ça dépend de l'API que tu utilise. Pour la SDL par exemple c'est le point en haut à gauche.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Août 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Août 2009
    Messages : 32
    Par défaut
    Et pour la SFML c'est le point qu'on veut

  7. #7
    Membre Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Par défaut
    Pour info une autre solution passe, par exemple, par une structure frame contenant mettons x0, y0, width, height. Dans ta séquence t'as plusieurs frames et chaque fois tu récupères les coordonnées de la frame courante et tu vas chercher dans ta texture/image complète la portion qui t'intéresse. C'est plus lourd en exécution mais beaucoup moins lourd en mémoire. En revanche, t'es obligé de stocker tes coordonnées de frames quelque part. Dans un moteur que j'ai codé j'utilise cette méthode qui fonctionne très bien. Ce qui veux dire que le système peut gérer des frames de tailles différentes et donc aussi, de tailles identiques. Car, en plus des frames sequences, c'est particulièrement pratique de pouvoir stocker également des décors de tailles différentes dans un même fichier et dans une même texture (en tout cas dans le cadre d'OGL).

Discussions similaires

  1. Pourquoi le scanf doit être interdit
    Par gnto dans le forum C
    Réponses: 4
    Dernier message: 14/06/2006, 14h54
  2. [WebForms]A quel endroit doit-être présent le framework ?
    Par HULK dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 13/04/2006, 14h59
  3. [Client/Serveur]Où doit être mis outil mesure Performances?
    Par sabure dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 06/03/2006, 23h52
  4. Réponses: 4
    Dernier message: 24/02/2006, 11h50
  5. dans un CSS que le texte doit être souligé?
    Par hstlaurent dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 01/09/2005, 16h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo