I'm kinda embarrassed about it but I need help.
Since my last post I have been reading a ton on how to draw only the tiles that are visible, but I only got confused about if thats even possible.
This is my "tile manager", is the one from the tutorial with 2 changes.
#pragma once
#include <iostream>
#include <SFML\Graphics.hpp>
class TileMap : public sf::Drawable, public sf::Transformable
{
public:
bool load(const std::string& tileset, sf::Vector2u tileSize, std::vector<std::vector<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.clear(); //wasnt originally here
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) // 20
for (unsigned int j = 0; j < height; ++j) // 30
{
// get the current tile number
//int tileNumber = tiles[i + j * width][7]; // 0 25 50.... reads the vector from top to bot, then moves to column 2 then 3....
int tileNumber = tiles[j][i]; // 0 25 50.... reads the vector from top to bot, then moves to column 2 then 3....
if (tileNumber == 0) // so 0 = no texture.
continue; //skips giving texture to this quad vertice.
else
tileNumber--;
// 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;
};
Changed from receiving "const int" to "std::vector<std::vector<int>>"
I added the m_vertices.clear() so when I change maps the old don't stay on screen.
and added
if (tileNumber == 0) // so 0 = no texture.
continue; //skips giving texture to this quad vertice.
else
tileNumber--;
So when the tile is 0 it doesn't show anything. (I'm not sure if I should be doing this, but thats a question for another day)
This is how I load the level:
map.load("Assets/tileSet2.png", sf::Vector2u(32, 32), _currentLevel, 30, 20);
This is how I draw the tilemap:
window.draw(map);
As you can see my map is 30x20.
My view is 15x10.
I want to draw only 16x11.
is that possible the way I have things set up?
What I was doing was, instead of loading the full map (30x20), i was loading only the 16x11, and update it it when i need the next tile. Since that is wrong, I don't know how to do it.
I read when you draw a vertex array it always fully draws, there is no way to draw only part of it. then read SFML doesn't render whats outside the view anyway. But I also saw in so many topics that rendering only the visible tiles its the correct way, so I'm just confused now.
I'm probably mixing concepts again. If anyone can help, i would appreciate it.