#include <SFML/Graphics.hpp>
#include <iostream>
#include <ctime>
class Map : public sf::Drawable, sf::Transformable
{
public:
Map() { tileset_texture.loadFromFile("tilesets/tileset_01.png"); loadTileMap(); }
void loadTileMap();
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
states.transform *= getTransform();
states.texture = &tileset_texture;
target.draw(tilemap, states);
}
private:
sf::VertexArray tilemap;
sf::Texture tileset_texture;
sf::RenderTexture render_texture;
sf::RenderStates states;
};
void Map::loadTileMap()
{
std::vector<int> tiles = { 1, 2, 3, 4, 8, 3, 3, 3, 4, 3, 1, 1,1, 1 ,1, 2, 2, 2, 2, 2,
1, 2, 135, 135, 135, 135, 3, 3, 4, 3, 4, 1,1, 1 ,1, 2, 2, 2, 2, 2,
1, 2, 198, 199, 200, 3, 3, 3, 4, 3, 4, 1,1, 1 ,1, 2, 2, 2, 2, 2,
1, 2, 277, 278, 277, 278, 3, 3, 4, 3, 4, 1,1, 1 ,1, 2, 2, 2, 2, 2,
1, 2, 3, 4, 3, 3, 3, 3, 4, 3, 4, 3,3, 3 ,3, 2, 2, 2, 2, 2,
1, 2, 3, 4, 3, 3, 3, 3, 4, 3, 4, 3,3, 3 ,3, 2, 2, 2, 2, 2,
10, 10, 10, 10, 10, 3, 3, 3, 4, 3, 4, 1,1, 1 ,1, 2, 2, 2, 2, 2,
1, 2, 6, 6, 6, 6, 3, 3, 4, 3, 4, 1,1, 1 ,1, 2, 2, 2, 2, 2,
1, 67, 67, 67, 67, 3, 3, 3, 4, 3, 4, 1,1, 1 ,1, 2, 2, 2, 2, 2,
1, 2, 11, 11, 11, 11, 3, 3, 4, 3, 4, 1,1, 1 ,1, 2, 2, 2, 2, 2,
1, 2, 3, 4, 3, 3, 3, 3, 4, 3, 4, 1,1, 1 ,1, 2, 2, 2, 2, 2,
1, 2, 3, 4, 3, 3, 3, 3, 4, 3, 4, 1,1, 1 ,1, 2, 2, 2, 2, 2 };
unsigned int width = 21;
unsigned int height = 12;
sf::Vector2u tileSize(16, 16);
tilemap.setPrimitiveType(sf::Quads);
tilemap.resize(width * height * 4); // Each tile have 4 vertex
for (unsigned int i = 0; i < width; ++i)
for (unsigned int j = 0; j < height; ++j)
{
// get the current tile number
int tileNumber = tiles[i + j * width];
// find its position in the tileset texture
int tu = tileNumber % (tileset_texture.getSize().x / 16);
int tv = tileNumber / (tileset_texture.getSize().x / 16);
// get a pointer to the current tile's quad
sf::Vertex* quad = &tilemap[(i + j * width) * 4];
// define its 4 corners
quad[0].position = sf::Vector2f(i * tileSize.x, j * tileSize.y);
quad[1].position = sf::Vector2f((i + 1) * tileSize.x, j * tileSize.y);
quad[2].position = sf::Vector2f((i + 1) * tileSize.x, (j + 1) * tileSize.y);
quad[3].position = sf::Vector2f(i * tileSize.x, (j + 1) * tileSize.y);
// define its 4 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);
}
}
class Level
{
public:
Level() { rectangle.setFillColor(sf::Color::Blue); rectangle.setSize(sf::Vector2f(30, 30)); }
void render(sf::RenderWindow &c_window) { c_window.draw(map); c_window.draw(rectangle); }
private:
sf::RectangleShape rectangle;
Map map;
};
class GameApp
{
public:
GameApp() : window(sf::VideoMode(800, 600), "SFML Graphic test", sf::Style::Fullscreen) { window.setVerticalSyncEnabled(true); view.setSize(200, 150); view.setCenter(100, 75); window.setView(view); }
sf::Clock clock;
sf::Time frame_time;
void run()
{
while (!sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
{
frame_time = clock.restart();
frame_time += clock.getElapsedTime();
while (frame_time.asSeconds() < 1.f / FPS)
{
frame_time += clock.getElapsedTime();
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) view.move(1, 0);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) view.move(-1, 0);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) view.move(0, -1);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) view.move(0, 1);
window.setView(view);
render();
}
}
void render() { window.clear(); level.render(window); window.display(); }
private:
sf::RenderWindow window;
Level level;
sf::View view;
const float FPS = 60.f;
};
int main()
{
GameApp game_app;
game_app.run();
return 0;
}
Another issue is that my pc screen works at 30 hz interlazed by default and only looks ok when changing to 50 or 60hz not interlazed. The game run at 60Hz. I thought that this was managed by sfml. Other games works in all frequencies.
¿I will need another library to detect the frecuencies of the screen and change it?