SFML community forums

Help => Graphics => Topic started by: wh1t3crayon on November 24, 2015, 10:04:06 pm

Title: Why is there a slight gap between my sf::ConvexShapes?
Post by: wh1t3crayon on November 24, 2015, 10:04:06 pm
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?
Title: Re: Why is there a slight gap between my sf::ConvexShapes?
Post by: Hapax on November 25, 2015, 03:48:53 am
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)
Title: Re: Why is there a slight gap between my sf::ConvexShapes?
Post by: Nexus on November 25, 2015, 01:50:02 pm
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).
Title: Re: Why is there a slight gap between my sf::ConvexShapes?
Post by: wh1t3crayon on November 30, 2015, 02:20:00 pm
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)
Title: Re: Why is there a slight gap between my sf::ConvexShapes?
Post by: Laurent on November 30, 2015, 04:09:53 pm
Quote
If I create each shape with the same data inside the code itself, then there is no gap formed
Quote
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... ;)
Title: Re: Why is there a slight gap between my sf::ConvexShapes?
Post by: Hapax on November 30, 2015, 05:07:38 pm
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?
Title: Re: Why is there a slight gap between my sf::ConvexShapes?
Post by: wh1t3crayon on November 30, 2015, 07:42:17 pm
Quote
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.
Quote
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
Title: Re: Why is there a slight gap between my sf::ConvexShapes?
Post by: Hapax on November 30, 2015, 11:44:58 pm
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?
Title: Re: Why is there a slight gap between my sf::ConvexShapes?
Post by: wh1t3crayon on December 01, 2015, 03:27:43 am
Quote
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.
Title: Re: Why is there a slight gap between my sf::ConvexShapes?
Post by: wh1t3crayon on December 01, 2015, 03:47:42 am
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.