-
When creating a row of sf::ConvexShapes from data in a .txt file, there is a slight gap between each shape. If I create each shape with the same data inside the code itself, then there is no gap formed.
std::ifstream fin;
std::string str("levels/level" + std::to_string(levelNumber) + ".txt");
fin.open(str);
int yCounter = 0; //incr whenever file reads /n
if(fin.good()){
while(!fin.eof()){
std::string line;
//this happens once per line, so whenever the while statement breaks, that means incr yCounter
while(std::getline(fin, line)){
int xCounter = 0; //incr for each char, reset per line
for(int i = 0; i < line.length(); i++){
if(line[i] == 'w'){
AddWall(xCounter, yCounter, tileSize);
}
xCounter++;
}
yCounter++;
}
}
}
void AddWall(int posX, int posY, int tileSize){
objects.push_back(new Platform(posX, posY, tileSize));
}
Platform::Platform(int posX, int posY, int tileSize){
shape.setPointCount(4);
shape.setPoint(0, sf::Vector2f(posX, posY));
shape.setPoint(1, sf::Vector2f(posX, posY + tileSize));
shape.setPoint(2, sf::Vector2f(posX + tileSize, posY + tileSize));
shape.setPoint(3, sf::Vector2f(posX + tileSize, posY));
shape.setFillColor(sf::Color::White);
shape.setPosition(posX * tileSize, posY * tileSize);
}
A screenshot of the gap is included. I know I can just add outlines to the shapes to solve this, but why is the problem happening in the first place?
-
It looks like your positions might be non-integer so try rounding them to see if that fixes your problem.
Rather than have two variables with exactly the same value, why not just use xCounter as the loop control variable?
i.e.
for (int xCounter = 0; xCounter < line.length(); ++xCounter)
-
while(!fin.eof()){
while (!eof) is an anti-idiom. (http://stackoverflow.com/questions/5431941/)
And you're nesting 3 (!) loops/branches that check for the validity of the same stream. One is enough, namely the most inner one. Also, for loops exist for a reason ;)
Furthermore, try to avoid new/delete, there are better alternatives in C++ (http://www.bromeon.ch/articles/raii.html).
-
Well, thanks for the coding tips, it all is slightly more optimized now. But the gaps between the shapes remain. And it has nothing to do with the file that I'm reading from, because even if I create side by side shapes by hardcoding in their positions, the gap is still there. Any other suggestions?
AddWall(0, 0, tileSize);
AddWall(1, 0, tileSize);
(two side by side shapes, but there is still a 1 pixel wide gap)
-
If I create each shape with the same data inside the code itself, then there is no gap formed
even if I create side by side shapes by hardcoding in their positions, the gap is still there
I think you'll have to clarify the situation... ;)
-
Well, thanks for the coding tips, it all is slightly more optimized now.
Did you try rounding off co-ordinates?
there is still a 1 pixel wide gap
In your screenshot, all of the gaps are not equal.
Are you using a view?
Are you resizing the window?
-
It looks like your positions might be non-integer so try rounding them to see if that fixes your problem.
The debugger showed that they are integer positions; nevertheless, rounding them, ceiling, or flooring them did not change the nature of the gaps a bit.
Are you using a view?
I am using a view. I'll show how I'm implementing it:
class WorldObject{
//...
sf::Drawable &GetDrawable(){
return shape;
}
};
class Level{
//...
public:
void SetActive(std::vector<WorldObject*> &permObjects, int levelNumber, int tileSize){
//other code not relevant to the objects vector
//parse given level file for all relevant startup info
std::ifstream fin;
std::string str("levels/level" + std::to_string(levelNumber) + ".txt");
fin.open(str);
int yCounter = 0; //incr whenever file reads /n
std::string line;
while(std::getline(fin, line)){
for(int xCounter = 0; xCounter < line.length(); xCounter++){
if(line[xCounter] == 'w'){
AddWall(xCounter, yCounter, tileSize);
}
}
yCounter++;
}
fin.close();
}
std::vector<WorldObject*> &GetLevelObjects(){
return objects;
}
private:
std::vector<WorldObject*> objects;
};
class Board{
public:
//...
void MoveCameraCenter(float offsetX, float offsetY){
cameraCenter += sf::Vector2f(offsetX, offsetY);
}
std::vector<WorldObject*> &GetObjects(){
return activeLevel.GetLevelObjects();
}
sf::View GetCamera(){
sf::View camera;
camera.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
camera.setCenter(cameraCenter);
return camera;
}
private:
sf::Vector2f cameraCenter;
};
class Engine{
private:
Board board;
//the view isn't called for until Render()
void Engine::Render(){
window.setView(board.GetCamera());
window.clear();
for(unsigned i = 0; i < board.GetObjects().size(); i++){
window.draw(board.GetObjects()[i]->GetDrawable());
}
window.display();
}
};
That should be all the relevant code, but if you need anything else let me know
-
I am using a view.
sf::View camera;
camera.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
That should be all the relevant code, but if you need anything else let me know
What is SCREEN_WIDTH and SCREEN_HEIGHT?
-
What is SCREEN_WIDTH and SCREEN_HEIGHT?
Ah, forgot about those. They're just constant integers, available to all classes, set at 1280 and 720 respectively.
-
Well this is a little embarrassing. In Platform's constructor,
Platform(int posX, int posY, int tileSize){
//shape.setPosition(posX * tileSize, posY * tileSize);
shape.setPointCount(4);
shape.setPoint(0, sf::Vector2f(posX + tileSize, posY));
shape.setPoint(1, sf::Vector2f(posX, posY));
shape.setPoint(2, sf::Vector2f(posX, posY + tileSize));
shape.setPoint(3, sf::Vector2f(posX + tileSize, posY + tileSize));
shape.setFillColor(sf::Color::White);
}
The setPosition function was messing with the shapes' positions (yes that's redundant). I commented that out and the gap went away.