SFML community forums

Help => Graphics => Topic started by: Max Power on April 22, 2014, 11:11:40 pm

Title: Strange behavior when I draw a chequered design
Post by: Max Power on April 22, 2014, 11:11:40 pm
Hello,

At the moment I´m programming a chess game with sfml. But when I tried to draw a chessboard I got strange results. If the window was not a square the chessboard was wiggly.
I can´t figure out where I made the mistake and I´m searching for it for hours.
I hope you guys will find it.

And sorry for my bad english.

So heres my Code:

void Chessboard::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    sf::Vector2u wsize = target.getSize();

    //Size
    int length = (wsize.x < wsize.y) ? (wsize.x - (wsize.x % 8)) / 8 : (wsize.y - (wsize.y % 8)) / 8;

    //Offset
    int xoffset = (wsize.x - (length * 8)) / 2;
    int posx = xoffset;
    int posy = (wsize.y - (length * 8)) / 2;

    //Draw boxes
    int n = 0;
    while (n < 64)
    {

        sf::RectangleShape box(sf::Vector2f(length, length));
        box.setFillColor(boxes[n]); //sf::Color boxes[64]
        box.setPosition(posx, posy);

        //Draw box
        target.draw(box, states);

        n++;

        if (n % 8 == 0)
        {
            posx = xoffset;
            posy += length;
        }
        else
        {
            posx += length;
        }
    }
}
 
Title: Re: Strange behavior when I draw a chequered design
Post by: eXpl0it3r on April 23, 2014, 01:39:37 am
Your loop would be better off as for loop. ;)

You need to be more specific than "wiggly". That doesn't mean anything to use. Provide a screenshot and at best a minimal and complete example.
Title: Re: Strange behavior when I draw a chequered design
Post by: Max Power on April 23, 2014, 12:54:26 pm
At first I had a for loop but the first square on the board is kind of special.
If I calculate the position first it didn´t worked. So i had to calculate it after the drawing the first square.
But also I had to increment n before I calculate the new position. I would to have use flags if I had used a for loop. So I think this while loop is a little bit convenient than a for loop with flags.

What do you mean with minimal and complete example?

So here´re some screenshots:
Big Window:
(http://up.picr.de/18059164xm.jpg)

Tiny window:
(http://up.picr.de/18059165ci.jpg)

EDIT:
I found the problem with the wiggly first row:
I forgot to add the offset to posx in each new row.

I updated the code in the first post.
Title: Re: Strange behavior when I draw a chequered design
Post by: didii on April 23, 2014, 01:19:03 pm
Minimal and complete example (http://en.sfml-dev.org/forums/index.php?topic=5559.msg36368#msg36368), right from the forum rules.
Title: Re: Strange behavior when I draw a chequered design
Post by: eXpl0it3r on April 23, 2014, 01:20:44 pm
I found the problem with the wiggly first row:
I forgot to add the offset to posx in each new row.

I updated the code in the first post.
So is this solved?
Title: Re: Strange behavior when I draw a chequered design
Post by: Max Power on April 23, 2014, 09:31:46 pm
Unfortenaly it isn´t.
Ironically my code works if I the window is given since the beiginning. Even if it´s not a square.
But as soon as I resize the window it looks as shown on the images.

But here´s a minimal and complete example that produces the problem:
#include <SFML/Graphics.hpp>

int main()
{
    sf::Color boxes[64];
    bool white = true;

    for (int n = 0; n < 64; n++)
    {
        white = (n % 8) == 0 ? white : !white;
        boxes[n] = white ? sf::Color::White : sf::Color::Black;
    }

    sf::RenderWindow window(sf::VideoMode(800, 600), "Chess");

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear(sf::Color::Blue);

        //Relevant Code:
        sf::Vector2u wsize = window.getSize();

        int length = (wsize.x < wsize.y) ? (wsize.x - (wsize.x % 8)) / 8 : (wsize.y - (wsize.y % 8)) / 8;
        int offsetx = (wsize.x - (length * 8)) / 2;
        int posy = (wsize.y - (length * 8)) / 2;
        int posx = offsetx;

        int n = 0;
        while (n < 64)
        {
            sf::RectangleShape box(sf::Vector2f(length, length));
            box.setFillColor(boxes[n]);
            box.setPosition(posx, posy);
            window.draw(box);

            n++;

            if (n % 8 == 0)
            {
                posx = offsetx;
                posy += length;
            }
            else
            {
                posx += length;
            }

        }
        //Relevant Code End

        window.display();
    }
}
 
Title: Re: Strange behavior when I draw a chequered design
Post by: Hapax on April 24, 2014, 04:38:49 am
here´s a minimal and complete example that produces the problem:
[code]
If the problem was the "wiggly" part, this code doesn't produce the problem.
Title: Re: Strange behavior when I draw a chequered design
Post by: Max Power on April 24, 2014, 12:02:18 pm
I already solved the "wiggly" part. But when I resize the window there´s an another problem:
If I make it bigger, the board is "cutted". So you can´t see the whole board.
If I make it smaller, there´s a big border arround the board.

I use Code::Blocks 13.12 with MinGW and a self-compiled SFML library. May is this responsible for the problem?
Title: Re: Strange behavior when I draw a chequered design
Post by: Rhimlock on April 24, 2014, 12:46:12 pm
What do you do, when you resize your window?
Title: Re: Strange behavior when I draw a chequered design
Post by: Max Power on April 24, 2014, 01:11:57 pm
What do you do, when you resize your window?

I dragged the corner of the window. Nothing else.
Title: Re: Strange behavior when I draw a chequered design
Post by: Rhimlock on April 24, 2014, 01:13:45 pm
So you don't handle that event in your code?
Title: Re: Strange behavior when I draw a chequered design
Post by: Max Power on April 24, 2014, 01:17:02 pm
No, I don´t. Should I handle it?
I got always the correct size of the window by the target argument given in the draw function so I thought I don´t have to handle it.
Title: Re: Strange behavior when I draw a chequered design
Post by: Cirrus Minor on April 24, 2014, 01:50:08 pm
I'm not sure, but I would say that resizing the windows does not resize the "video mode".
Title: Re: Strange behavior when I draw a chequered design
Post by: Max Power on April 24, 2014, 02:02:01 pm
So how can I resize the "video mode"?
Title: Re: Strange behavior when I draw a chequered design
Post by: binary1248 on April 24, 2014, 02:41:34 pm
The problem is that you need to reset the view parameters every time you resize the window.
#include <SFML/Graphics.hpp>
#include <algorithm>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Chess");

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();

            if (event.type == sf::Event::Resized)
            {
                sf::View view = window.getView();
                view.setCenter(event.size.width / 2, event.size.height / 2);
                view.setSize(event.size.width, event.size.height);
                window.setView(view);
            }
        }

        window.clear(sf::Color::Blue);

        //Relevant Code:
        sf::Vector2u wsize = window.getSize();

        int length = std::min(wsize.x, wsize.y) / 8;
        int offsetx = (wsize.x - (length * 8)) / 2;
        int offsety = (wsize.y - (length * 8)) / 2;

        bool white = true;

        for (int row = 0; row < 8; row++)
        {
            for (int col = 0; col < 8; col++)
            {
                sf::RectangleShape box(sf::Vector2f(length, length));
                box.setFillColor(white ? sf::Color::White : sf::Color::Black);
                box.setPosition(offsetx + col * length, offsety + row * length);
                window.draw(box);
                white = !white;
            }

            white = !white;
        }
        //Relevant Code End

        window.display();
    }
}
Whenever the window is resized, the view size and center position will not change, contrary to what newcomers might expect. You need to reset them to what you expect them to be, in your case, fitting to the new window dimensions. You might wonder why it doesn't do so automatically and the answer is that if you keep drawing relative to the original window size, everything will be scaled proportionally. Something that was in the center of the screen previously will still be in the center of the screen after the resize. Since it wouldn't look so nice if the chess board wasn't a square any more, you need to manually resize the view and re-center it again every time the window changes its size.

I also cleaned up and rewrote a bit of your code because I thought it was overly complicated and hard to follow in its initial state ;).
Title: Re: Strange behavior when I draw a chequered design
Post by: Max Power on April 24, 2014, 03:41:53 pm
Thanks!
Now it work just fine!