-
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;
}
}
}
-
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.
-
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.
-
Minimal and complete example (http://en.sfml-dev.org/forums/index.php?topic=5559.msg36368#msg36368), right from the forum rules.
-
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?
-
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();
}
}
-
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.
-
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?
-
What do you do, when you resize your window?
-
What do you do, when you resize your window?
I dragged the corner of the window. Nothing else.
-
So you don't handle that event in your code?
-
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.
-
I'm not sure, but I would say that resizing the windows does not resize the "video mode".
-
So how can I resize the "video mode"?
-
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 ;).
-
Thanks!
Now it work just fine!