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

Auteur Sujet: Fonction draw  (Lu 2231 fois)

0 Membres et 1 Invité sur ce sujet

Morgomir

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
Fonction draw
« le: Mai 22, 2017, 05:03:34 pm »
Bonjour, :)

Je "travaille" actuellement sur un petit projet perso et je viens de me confronter à un problème assez chiant.
J'essaie de faire déplacer un personnage sur une map 2D vue de côté que je modélise par un tableau2D d'int. Chaque valeur est associée à un bloc différent (0->air ; 1->terre ; 2->pierre etc...)
J'ai donc initialisé un tableau avec les sprites de chaque bloc dans le bon ordre et l'ai nommé liste_bloc
Et j'affiche cette map en la parcourant avec une double boucle en déplaçant les blocs directement dans la liste_bloc et en les dessinant, ce qui donne ceci :

liste_bloc[carte[ i ][j]].setPosition(Vector2f(i*tailleBloc, j*tailleBloc));
window.draw(liste_bloc[carte[ i ][j]]);

Les deux boucles imbriquées font environ maximum 250 000 fois ces 2 commandes (480 blocs de largeur * 480 blocs de hauteur) (par frame, soit *60 par seconde)
Je me rend bien compte que c'est un total non négligeable d'instructions mais je ne peux pas faire autrement. Si ?
En soit je pourrais réduire le nombre d'appel de ces fonctions quasiment par 2 mais le fait est que si avec aucune fonctionnalité mon jeu rame ainsi j'ai peur de ce que ça va devenir .. (je réduirais surement de toute manière cet appel encore plus car la vision du jeu est trop large mais la question m'intéresse quand même)

Je voudrais donc savoir s'il est possible de faire autrement pour l'affichage d'une map 2D (plus optimisée) ou peut être est-ce la fonction draw qui n'est pas faite pour être appelé autant de fois ?
En tant que débutant dans le domaine je cherche conseil et j'espère que vous pourrez m'aider. Merci d'avance pour votre aide :)

ps: j'utilise Code::Blocks et C++, même si je ne pense pas qu'SFML fonctionne avec autre chose que C++, je préfère préciser :)
« Modifié: Mai 23, 2017, 08:51:47 am par Morgomir »

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re: Fonction draw
« Réponse #1 le: Mai 22, 2017, 06:07:30 pm »
Tu peux ne pas afficher un bloc s'il est hors de la vue, si c'est pas déjà ce que tu fais
Tu peux facilement trouver le i à partir duquel commencer en soustrayant la moitié de la largeur de ta vue à la position de la vue, le tout divisé par taille_bloc.
Par exemple ta vue est centrée en 800, 500, elle fait 300, 200 de taille, tes blocs font 50.
ça fait i = (800 - 300 / 2) / 50 = 13
Pour trouver le i où terminer c'est pareil mais en additionnant la moitié de la vue au lieu de la soustraire.
(pour le j, bah pareil mais avec les hauteurs)
Ça devrait probablement améliorer les performances.

Sinon tu peux aussi construire un vertex array avec tout (ou une partie si t'en as vraiment un nombre de ouf) tes blocs dedans ça te permettra de tout dessiner en un seul draw.

Guillaume__

  • Newbie
  • *
  • Messages: 42
    • Voir le profil
Re: Fonction draw
« Réponse #2 le: Mai 22, 2017, 06:51:44 pm »
Bonjour Morgomir,

La principale chose à faire dans ton cas pour gagner en performance est de jouer sur le nombre d'appel à draw comme l'a souligné G..

Actuellement pour chacune des tiles de ta carte tu effectues un appel à draw. Le problème est qu'un nombre trop conséquent d'appel à la méthode draw ralentit le programme, c'est pourquoi il serait judicieux de mettre en place un Vertex Array pour l'affichage de ta carte. Pour faire simple il va te permettre d'afficher d'un seul appel à draw l'ensemble ta carte.

Je ne vais pas entrer plus dans les détails, et aussi je te redirige vers cet article qui explicite le fonctionne des Vertex Array avec la SFML. Tu y trouveras à la fin une section particulièrement intéressant sur le principe du tilemap : Concevoir ses entités avec les tableaux de vertex

Cordialement G
Rejoignez-nous sur le serveur
Discord SFML

Morgomir

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
Re: Fonction draw
« Réponse #3 le: Mai 22, 2017, 09:14:31 pm »
En effet j'affiche actuellement en dehors de mon écran (trop d'ailleurs), de plus, je compte réduire le nombre de blocs visibles par écran en fixant une taille (ce n'est pas normal qu'un joueur voit plus qu'un autre parce qu'il a une résolution plus élevée ! :p) Je vais me pencher sur ce nouvel outil qui a l'air très intéressant :)

Merci à vous deux pour vos conseils et votre précision !

ps: G. : j'utilisais déjà cette méthode pour afficher les blocs uniquement autour du joueur, étant donné qu'il peut se déplacer et que je ne veux pas afficher TOUTE la map, ça n'aurait aucun sens ^^. Mais merci quand même :p