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 ?