Précédent   Forum du club des développeurs et IT Pro > Applications > Développement 2D, 3D et Jeux > API graphiques > SFML
SFML Forum d'entraide sur l'API SFML
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 19/11/2009, 21h45   #1
Oragon Efreet
Candidat au titre de Membre du Club
 
Kevin D'ORANGE
Inscription : août 2009
Messages : 33
Détails du profil
Informations personnelles :
Nom : Kevin D'ORANGE
Localisation : France, Doubs (Franche Comté)

Informations forums :
Inscription : août 2009
Messages : 33
Points : 13
Points : 13
Envoyer un message via MSN à Oragon Efreet Envoyer un message via Skype™ à Oragon Efreet
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
Oragon Efreet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2009, 22h21   #2
Mat.M
Expert Confirmé Sénior
 
Développeur informatique
Inscription : novembre 2006
Messages : 4 453
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 : 4 453
Points : 5 874
Points : 5 874
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/

Citation:
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..
Mat.M est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2009, 22h55   #3
Oragon Efreet
Candidat au titre de Membre du Club
 
Kevin D'ORANGE
Inscription : août 2009
Messages : 33
Détails du profil
Informations personnelles :
Nom : Kevin D'ORANGE
Localisation : France, Doubs (Franche Comté)

Informations forums :
Inscription : août 2009
Messages : 33
Points : 13
Points : 13
Envoyer un message via MSN à Oragon Efreet Envoyer un message via Skype™ à Oragon Efreet
Citation:
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
Oragon Efreet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/12/2009, 00h54   #4
franck06
Membre actif
 
Inscription : octobre 2004
Messages : 243
Détails du profil
Informations forums :
Inscription : octobre 2004
Messages : 243
Points : 189
Points : 189
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 ...
franck06 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/12/2009, 08h17   #5
kain_tn
Membre Expert
 
Avatar de kain_tn
 
Homme
Inscription : mars 2005
Messages : 600
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Canada

Informations forums :
Inscription : mars 2005
Messages : 600
Points : 1 329
Points : 1 329
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.
kain_tn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/12/2009, 08h35   #6
Oragon Efreet
Candidat au titre de Membre du Club
 
Kevin D'ORANGE
Inscription : août 2009
Messages : 33
Détails du profil
Informations personnelles :
Nom : Kevin D'ORANGE
Localisation : France, Doubs (Franche Comté)

Informations forums :
Inscription : août 2009
Messages : 33
Points : 13
Points : 13
Envoyer un message via MSN à Oragon Efreet Envoyer un message via Skype™ à Oragon Efreet
Et pour la SFML c'est le point qu'on veut
Oragon Efreet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/12/2009, 11h07   #7
Djakisback
Membre Expert
 
Avatar de Djakisback
 
Inscription : février 2005
Messages : 1 914
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 1 914
Points : 1 840
Points : 1 840
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).
Djakisback est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/12/2009, 14h15   #8
Emmanuel Deloget
Expert Confirmé Sénior
 
Homme Emmanuel Deloget
Développeur informatique
Inscription : septembre 2007
Messages : 1 827
Détails du profil
Informations personnelles :
Nom : Homme Emmanuel Deloget
Âge : 37
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 827
Points : 4 395
Points : 4 395
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.
Emmanuel Deloget est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/12/2009, 15h08   #9
Djakisback
Membre Expert
 
Avatar de Djakisback
 
Inscription : février 2005
Messages : 1 914
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 1 914
Points : 1 840
Points : 1 840
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
Djakisback est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/12/2009, 15h41   #10
Emmanuel Deloget
Expert Confirmé Sénior
 
Homme Emmanuel Deloget
Développeur informatique
Inscription : septembre 2007
Messages : 1 827
Détails du profil
Informations personnelles :
Nom : Homme Emmanuel Deloget
Âge : 37
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 827
Points : 4 395
Points : 4 395
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.
Emmanuel Deloget est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/12/2009, 15h47   #11
Djakisback
Membre Expert
 
Avatar de Djakisback
 
Inscription : février 2005
Messages : 1 914
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 1 914
Points : 1 840
Points : 1 840
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 ^^
Djakisback est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 00h32.


 
 
 
 
Partenaires

Hébergement Web