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

  1. #1
    Nouveau membre du Club
    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
    Points : 30
    Points
    30
    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 éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    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 361
    Points : 20 379
    Points
    20 379
    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
    Nouveau membre du Club
    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
    Points : 30
    Points
    30
    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 éclairé
    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
    Points : 710
    Points
    710
    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
    Expert éminent Avatar de kain_tn
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 564
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 564
    Points : 7 286
    Points
    7 286
    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.
    Copier c'est copier; voler c'est vendre un CD une vingtaine d'euros!


    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include <stdio.h>
     
    int main(int argc, char **argv) {
     
        printf("So long, and thanks for the fish, Dennis...\n");
        return 0;
    }

  6. #6
    Nouveau membre du Club
    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
    Points : 30
    Points
    30
    Par défaut
    Et pour la SFML c'est le point qu'on veut

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

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    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).
    Vive les roues en pierre

  8. #8
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Si tu veux supporter des dimensions arbitraires, alors il faut aussi que tu le fait que le point d'ancrage du sprite est à déterminer pour chaque sprite. Si les sprites sont sur une planche, il te faut donc connaitre

    1) le rectangle englobant
    2) le point d'ancrage par rapport à un point particulier du rectangle englobabtn (par exemple le coin haut/gauche).

    De cette manière, tu sauras toujours positionner le sprite, quel qu'il soit. La méthode est generique et ouverte, mais suppose que tu as un outil spécial pour générer les planches de sprites. Un tel outil peut être créé pour packager les sprites de manière à ce qu'ils prennent le moins de place possible.

    1) en entrée, N bitmap de taille connue, avec (par exemple) le point d'ancrage au centre.
    2) pour chaque bitmap,
    2.1) calculer la boite englobante minimale du sprite
    2.2) recalculer la position du point d'ancrage en fonction de cette boite
    2.3) stocker ces deux information quelque part
    2.4) copier la partie du bitmap qui nous intéresse dans la planche destination

    L'algorithme pour créer la planche destination peut être plus ou moins complexe (il peut se contenter de placer le sprite en force brute, ou essayer de minimiser les cache miss du GPU, ...)

    Quoi qu'il en soit, cette idée que le centre est un point d'intérêt particluer lorsque les sprites sont de taille arbitraire va vite poser soucis, car elle suppose que le centre de gravité du sprite ne change jamais - hors une telle chose ne peut pas être garantie.

    Ceci dit, vu la puissance de calcul à notre disposition, je ne vois pas trop l'intérêt d'éviter les feuilles de sprites classique (où tous les sprites ont la même taille).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  9. #9
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 021
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Ceci dit, vu la puissance de calcul à notre disposition, je ne vois pas trop l'intérêt d'éviter les feuilles de sprites classique (où tous les sprites ont la même taille).
    De ce que j'ai compris, en mode hardware, tu stockes tes textures dans la Ram de la CG. Si t'as une carte de 256mo, ça peut se remplir assez vite a priori avec de la texture 32bits et beaucoup de sprites animés. Quand t'es à saturation de la RAM de la CG, il y a alors des va-et-vient entre la RAM de l'ordi et de la CG, mais effectivement le ralentissement est peut-être négligeable.
    N'hésitez pas à me corriger si je me trompe
    Vive les roues en pierre

  10. #10
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Djakisback Voir le message
    De ce que j'ai compris, en mode hardware, tu stockes tes textures dans la Ram de la CG. Si t'as une carte de 256mo, ça peut se remplir assez vite a priori avec de la texture 32bits et beaucoup de sprites animés. Quand t'es à saturation de la RAM de la CG, il y a alors des va-et-vient entre la RAM de l'ordi et de la CG, mais effectivement le ralentissement est peut-être négligeable.
    N'hésitez pas à me corriger si je me trompe
    Oui, c'est ça. De toute façon, comment souhaiterais-tu faire autrement ?

    Le ralentissement sera négligeable à partir du moment ou au lieu d'envoyer des textures de 8192x8192, tu envoie des feuilles de sprites plus petites (1024x1024 au maximum)
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  11. #11
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 021
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut
    Merci

    Citation Envoyé par Emmanuel Deloget Voir le message
    Le ralentissement sera négligeable à partir du moment ou au lieu d'envoyer des textures de 8192x8192, tu envoie des feuilles de sprites plus petites (1024x1024 au maximum)
    Ah oui effectivement je n'avais pas pensé à ça ^^
    Vive les roues en pierre

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