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

Auteur Sujet: Jeu en 2d iso : Affichage des tiles uniquement visible par le joueur  (Lu 2697 fois)

0 Membres et 1 Invité sur ce sujet

arrakis42

  • Newbie
  • *
  • Messages: 8
    • Voir le profil
Bonjour,

Je débute en programmation avec la sfml et je suis en train de faire un jeu en 2d isométrique. J'affiche donc ma map en assemblant des tiles, mon personnage avance dessus en bougeant la caméra, mais le soucis c'est que sur une grosse map le jeu commence à ramer sérieusement au niveau des fps.

 Je vous consulte donc pour savoir quel est la meilleur technique à adopter et comment l'appliquer à mon code pour optimiser l'affichage des tiles, j'ai en tête de prendre la position centrale de la view et d'afficher le nombre de tiles en x et en y selon cette position.

voici un bout de code en c++ :

  sf::Vector2f positionTileUpLeft(0, 0);
  int max_tile_length = 10;
  int max_tile_width = 10;

  std::vector<sf::Sprite *>::iterator it = this->floorVect.begin();
  for (i = positionTileUpLeft.x; i < this->y_map || i < max_tile_length; i++) // je parcours tous les tiles et je set leurs valeurs en x et y
    {
      for (j = positionTileUpLeft.y; j < max_tile_width; j++)
        {
          x = (i - j) * (*it)->GetSize().x / 2;
          y = (i + j) * (*it)->GetSize().y / 2;

          (*it)->SetX(x);
          (*it)->SetY(y);                                                                                                                                  
          this->App->Draw(**it);
          ++it;
        }
    }

 

Merci d'avance pour votre aide.

Cpl.Bator

  • Hero Member
  • *****
  • Messages: 540
    • Voir le profil
Re : Jeu en 2d iso : Affichage des tiles uniquement visible par le joueur
« Réponse #1 le: Juin 23, 2013, 01:27:17 pm »
Dans un premier temps je passerais aux vertex array se qui te permet d'avoir qu'un seul appel à draw , qui lui est couteux en temps.
Dans un second temps j'optimiserais l'affichage en supprimant les vertex qui sont hors de l'écran.
un lien pour commencer : http://www.tonypa.pri.ee/tbw/

arrakis42

  • Newbie
  • *
  • Messages: 8
    • Voir le profil
Re : Jeu en 2d iso : Affichage des tiles uniquement visible par le joueur
« Réponse #2 le: Juin 23, 2013, 02:09:22 pm »
J'ai reussi à supprimer les  vertex hors de l'écran, ca a beaucoup améliorer les performance du jeu, mais je ne vois comment faire  un array de vertex sur mes draws sachant que je suis en sfml :/

Cpl.Bator

  • Hero Member
  • *****
  • Messages: 540
    • Voir le profil
Re : Jeu en 2d iso : Affichage des tiles uniquement visible par le joueur
« Réponse #3 le: Juin 23, 2013, 03:02:45 pm »
Lis les tutoriels de Laurent sur les vertex array , notamment les tilemap

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Jeu en 2d iso : Affichage des tiles uniquement visible par le joueur
« Réponse #4 le: Juin 29, 2013, 10:36:26 am »
Oui les affichages sont lent si on fait trop d'appels à draw, moi je fais un appel à draw par tile visible à l'écran et même si je tourne avec un bon FPS, au niveau des animations (ou je change de tiles à chaque fois.) ça saccade pas mal :

http://www.youtube.com/watch?v=0dqXs82VNbI&feature=youtu.be

Je penses que il faudrait plutôt que j'essaye d'utiliser une tileMap ?
Faut que j'aille voir sur le tutoriel de Laurent.
Pour l'affichage de ce qui est visible à l'écran, je ne sais pas comment tu gère le stockage des tiles donc, mais moi je mets mes tiles dans une grille virtuelle remplie de losanges, chaque losange à une coordonnée  iso (0, 0; 1, 0, 2, 0, etc...) et je me sert de ses coordonnées pour récupérer l'indice du losange dans mon vecteur.
Je récupère chaque losange qui se trouve dans la vue en oubliant pas de décaler une ligne sur deux.
//Cherche les tiles qui sont visibles à l'écran.
void GridMap::checkVisibleTiles (Vector2f &centerView) {
    visibleTiles.clear();
    int x = (centerView.x - Configuration::getConfiguration().x / 2) - 100;
    int y = (centerView.y - Configuration::getConfiguration().y / 2) - 50;
    int endX = (centerView.x - Configuration::getConfiguration().x / 2) + Configuration::getConfiguration().x + 100;
    int endY = (centerView.y - Configuration::getConfiguration().y / 2) + Configuration::getConfiguration().y + 50;
    BoundingRectangle br(x, y, Configuration::getConfiguration().x + 100, Configuration::getConfiguration().y + 50);

    for (int l = 0; l < NB_LAYERS; l++) {
        for (int i = x / 100 * 100; i <= endX / 100 * 100; i+=100) {
            for (int j = y / 50 * 50; j <= endY / 50 * 50; j+=25) {
                int deltaX = (j % 50 == 0) ? 0 : 50;

                Vec2f point(i + deltaX, j);
                CellMap* cell = getGridCellAt(point);
                if (cell != NULL) {

                    for (unsigned int n = 0; n < cell->getEntitiesInside()[l].size(); n++) {
                        Entity* entity = cell->getEntityInside(n, l);
                        Tile *t;
                        if (entity->getType() == Entity::E_GROUND
                                   || entity->getType() == Entity::E_DECOR
                                   || entity->getType() == Entity::E_WALL) {
                            t = static_cast<Tile*>(entity);

                        }
                    }
                }
            }
        }
    }
}