Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Simple Isometric tileMAP but ugly result  (Read 1704 times)

0 Members and 1 Guest are viewing this topic.

TrucMuche

  • Newbie
  • *
  • Posts: 11
    • View Profile
    • Email
Simple Isometric tileMAP but ugly result
« on: February 22, 2020, 01:13:04 pm »
Hello ...i'm french, sorry but nobody answers for 2 weeks on french forum.

I make a tilemap with the SFML Tutorial https://www.sfml-dev.org/tutorials/2.5/graphics-vertex-array.php. (version française)

I want to make an isometric tileMAP. The code work for me, but when i move the map there are an ugly result.

In game we can move in heigt directions.

The idle, left and right make a good result.
The others directions (up, down, down+left, up+right ...) change the color of the border of tiles in black to grey.

I sink it's a visual effect and not a color change.

I try to change VerticalSyncEnabled , setFramerateLimit , sf::Time timeInterval = sf::milliseconds(20);,  but no good result.

the code :


//systeme windows
#include <windows.h>

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

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


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;

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)
    {
        // load of tileset texture
        if (!m_tileset.loadFromFile(tileset))
            return false;

        // resize the vertex board because about the level size
        m_vertices.setPrimitiveType(sf::Quads);
        m_vertices.resize(width * height * 4);

        int compteurAxeY = 0;
        // filled the vertex board with a quad per tile
        for (unsigned int i = 0; i < width; ++i)
        {
            compteurAxeY = 0;

            for (unsigned int j = 0; j < height; ++j)
            {
                // find the number of the current tile
                int tileNumber = tiles[i + j * width];

                // find the position on the texture tileset
                int tu = tileNumber % (m_tileset.getSize().x / tileSize.x);
                int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);

                // find a pointor to the quad at defined on the vertex board
                sf::Vertex* quad = &m_vertices[(i + j * width) * 4];

                // defined this fore corners depending on:
                if (( j % 2) == 0) // j is even
                {
                    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 is odd   .... ahah "odd"world -> i enderstand now.
                {
                    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) );
                }

                // defined the fore texture coordinates
                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
    {
        // make the transform
        states.transform *= getTransform();

        // painting the texture of tileset
        states.texture = &m_tileset;

        // drawing the vertex board
        target.draw(m_vertices, states);
    }

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


int main()
{
//-------------------------
//make a windows window
//-------------------------
    sf::RenderWindow myWindow(sf::VideoMode(1200, 600), "testMAP");
    //sf::RenderWindow myWindow(sf::VideoMode(SCREEN_X, SCREEN_Y), "BLABLA",sf::Style::Fullscreen);
    myWindow.setVerticalSyncEnabled(true);
    myWindow.setFramerateLimit(90);
    myWindow.setKeyRepeatEnabled(false);

    //Set an icon window
    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 of the game
    //-------------------------
    sf::Clock gameClock; //start the time
    sf::Time timeInterval = sf::milliseconds(10);//interval between each move of the map
    sf::Time timeElapsed = gameClock.getElapsedTime();save the actual time
    sf::Time timePrecElapsed = timeElapsed; save the previous time


    int xMove = 0 , yMove = 0; //move of the map

        // defined the level...
    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,*/

    };

    // make a tile map
    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;
        //------------------------------
        // 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;
            }
        }



        timeElapsed = gameClock.getElapsedTime();//Mise à jour du temps écoulé
       
        myWindow.clear(sf::Color(255,255,150));//BLANC beige
        // drawing here

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

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

        //display !
        myWindow.display();
    }
//end of the end
return 0;
}
 

I join the tile and a test with full map texture sprite.

S.O.S, Can you help me ?  ;D


TrucMuche

  • Newbie
  • *
  • Posts: 11
    • View Profile
    • Email
Re: Simple Isometric tileMAP but ugly result
« Reply #1 on: February 23, 2020, 02:41:49 pm »
Plus the auto resize in fullScreen who change my pictures size :'(.

Mortal

  • Sr. Member
  • ****
  • Posts: 284
    • View Profile
Re: Simple Isometric tileMAP but ugly result
« Reply #2 on: February 23, 2020, 05:32:39 pm »
i had similar problem with this, it turns out that it is happened due to float point precision problem.

i have solved it here in this link: https://en.sfml-dev.org/forums/index.php?topic=21048.msg150470#msg150470

TrucMuche

  • Newbie
  • *
  • Posts: 11
    • View Profile
    • Email
Re: Simple Isometric tileMAP but ugly result
« Reply #3 on: February 27, 2020, 10:32:11 am »
Hi, senk you,

If i understand the probleme could come from my texture.

A texture tile set is better if there are a space between each tiles ?
but in my test i had juste one tile and one texture. The pixels should not touch any edges ?

betweentime i tried to use an other type of tile texture (who don't respect my previous questions).
 i fixed my reisizing bug using  sf::View. i also have change the game design...

i join my new texture tile set, i can see the ugly result if i force on my sight or if the view move very fast.

 

anything