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 the tileset texture
if (!m_tileset.loadFromFile(tileset))
return false;
// resize the vertex array to fit the level size
m_vertices.setPrimitiveType(sf::Quads);
m_vertices.resize(width * height * 4);
// populate the vertex array, with one quad per tile
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 % (m_tileset.getSize().x / tileSize.x);
int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);
// get a pointer to the current tile's quad
sf::Vertex* quad = &m_vertices[(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);
}
return true;
}
private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
// apply the transform
states.transform *= getTransform();
// apply the tileset texture
states.texture = &m_tileset;
// draw the vertex array
target.draw(m_vertices, states);
}
sf::VertexArray m_vertices;
sf::Texture m_tileset;
};
int main()
{
// create the window
sf::RenderWindow window(sf::VideoMode(512, 256), "Tilemap");
// define the level with an array of tile indices
const int level[] =
{
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, 2, 2, 2, 2, 1, 1, 1, 1,
0, 1, 0, 0, 2, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,
0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 2, 0, 0,
0, 0, 1, 0, 1, 0, 2, 2, 0, 0, 1, 1, 1, 1, 2, 0,
2, 0, 1, 0, 1, 0, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1,
0, 0, 1, 0, 1, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1,
};
// create the tilemap from the level definition
TileMap map;
if (!map.load("spritesheet.png", sf::Vector2u(32, 32), level, 16, 8))
return -1;
// run the main loop
while (window.isOpen())
{
// handle events
sf::Event event;
while (window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
}
// draw the map
window.clear();
window.draw(map);
window.display();
}
return 0;
}
You can go ahead and use the tilemap I supplied in the first post.
Thanks!
Ok I just tested the sample version again, and I don't get the lines. So that leaves me to conclude that something about how I'm using my views is causing the problem. Here's the relevant code in my player's view:
Player.cpp:
Player::Player(const std::string& id, bool active) :
m_viewArea(sf::Vector2f(100, 100))
{
m_texture.loadFromFile("Resources/player.png");
m_sprite.setTexture(m_texture);
m_sprite.setPosition(350, 300);
registerAttribute("renderable", new bool(true));
registerAttribute("health", new int(20));
SceneManager::getView().setCenter(m_sprite.getPosition());
SceneManager::getView().setSize(m_viewArea);
}
bool Player::nextPosValid(const sf::Vector2f& offset)
{
sf::Vector2f offsettedPos(m_sprite.getPosition().x + offset.x, m_sprite.getPosition().y + offset.y);
//The bounding rectangle of the future player
sf::FloatRect rect(offsettedPos, sf::Vector2f(m_sprite.getGlobalBounds().width, m_sprite.getGlobalBounds().height));
if (SceneManager::getWorld().getCurrentCell()->getTileMap().collidesWithType(2, rect))
return false;
return true;
}
void Player::move(const sf::Vector2f& offset)
{
m_sprite.move(offset);
SceneManager::getView().setCenter(m_sprite.getPosition());
}
void Player::update(sf::Time dt)
{
if (InputManager::isActive(User_Input::UPHOLD))
{
if (nextPosValid(sf::Vector2f(0, -100 * dt.asSeconds())))
move(sf::Vector2f(0, -100 * dt.asSeconds()));
}
if (InputManager::isActive(User_Input::LEFTHOLD))
{
if (nextPosValid(sf::Vector2f(-100 * dt.asSeconds(), 0)))
move(sf::Vector2f(-100 * dt.asSeconds(), 0));
}
if (InputManager::isActive(User_Input::DOWNHOLD))
{
if (nextPosValid(sf::Vector2f(0, 100 * dt.asSeconds())))
move(sf::Vector2f(0, 100 * dt.asSeconds()));
}
if (InputManager::isActive(User_Input::RIGHTHOLD))
{
if (nextPosValid(sf::Vector2f(100 * dt.asSeconds(), 0)))
move(sf::Vector2f(100 * dt.asSeconds(), 0));
}
if (InputManager::isActive(User_Input::PPRESS))
{
getAttribute<int>("health") -= 5;
std::cout << "Player health is now: " << getAttribute<int>("health") << std::endl;
}
if (InputManager::isActive(User_Input::VHOLD))
{
if (SceneManager::getView().getSize().x < 300 ||
SceneManager::getView().getSize().y < 300)
SceneManager::getView().setSize(sf::Vector2f(SceneManager::getView().getSize().x + 0.5, SceneManager::getView().getSize().y + 0.5));
}
else if (InputManager::isActive(User_Input::IHOLD))
{
if (SceneManager::getView().getSize().x >= 100 ||
SceneManager::getView().getSize().y >= 100)
SceneManager::getView().setSize(sf::Vector2f(SceneManager::getView().getSize().x - 0.5, SceneManager::getView().getSize().y - 0.5));
}
if (getAttribute<int>("health") <= 0)
setAttribute("renderable", new bool(false));
setPosition(m_sprite.getPosition());
setBounds(m_sprite.getGlobalBounds());
}