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

Auteur Sujet: tileMap Sprite Positionnement et Scintillement  (Lu 2273 fois)

0 Membres et 1 Invité sur ce sujet

TrucMuche

  • Newbie
  • *
  • Messages: 11
    • Voir le profil
    • E-mail
tileMap Sprite Positionnement et Scintillement
« le: Février 04, 2020, 09:11:35 pm »
Bonjour,

Je souhaite créer un jeu dans le cadre de mes loisirs.
Ne maitrisant pas les Classes et la POO j'utilise pour l'instant des fonctions tant bien que mal. J'ai honte de vous montrer le code, mais je peux si besoin.

Je suis parvenus à créer un personnage 8 vue sous forme de Sprite texturé avant la boucle principale puis  découpé et draw dans la boucle principale.
L'animation se passe convenablement, et ce, dans les 8 directions condensées en une seul texture. Une direction comprends 12 découpes en x et une découpe en y. l'ensemble représentant le mouvement du personnage. Cela fait une découpe de texture de 64 par 34 pixels, collés sur le sprite. Cette découpe est appelée toute les 40 ms (1/25 = 40 ms)

J'ai ajouté les commandes de mouvement de mon personnage, par des key enable et key disable. Je déplace mon sprite avec des "mySprite.move(x,y);" les move sont mit à jour en même temps que l'animation du sprite. J'ai vite activé la synchronisation vertical. mais je ressent encore un faible scintillement presque pas gênant.

Je continue mon code et ajoute un tile map. Il est sous forme de tableau[][] de sprite texturé par une seul tuile, avant la boucle principale . J'ai une tuile isométrique type losange  1 pixel en y pour 2 en x, contenue dans une texture de 128 par 64 pixel. Lorsque je déplace ma map, que ce soit une map de 1 par 1 sprite texturé, ou de 50 par 50 j'ai un scintillement très gênant, de plus en plus gênant d'autant que j'augmente la taille du tableau.
la texture d'origine est en format png avec un fond transparent, ci joint : tile0.png

L'imprime écran évoquant le scintillement sur le fond jaune de ma fenêtre, ci joint  ; tileMoche.png.
Je parle de scintillement quand je suis en mouvement, car à l’arrêt, l'image reste dans l'état ci présenté par tileMoche.png.
Sur tileMoche on voit plusieurs zones dégradées , ces zones grisées / floutées se déplacent le long du contour noir du losange lors d'un déplacement. En faite Le losange n'est jamais rafraichie de la même façon.

Pourtant je déplace les sprite avec des integer,  donc des pixels entiers. Enfin qu'es qui vient dégrader la qualité de mes texture ?
Dois-je songer à utiliser des vertex ?

 
 

G.

  • Hero Member
  • *****
  • Messages: 1592
    • Voir le profil
Re: tileMap Sprite Positionnement et Scintillement
« Réponse #1 le: Février 05, 2020, 12:00:56 am »
Tu as pas joint tilemoche.png :p

TrucMuche

  • Newbie
  • *
  • Messages: 11
    • Voir le profil
    • E-mail
Re: tileMap Sprite Positionnement et Scintillement
« Réponse #2 le: Février 08, 2020, 10:11:50 pm »
oups pardon   ::)
 voila :

Peut-être une piste, je viens de m’apercevoir que dans l'imprime écran, la taille de la tuile ne fait plus 128 par 64 mais 128 par 59.
J'aurais pus mal redimensionner la fenêtre ?
Je vais devoir ajouter du code pour gérer cela ?
« Modifié: Février 08, 2020, 10:23:32 pm par TrucMuche »

TrucMuche

  • Newbie
  • *
  • Messages: 11
    • Voir le profil
    • E-mail
Re: tileMap Sprite Positionnement et Scintillement
« Réponse #3 le: Février 17, 2020, 07:42:42 pm »
Bonjour,

J'ai du nouveau

Déjà mon code est simplifié pour afficher uniquement la MAP et la déplacer avec les touches.


Je défraichie la map toutes les 20 ms, au lieu de 40ms (soit 50 pixel/s par "move").
J'ai constaté une amélioration, moins le temps de voir les scintillements.

J'ai mis les bordures de la tuile en gris claire, cela aussi contre le scintillement

MAIS il y a toujours un MAIS :

C'est toujours présent ce scintillement.
J'ai un doute dans mon calcule de placement des tuiles mais je ne vois pas quoi.
J'ai un doute dans le dessin de ma tuile.
Es trop brut ?
La forme ne correspond pas au calcul de placement des tuiles ?
Seriez vous comment l'améliorer ou me conseiller en dessin ?

Voici mon code :
//directive de préprocesseur

//systeme windows
#include <windows.h>

//Standard
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>

//SFML
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>

//obtention de la taille de l'écran utilisateur en pixel.
int const SCREEN_X = GetSystemMetrics(SM_CXSCREEN);
int const SCREEN_Y = GetSystemMetrics(SM_CYSCREEN);
int const SCREEN_X_MIDDLE = SCREEN_X / 2;
int const SCREEN_Y_MIDDLE = SCREEN_Y / 2;

//Constante de la MAP
int const TAILLEMAP_X = 10, TAILLEMAP_Y = 20;
int const UP = 4, UP_RIGHT = 3, RIGHT = 2, DOWN_RIGHT = 1, DOWN = 0,DOWN_LEFT = 7,LEFT = 6,UP_LEFT = 5;


void maj_map (sf::Sprite myMap[TAILLEMAP_Y][TAILLEMAP_X], int direction)
{
    int x_move = 0;
    int y_move =0;


    switch (direction)
        {
            case UP:
                x_move = 0;
                y_move = 2;
                break;
            case UP_RIGHT:
                x_move =-2;
                y_move =1;
                break;
            case RIGHT:
                x_move =-2;
                y_move =0;
                break;
            case DOWN_RIGHT:
                x_move =-2;
                y_move =-1;
                break;
            case DOWN:
                x_move =0;
                y_move =-2;
                break;
            case DOWN_LEFT:
                x_move =2;
                y_move =-1;
                break;
            case LEFT:
                x_move =2;
                y_move =0;
                break;
            case UP_LEFT:
                x_move =2;
                y_move =1;
                break;
            default:
                x_move =0;
                y_move =0;
                break;
        }

    for (int Ytile0 = 0; Ytile0 < TAILLEMAP_Y ; ++ Ytile0) // index
    {
        for (int Xtile0 = 0; Xtile0 < TAILLEMAP_X ; ++ Xtile0) // jndex lol
        {
            myMap[Ytile0][Xtile0].move(x_move,y_move);
        }
    }
}

int maj_direction(bool up,bool right, bool down, bool left)
{

    int direction = -1;
    if ( up && !right && !down && !left ){direction = UP;}
    if ( up &&  right && !down && !left ){direction = UP_RIGHT;}
    if (!up &&  right && !down && !left ){direction = RIGHT;}
    if (!up &&  right &&  down && !left ){direction = DOWN_RIGHT;}
    if (!up && !right &&  down && !left ){direction = DOWN;}
    if (!up && !right &&  down &&  left ){direction = DOWN_LEFT;}
    if (!up && !right && !down &&  left ){direction = LEFT;}
    if ( up && !right && !down &&  left ){direction = UP_LEFT;}



    return direction;
}
int main()
{
//-------------------------
//création de la fenêtre
//-------------------------
    sf::RenderWindow myWindow(sf::VideoMode(1200, 600), "titredujeu");//celon taille écran
    //sf::RenderWindow myWindow(sf::VideoMode(SCREEN_X, SCREEN_Y), "titreduJeu",sf::Style::Fullscreen);//plein écran
    myWindow.setVerticalSyncEnabled(true); //activation de synchronisation vertical pour meilleur affichage
    myWindow.setFramerateLimit(60);// max fps
    myWindow.setKeyRepeatEnabled(false);//Désactivation de la répétition lorsqu'une touche est maintenu appuyée.
    //Activation de l'icon de la fenêtre
    sf::Image icon;
    if(!icon.loadFromFile("icon.png"))
    {
        //error...
        std::cout << "Load of icon Failed!" <<std::endl;
        exit(EXIT_FAILURE);
    }
    myWindow.setIcon(32,32,icon.getPixelsPtr());

    //-------------------------
    // Etat du jeux
    //-------------------------
    sf::Clock gameClock; //démarre le chrono
    sf::Time timeInterval;//espace de temps entre chaque mise à jours de l'ecran
    timeInterval = sf::milliseconds(20);
    sf::Time timeElapsed = gameClock.getElapsedTime();//enregistre le temps actuel
    sf::Time timePrecElapsed = timeElapsed;//enregistre le temps actuel précédent
    //sf::Time spriteElapsed = gameClock.getElapsedTime();

    sf::Clock myClock; //démarre le chrono

    int direction = -1;


    //-------------------------
    //MAP
    //-------------------------
    sf::Texture tile0Texture;
    tile0Texture.loadFromFile("Images/GAME/MAP/tile0_V2.png");
    tile0Texture.setSmooth (true);
    sf::Sprite tile0Sprite[TAILLEMAP_Y][TAILLEMAP_X];
    for (int Ytile0 = 0; Ytile0 < TAILLEMAP_Y ; ++ Ytile0) // index
    {
        for (int Xtile0 = 0; Xtile0 < TAILLEMAP_X ; ++ Xtile0) // jndex lol
        {
            tile0Sprite[Ytile0][Xtile0].setTexture(tile0Texture);
            if ( (Ytile0 % 2) == 0) //si Ytile est paire
            {
                tile0Sprite[Ytile0][Xtile0].setPosition( (128*(Xtile0)),(32*(Ytile0)));
            }
            else // impaire
            {
                tile0Sprite[Ytile0][Xtile0].setPosition((128*(Xtile0+1)-64),(32*(Ytile0)));
            }
        }
    }

    bool up = 0,upRight=0, right=0, downRight=0, down=0, downLeft=0, left=0, upLeft=0;

    int choix = 1;

    int curseurMenu = 1;
    while (myWindow.isOpen() && choix == 1)
    {
        // on traite tous les évènements de la fenêtre qui ont été générés depuis la dernière itération de la boucle
        sf::Event event;
        //------------------------------
        //Gestion Clavier , joystick ...
        //------------------------------
        while (myWindow.pollEvent(event))
        {// tant qu'il y a des évènements : clavier , joystick...
            switch (event.type)
            {
                //croix fermeture fenêtre
                case sf::Event::Closed:
                    choix = 0;
                    //window.close();
                    std::cout << "fenetre fermee par [X]!" <<std::endl;
                    break;
                // n'importe quelle touche pressée
                case sf::Event::KeyPressed:
                    switch (event.key.code)
                    {
                        case sf::Keyboard::Escape:
                            choix = 0;
                            //window.close();
                            std::cout << "fenetre fermee par Escape!" <<std::endl;
                            break;
                        case sf::Keyboard::Up:
                            up = 1;
                            down = 0;
                            break;
                        case sf::Keyboard::Right:
                            right = 1;
                            left = 0;
                            break;
                        case sf::Keyboard::Down:
                            down = 1;
                            up = 0;
                            break;
                        case sf::Keyboard::Left:
                            left = 1;
                            right = 0;
                            break;
                        default:
                            choix = 0;
                            break;
                    }
                    break;
                //n'importe quelle touche relachée
                case sf::Event::KeyReleased:
                    switch (event.key.code)
                    {
                        case sf::Keyboard::Up:
                            up = 0;
                            break;
                        case sf::Keyboard::Right:
                            right = 0;
                            break;
                        case sf::Keyboard::Down:
                            down = 0;
                            break;
                        case sf::Keyboard::Left:
                            left = 0;
                            break;
                        default:
                            break;
                    }
                    break;
            }
        }


        //------------------------------
        //Mise à jour de l'affichage
        //------------------------------
        timeElapsed = gameClock.getElapsedTime();//Mise à jour du temps écoulé
        // effacement de la fenêtre en une couleur au choix
        myWindow.clear(sf::Color(255,255,150));//BLANC beige
        // c'est ici qu'on dessine tout

        // gestion affichage de la map
        direction = maj_direction(up, right, down, left);
        if (timeElapsed >= timePrecElapsed + timeInterval)
        {
            timePrecElapsed = timeElapsed;
            maj_map(tile0Sprite,direction);
        }
        for (int Ytile0 = 0; Ytile0 < TAILLEMAP_Y ; ++ Ytile0) // index
        {
            for (int Xtile0 = 0; Xtile0 < TAILLEMAP_X ; ++ Xtile0) // jndex
            {
                myWindow.draw(tile0Sprite[Ytile0][Xtile0]);
            }
        }
        //affichage de la nouvelle frame
        myWindow.display();
    }
//fin du programme
return 0;
}

 

Et la nouvelle tuile ci jointe

Voila essayez de déplacer dans toutes les directions la map (8 au total) avec les flèches. Dite moi si ça scintille chez vous.

Cordialement

TrucMuche

  • Newbie
  • *
  • Messages: 11
    • Voir le profil
    • E-mail
Re: tileMap Sprite Positionnement et Scintillement
« Réponse #4 le: Février 20, 2020, 08:09:31 pm »
C'est encore moi  ::)

Je suis parvenu à exploiter le tuto de la SFML concernant le tile map. Je l'ai réadapté pour mon tile map isométrique.

 Il fonctionne, voici le code :

//directive de préprocesseur

//systeme windows
#include <windows.h>

//Standard
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>

//SFML
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>

//obtention de la taille de l'écran utilisateur en pixel.
int const SCREEN_X = GetSystemMetrics(SM_CXSCREEN);
int const SCREEN_Y = GetSystemMetrics(SM_CYSCREEN);
int const SCREEN_X_MIDDLE = SCREEN_X / 2;
int const SCREEN_Y_MIDDLE = SCREEN_Y / 2;

//Constante de la MAP
int const TAILLEMAP_X = 10, TAILLEMAP_Y = 20;
int const UP = 4, UP_RIGHT = 3, RIGHT = 2, DOWN_RIGHT = 1, DOWN = 0,DOWN_LEFT = 7,LEFT = 6,UP_LEFT = 5;



void maj_direction(bool up,bool right, bool down, bool left, int& xMove , int& yMove)
{

    int direction = -1;

    if ( up && !right && !down && !left )
        {direction = UP; xMove = 0; yMove = -1;}
    if ( up &&  right && !down && !left )
    {direction = UP_RIGHT; xMove = 1; yMove = -1;}
    if (!up &&  right && !down && !left )
    {direction = RIGHT; xMove = 1; yMove = 0;}
    if (!up &&  right &&  down && !left )
    {direction = DOWN_RIGHT; xMove = 1; yMove = 1;}
    if (!up && !right &&  down && !left )
    {direction = DOWN; xMove = 0; yMove = 1;}
    if (!up && !right &&  down &&  left )
    {direction = DOWN_LEFT; xMove = -1; yMove = 1;}
    if (!up && !right && !down &&  left )
    {direction = LEFT; xMove = -1; yMove = 0;}
    if ( up && !right && !down &&  left )
    {direction = UP_LEFT; xMove = -1; yMove = -1;}

    if ( !up && !right && !down &&  !left ){direction = -1; xMove = 0; yMove = 0;}
}

class TileMap : public sf::Drawable, public sf::Transformable
{
public:

    bool load(const std::string& tileset, sf::Vector2u tileSize, const int* tiles, unsigned int width, unsigned int height)
    {
        // on charge la texture du tileset
        if (!m_tileset.loadFromFile(tileset))
            return false;

        // on redimensionne le tableau de vertex pour qu'il puisse contenir tout le niveau
        m_vertices.setPrimitiveType(sf::Quads);
        m_vertices.resize(width * height * 4);

        int compteurAxeY = 0;
        // on remplit le tableau de vertex, avec un quad par tuile
        for (unsigned int i = 0; i < width; ++i)
        {
            compteurAxeY = 0;

            for (unsigned int j = 0; j < height; ++j)
            {
                // on récupère le numéro de tuile courant
                int tileNumber = tiles[i + j * width];

                // on en déduit sa position dans la texture du tileset
                int tu = tileNumber % (m_tileset.getSize().x / tileSize.x);
                int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);

                // on récupère un pointeur vers le quad à définir dans le tableau de vertex
                sf::Vertex* quad = &m_vertices[(i + j * width) * 4];

                // on définit ses quatre coins en fonction de :
                if (( j % 2) == 0) // si j est paire
                {
                    compteurAxeY = compteurAxeY + tileSize.y;
                    quad[0].position = sf::Vector2f( i   * tileSize.x  , compteurAxeY);
                    quad[1].position = sf::Vector2f((i+1)* tileSize.x  , compteurAxeY);
                    quad[2].position = sf::Vector2f((i+1)* tileSize.x  , compteurAxeY + tileSize.y);
                    quad[3].position = sf::Vector2f( i   * tileSize.x  , compteurAxeY + tileSize.y);

                }
                else //j impaire
                {
                    quad[0].position = sf::Vector2f( i   * tileSize.x + (tileSize.x / 2) , compteurAxeY + (tileSize.y/2) );
                    quad[1].position = sf::Vector2f((i+1)* tileSize.x + (tileSize.x / 2) , compteurAxeY + (tileSize.y/2) );
                    quad[2].position = sf::Vector2f((i+1)* tileSize.x + (tileSize.x / 2) , compteurAxeY +  tileSize.y + (tileSize.y/2) );
                    quad[3].position = sf::Vector2f( i   * tileSize.x + (tileSize.x / 2) , compteurAxeY+  tileSize.y + (tileSize.y/2) );
                }

                // on définit ses quatre coordonnées de texture
                quad[0].texCoords = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
                quad[1].texCoords = sf::Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
                quad[2].texCoords = sf::Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
                quad[3].texCoords = sf::Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
            }
        }
        return true;
    }

private:

    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        // on applique la transformation
        states.transform *= getTransform();

        // on applique la texture du tileset
        states.texture = &m_tileset;

        // et on dessine enfin le tableau de vertex
        target.draw(m_vertices, states);
    }

    sf::VertexArray m_vertices;
    sf::Texture m_tileset;
};


int main()
{
//-------------------------
//création de la fenêtre
//-------------------------
    sf::RenderWindow myWindow(sf::VideoMode(1200, 600), "testMAP");//celon taille écran
    //sf::RenderWindow myWindow(sf::VideoMode(SCREEN_X, SCREEN_Y), "BLABLA",sf::Style::Fullscreen);//plein écran
    myWindow.setVerticalSyncEnabled(false); //activation de synchronisation vertical pour meilleur affichage
    myWindow.setFramerateLimit(60);// max fps
    myWindow.setKeyRepeatEnabled(false);//Désactivation de la répétition lorsqu'une touche est maintenu appuyée.
    //Activation de l'icon de la fenêtre
    sf::Image icon;
    if(!icon.loadFromFile("icon.png"))
    {
        //error...
        std::cout << "Load of icon Failed!" <<std::endl;
        exit(EXIT_FAILURE);
    }
    myWindow.setIcon(32,32,icon.getPixelsPtr());

    //-------------------------
    // Time du jeux
    //-------------------------
    sf::Clock gameClock; //démarre le chrono
    sf::Time timeInterval = sf::milliseconds(20);;//espace de temps entre chaque mise à jours de la map
    sf::Time timeElapsed = gameClock.getElapsedTime();//enregistre le temps actuel
    sf::Time timePrecElapsed = timeElapsed;//enregistre le temps actuel précédent


    int xMove = 0 , yMove = 0; //test de déplacement de la map

        // on définit le niveau à l'aide de numéro de tuiles
    const int level[] =
    {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

        /*0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0,
        1, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3,
        0, 1, 0, 0, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 0, 0,
        0, 1, 1, 0, 3, 3, 3, 0, 0, 0, 1, 1, 1, 2, 0, 0,
        0, 0, 1, 0, 3, 0, 2, 2, 0, 0, 1, 1, 1, 1, 2, 0,
        2, 0, 1, 0, 3, 0, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1,
        0, 0, 1, 0, 3, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1,*/

    };

    // on crée la tilemap avec le niveau précédemment défini
    TileMap myMap;
    if (!myMap.load("Images/GAME/MAP/tilesetTEST_V3.png", sf::Vector2u(128, 64), level, 8, 6))
        return -1;

    sf::Texture mapFullTexture;
    mapFullTexture.loadFromFile("Images/GAME/MAP/fullTEXTURE.png");
    sf::Sprite mapSprite;
    mapSprite.setTexture(mapFullTexture);
    mapSprite.setPosition(0,0);

    bool up ,upRight, right, downRight, down, downLeft, left, upLeft;
    up = 0; upRight=0; right=0; downRight=0; down=0; downLeft=0; left=0; upLeft=0;
    int choix = 1;
    while (myWindow.isOpen() && choix == 1)
    {
        // on traite tous les évènements de la fenêtre qui ont été générés depuis la dernière itération de la boucle
        sf::Event event;
        //------------------------------
        //Gestion Clavier , joystick ...
        //------------------------------
        while (myWindow.pollEvent(event))
        {// tant qu'il y a des évènements : clavier , joystick...
            switch (event.type)
            {
                //croix fermeture fenêtre
                case sf::Event::Closed:
                    choix = 0;
                    //window.close();
                    std::cout << "fenetre fermee par [X]!" <<std::endl;
                    break;
                // n'importe quelle touche pressée
                case sf::Event::KeyPressed:
                    switch (event.key.code)
                    {
                        case sf::Keyboard::Escape:
                            choix = 0;
                            //window.close();
                            std::cout << "fenetre fermee par Escape!" <<std::endl;
                            break;
                        case sf::Keyboard::Up:
                            up = 1;
                            down = 0;
                            break;
                        case sf::Keyboard::Right:
                            right = 1;
                            left = 0;
                            break;
                        case sf::Keyboard::Down:
                            down = 1;
                            up = 0;
                            break;
                        case sf::Keyboard::Left:
                            left = 1;
                            right = 0;
                            break;
                        default:
                            choix = 0;
                            break;
                    }
                    break;
                //n'importe quelle touche relachée
                case sf::Event::KeyReleased:
                    switch (event.key.code)
                    {
                        case sf::Keyboard::Up:
                            up = 0;
                            break;
                        case sf::Keyboard::Right:
                            right = 0;
                            break;
                        case sf::Keyboard::Down:
                            down = 0;
                            break;
                        case sf::Keyboard::Left:
                            left = 0;
                            break;
                        default:
                            break;
                    }
                    break;
            }
        }


        //------------------------------
        //Mise à jour de l'affichage
        //------------------------------
        timeElapsed = gameClock.getElapsedTime();//Mise à jour du temps écoulé
        // effacement de la fenêtre en une couleur au choix
        myWindow.clear(sf::Color(255,255,150));//BLANC beige
        // c'est ici qu'on dessine tout

        // gestion affichage de la map
        maj_direction(up, right, down, left,xMove,yMove);
        if (timeElapsed >= timePrecElapsed + timeInterval)
        {
            timePrecElapsed = timeElapsed;
            myMap.move(xMove,yMove);
            //mapSprite.move(xMove,yMove);
        }

        myWindow.draw(myMap);
        //myWindow.draw(mapSprite);

        //affichage de la nouvelle frame
        myWindow.display();
    }
//fin du programme
return 0;
}
 

C'est trop propre les Classes.

Seulement voila j'ai toujours un petit kwak, plus aucun scintillement la c'est génial

myWindow.setVerticalSyncEnabled(true); // ou false
En option soit un sprite standard soit une classe fille type drawable / transformable optimisé celon le tuto.

Lorsque je change de direction up_right up_left ou down_right down_left alternativement, il y un effet désagréable sur les lignes noires des tuiles, un coup c'est la diagonale " \ " qui est lisse l'autre " / " pixélisée, puis un coup c'est l'inverse selon la direction. 

Que j'utilise la Classe optimisée ou un sprite de tuile utilisant une texture de plusieurs tuile. (si joint)

Avec mes tests je suis presque persuadé que ce n'est plus lié à la SFML.

Quelqu'un à une idée ou une piste à me donner ?
Ma tuile doit elle faire 64/128 ou 65/129 ...
Dois je abandonner les bordures de tuile et les diagonales pures 1:2 ?
Dois-je poser une autre question ? <----   ???
TOK TOK ? " c'est le début d'une blague ça ? "

Salut

TrucMuche

  • Newbie
  • *
  • Messages: 11
    • Voir le profil
    • E-mail
Re: tileMap Sprite Positionnement et Scintillement
« Réponse #5 le: Février 23, 2020, 02:40:43 pm »
Plus le resize des images en fullscreen que je n'arrive pas à désactiver ...

TrucMuche

  • Newbie
  • *
  • Messages: 11
    • Voir le profil
    • E-mail
Re: tileMap Sprite Positionnement et Scintillement
« Réponse #6 le: Février 23, 2020, 03:24:41 pm »
J'ai essayé cela :
https://fr.sfml-dev.org/forums/index.php?topic=8786.0

Mais le résultat est vraiment très moche. Mes tuiles sont aléatoirement découpées

Mon code actuel :

//directive de préprocesseur

//systeme windows
#include <windows.h>

//Standard
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>

//SFML
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>

//obtention de la taille de l'écran utilisateur en pixel.
float const SCREEN_Width = GetSystemMetrics(SM_CXSCREEN);
float const SCREEN_Height = GetSystemMetrics(SM_CYSCREEN);

int const UP = 0, UP_RIGHT = 1, RIGHT = 2, DOWN_RIGHT = 3, DOWN = 4,DOWN_LEFT = 5,LEFT = 6,UP_LEFT = 7;
void maj_direction(bool up,bool right, bool down, bool left, float& xMove , float& yMove)
{

    int direction = -1;

    if ( up && !right && !down && !left )//up
        {direction = UP;            xMove = 0;      yMove = -4;}
    if ( up &&  right && !down && !left )//up right
        {direction = UP_RIGHT;      xMove = 4;      yMove = -2;}
    if (!up &&  right && !down && !left )//right
        {direction = RIGHT;         xMove = 4;      yMove = 0;}
    if (!up &&  right &&  down && !left )//down right
        {direction = DOWN_RIGHT;    xMove = 4;      yMove = 2;}
    if (!up && !right &&  down && !left )//down
        {direction = DOWN;          xMove = 0;      yMove = 4;}
    if (!up && !right &&  down &&  left )//down left
        {direction = DOWN_LEFT;     xMove = -4;     yMove = 2;}
    if (!up && !right && !down &&  left )// left
        {direction = LEFT;          xMove = -4;     yMove = 0;}
    if ( up && !right && !down &&  left )// up left
        {direction = UP_LEFT;       xMove = -4;     yMove = -2;}

    if ( !up && !right && !down &&  !left ){direction = -1; xMove = 0; yMove = 0;}
}


class TileMap : public sf::Drawable, public sf::Transformable
{
public:

    bool load(const std::string& tileset, sf::Vector2u tileSize, const int* tiles, unsigned int width, unsigned int height)
    {
        // on charge la texture du tileset
        if (!m_tileset.loadFromFile(tileset))
            return false;

        // on redimensionne le tableau de vertex pour qu'il puisse contenir tout le niveau
        m_vertices.setPrimitiveType(sf::Quads);
        m_vertices.resize(width * height * 4);

        int compteurAxeY = 0;
        // on remplit le tableau de vertex, avec un quad par tuile
        for (unsigned int i = 0; i < width; ++i)
        {
            compteurAxeY = 0;

            for (unsigned int j = 0; j < height; ++j)
            {
                // on récupère le numéro de tuile courant
                int tileNumber = tiles[i + j * width];

                // on en déduit sa position dans la texture du tileset
                int tu = tileNumber % (m_tileset.getSize().x / tileSize.x);
                int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);

                // on récupère un pointeur vers le quad à définir dans le tableau de vertex
                sf::Vertex* quad = &m_vertices[(i + j * width) * 4];

                // on définit ses quatre coins en fonction de :
                if (( j % 2) == 0) // si j est paire
                {
                    compteurAxeY = compteurAxeY + tileSize.y;
                    quad[0].position = sf::Vector2f( i   * tileSize.x  , compteurAxeY);
                    quad[1].position = sf::Vector2f((i+1)* tileSize.x  , compteurAxeY);
                    quad[2].position = sf::Vector2f((i+1)* tileSize.x  , compteurAxeY + tileSize.y);
                    quad[3].position = sf::Vector2f( i   * tileSize.x  , compteurAxeY + tileSize.y);

                }
                else //j impaire
                {
                    quad[0].position = sf::Vector2f( i   * tileSize.x + (tileSize.x / 2) , compteurAxeY + (tileSize.y/2) );
                    quad[1].position = sf::Vector2f((i+1)* tileSize.x + (tileSize.x / 2) , compteurAxeY + (tileSize.y/2) );
                    quad[2].position = sf::Vector2f((i+1)* tileSize.x + (tileSize.x / 2) , compteurAxeY +  tileSize.y + (tileSize.y/2) );
                    quad[3].position = sf::Vector2f( i   * tileSize.x + (tileSize.x / 2) , compteurAxeY+  tileSize.y + (tileSize.y/2) );
                }

                // on définit ses quatre coordonnées de texture
                quad[0].texCoords = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
                quad[1].texCoords = sf::Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
                quad[2].texCoords = sf::Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
                quad[3].texCoords = sf::Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
            }
        }
        return true;
    }

private:

    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        // on applique la transformation
        states.transform *= getTransform();

        // on applique la texture du tileset
        states.texture = &m_tileset;

        // et on dessine enfin le tableau de vertex
        target.draw(m_vertices, states);
    }

    sf::VertexArray m_vertices;
    sf::Texture m_tileset;
};


int main()
{
//-------------------------
//création de la fenêtre
//-------------------------
    sf::RenderWindow myWindow(sf::VideoMode(0,0), "World",sf::Style::Fullscreen );
    //sf::RenderWindow myWindow((sf::VideoMode::GetMode(0)); //can't use this instruction because GetMode is not a member of sf::VideoMode !!!!!!!?
    myWindow.setVerticalSyncEnabled(true); //activation de synchronisation vertical pour meilleur affichage
    myWindow.setFramerateLimit(60);//max fps
    myWindow.setKeyRepeatEnabled(false);//Désactivation de la répétition lorsqu'une touche est maintenu appuyée.

    //Activation de l'icon de la fenêtre // set a icon
    sf::Image icon;
    if(!icon.loadFromFile("icon.png")){std::cout << "Load of icon Failed!" <<std::endl;}
    myWindow.setIcon(32,32,icon.getPixelsPtr());

    // création d'une vue à partir de ( sa position centrale , et de sa taille )
    //sf::View gameView(sf::Vector2f(800.f, 600.f), sf::Vector2f(1200.f, 600.f));
    //float event_ResizedWidth = 1.f;
    //float event_ResizedHeight = 1.f;
    //sf::FloatRect visibleArea(0.f, 0.f,event_ResizedWidth,event_ResizedHeight);
    //gameView.setViewport(visibleArea);
    sf::View gameView;
    gameView.setSize(SCREEN_Width,SCREEN_Height);
    gameView.setCenter( (SCREEN_Width/2) , (SCREEN_Height/2) );

    // Déterminer s'il faut des bandes horizontales ou verticales
    float largeur_image = 1200;
    float hauteur_image = 600;
    if (SCREEN_Width/SCREEN_Height < hauteur_image/largeur_image)// Fenêtre plus large que l'image (relativement à leur hauteur)
    {
        // Bandes à-gauche et à-droite
        // Définir la proportion entre le "input" et le "output" de "view_1" pour que le haut et le bas correspondent
        gameView.zoom(hauteur_image/SCREEN_Height);
        // Ne représenter que la zone "input" (et pas un élément extérieur pouvant par-exemple glisser dedans), et la représenter au-centre de la fenêtre
        gameView.setViewport({(1-largeur_image*SCREEN_Height/hauteur_image/SCREEN_Width)/2, 0, largeur_image*SCREEN_Height/hauteur_image/SCREEN_Width, 1});
    }
    else
        // Fenêtre plus haute que l'image (relativement à leur largeur), ou formats équivalents
        // Bandes en-haut et en-bas
    {   // Définir la proportion entre le "input" et le "output" de "view_1" pour que la gauche et la droite correspondent
        gameView.zoom(largeur_image/SCREEN_Width);
        // Ne représenter que la zone "input" (et pas un élément extérieur pouvant par-exemple glisser dedans), et la représenter au-centre de la fenêtre
        gameView.setViewport({0, (1-hauteur_image*SCREEN_Width/largeur_image/SCREEN_Height)/2, 1, hauteur_image*SCREEN_Width/largeur_image/SCREEN_Height});
    }


    // Attribuer "view_1" à "RenderWindow_1"; je crois qu'il n'y a pas besoin de le refaire en cas de modification de "view_1", mais il faudrait vérifier
    //RenderWindow_1.setView(View_1);

    //-------------------------
    // horloge du jeux // game timer
    //-------------------------
    sf::Clock gameClock; //démarre le chrono
    sf::Time timeInterval = sf::milliseconds(15);//espace de temps entre chaque mise à jours de la map
    sf::Time timeElapsed = gameClock.getElapsedTime();//enregistre le temps actuel
    sf::Time timePrecElapsed = timeElapsed;//enregistre le temps actuel précédent

    // variable pour déplacement de la map // variable for move the map
    float xMove = 0 , yMove = 0;

    // on définit le niveau à l'aide de numéro de tuiles // define the level with tiles numbers
    const int level[] =
    {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,//3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

        /*0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0,
        1, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3,
        0, 1, 0, 0, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 0, 0,
        0, 1, 1, 0, 3, 3, 3, 0, 0, 0, 1, 1, 1, 2, 0, 0,
        0, 0, 1, 0, 3, 0, 2, 2, 0, 0, 1, 1, 1, 1, 2, 0,
        2, 0, 1, 0, 3, 0, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1,
        0, 0, 1, 0, 3, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1,*/

    };

    // on crée la tilemap avec le niveau précédemment défini
    TileMap myMap;
    if (!myMap.load("Images/GAME/MAP/tileset.png", sf::Vector2u(128, 64), level, 16, 32))
    {
        //error...
        std::cout << "Load of tileset Failed!" <<std::endl;
        exit(EXIT_FAILURE);
        //return -1;
    }

    bool up ,upRight, right, downRight, down, downLeft, left, upLeft;
    up = 0; upRight=0; right=0; downRight=0; down=0; downLeft=0; left=0; upLeft=0;
    int choix = 1;
    while (myWindow.isOpen() && choix == 1)
    {
        // on traite tous les évènements de la fenêtre qui ont été générés depuis la dernière itération de la boucle
        sf::Event event;
        //------------------------------
        //Gestion Clavier , joystick ...
        //------------------------------
        while (myWindow.pollEvent(event))
        {// tant qu'il y a des évènements : clavier , joystick...
            switch (event.type)
            {
                //croix fermeture fenêtre.
                case sf::Event::Closed:
                    choix = 0;
                    //window.close();
                    std::cout << "fenetre fermee par [X]!" <<std::endl;
                    break;
                // n'importe quelle touche pressée
                case sf::Event::KeyPressed:
                    switch (event.key.code)
                    {
                        case sf::Keyboard::Escape:
                            choix = 0;
                            //window.close();
                            std::cout << "fenetre fermee par Escape!" <<std::endl;
                            break;
                        case sf::Keyboard::Up:
                            up = 1;
                            down = 0;
                            break;
                        case sf::Keyboard::Right:
                            right = 1;
                            left = 0;
                            break;
                        case sf::Keyboard::Down:
                            down = 1;
                            up = 0;
                            break;
                        case sf::Keyboard::Left:
                            left = 1;
                            right = 0;
                            break;
                        default:
                            break;
                    }
                    break;
                //n'importe quelle touche relachée
                case sf::Event::KeyReleased:
                    switch (event.key.code)
                    {
                        case sf::Keyboard::Up:
                            up = 0;
                            break;
                        case sf::Keyboard::Right:
                            right = 0;
                            break;
                        case sf::Keyboard::Down:
                            down = 0;
                            break;
                        case sf::Keyboard::Left:
                            left = 0;
                            break;
                        default:
                            break;
                    }
                    break;
            }
        }

        //------------------------------
        //Mise à jour de l'affichage
        //------------------------------
        // effacement de la fenêtre en une couleur au choix
        myWindow.clear(sf::Color(0,0,0));//BLACK

        myWindow.setView(gameView);

        //déplacement de la View
        timeElapsed = gameClock.getElapsedTime();//Mise à jour du temps écoulé
        if (timeElapsed >= timePrecElapsed + timeInterval)
        {
            maj_direction(up, right, down, left,xMove,yMove);
            timePrecElapsed = timeElapsed;
            // déplacement de la vue
            gameView.move(xMove, yMove);
        }
        myWindow.draw(myMap);

        //réactivation de la vue par défaut wh
        //myWindow.setView(myWindow.getDefaultView());

        //affichage de la nouvelle frame
        myWindow.display();
    }
//fin du programme
return 0;
}

Biensur j'ai éssayé le tuto sur les view https://www.sfml-dev.org/tutorials/2.5/graphics-view-fr.php
J'ai fait fonctionner "Affichée plus lorsque la fenêtre est redimentionnée" ça a fonctionné mais je ne pouvais plus déplacer la vue. Puis je souhaite être en plein écran.

Comment être en fullScreen sans redimentionner quoi que ce soit, mise à part la fenêtre ?
« Modifié: Février 23, 2020, 03:31:26 pm par TrucMuche »

 

anything