SFML community forums
Help => Graphics => Topic started by: board_sfml on October 03, 2010, 12:01:30 pm
-
I just get started with sfml and the graphic library and tried a little program which sorts number and displays it.
the problem is that the std::vector is sorted, but the RenderWindow doesn't show it correctly.
here is a minmal program:
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <algorithm>
sf::RenderWindow App(sf::VideoMode(800, 600), "J4F");
typedef std::vector<int> fieldType;
class Field
{
std::vector<sf::Shape> m_points;
public:
// fill 'm_points'
void fill(const fieldType& field)
{
std::size_t y = 0;
for(std::size_t i = 0; i < field.size(); i++)
{
sf::Shape point(sf::Shape::Circle(0.0, 0.0, 2, sf::Color::Red));
point.SetPosition(field[i], y++);
std::cout << "x: " << point.GetPosition().x << " y: " << point.GetPosition().y << std::endl;
App.Draw(point);
App.Display();
this->m_points.push_back(point);
}
}
void sort()//bubble
{
for(std::size_t o = this->m_points.size()-1;o > 0; --o)
{
for(std::size_t pos = 0; pos < o; ++pos)
{
if(this->m_points[pos].GetPosition().x > this->m_points[pos+1].GetPosition().x)
{
sf::Vector2f tmp_pos = this->m_points[pos].GetPosition();
this->m_points[pos].SetPosition(this->m_points[pos+1].GetPosition());
this->m_points[pos+1].SetPosition(tmp_pos);
App.Display();
}
}
}
// sort&debug
for(std::size_t i = 0; i < this->m_points.size(); i++)
{
this->m_points[i].SetPosition(this->m_points[i].GetPosition().x, i);
std::cout << "x: " << this->m_points[i].GetPosition().x << " y: " << this->m_points[i].GetPosition().y << std::endl;
App.Display();
}
}
};
int main()
{
Field fieldContext;
std::vector<int> field;
for(int i = 0; i < 20; i++)
field.push_back(i);
std::random_shuffle(field.begin(), field.end());
std::cout << "Filling..." << std::endl;
fieldContext.fill(field);
std::cin.get();
std::cout << "Sorting..." << std::endl;
fieldContext.sort();
App.Display();
std::cin.get();
return 0;
}
just copy + paste and compile it. :idea:
i hope you can help me!
-
no one an idea what it could be? :(
-
Your code is a bite distubing for me. Could you show what you get and what you wanna got (or suppose to)?
-
Look at this: sorting algorithm graphic (http://www.sorting-algorithms.com/animation/20/random-initial-order/bubble-sort.gif)
I want to do this too, just with little points.
First the points look like this:
.
.
.
.
.
.
.
then if it's sorted, it should like this:
.
.
.
.
.
.
.
Do you understand?
-
Okay i get it. First of all, i don't know for you, but me i can't really make your code work (on mac) because i need the event handling on a main loop. May be this is linked to your problem. You might wanna try a main loop and handling event.
-
hey mooglwy
it also doesn't work with the eventloop.
Is it a logic problem with the sorting algorithm or did I forget something?
thank you for helping me! :oops:
-
Ok, let's make a little tutorial about how SFML is working...
App.Draw() is displaying the drawable in a buffer screen.
App.Display() invert the screen with the buffer screen, this is the Double-Buffer method. This method permits to draw somewhere without showing it on the screen and flipping buffers in order to draw to the screen very quickly.
What you app does is :
- fill
drawing a shape on the buffer, then display it, then drawing an other shape on the second buffer (being the buffer where everything is drawed now) and flipping the buffers again (only the second is drawed). The buffer is clear and you draw the third shape and display it (only the third now), etc...
- sort
simply flip the buffers
- main
simply flip the buffers again
Example of algo :
fill ()
{
for ()
{
App.Draw(); //Drawing each shape on the same buffer
}
App.Display(); //Just once a the end of filling
}
sort ()
{
//Sorting
//Drawing shapes
for ()
{
App.Draw();
}
//Displaying
App.Display();
}
What you should do : do the graphics things out of the flow of the app. The main loop must draw each frame the shapesand wait for a key in order to sort them...
-
Yep this might help, but i still can't run this code and i dont't know if it's normal.
-
Yep this might help, but i still can't run this code and i dont't know if it's normal.
Maybe you forgot to link the 3 libraries? (system,graphics,window).
Paste more infos!
If I copy my code and compile it, it works.
@Mindiell:
Thank you :D
I finally got it.
But it's not the result that I want.
Compile it and you will see that the points are going to be sorted.
But it's also flickering. I want it like this:
(http://upload.wikimedia.org/wikipedia/commons/3/37/Bubble_sort_animation.gif)
the current code is here:
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include <cstdlib>
sf::RenderWindow App(sf::VideoMode(800, 600), "J4F");
typedef std::vector<int> fieldType;
class Field
{
std::vector<sf::Shape> m_points;
public:
// fill 'm_points'
void fill(const fieldType& field)
{
std::size_t y = 0;
for(std::size_t i = 0; i < field.size(); i++)
{
sf::Shape point(sf::Shape::Circle(0.0, 0.0, 2, sf::Color::Red));
point.SetPosition(field[i], y++);
//std::cout << "x: " << point.GetPosition().x << " y: " << point.GetPosition().y << std::endl;
this->m_points.push_back(point);
App.Draw(point);
}
}
void sort()//bubble
{
for(std::size_t o = this->m_points.size()-1;o > 0; --o)
{
for(std::size_t pos = 0; pos < o; ++pos)
{
if(this->m_points[pos].GetPosition().x > this->m_points[pos+1].GetPosition().x)
{
sf::Vector2f tmp_pos = this->m_points[pos].GetPosition();
this->m_points[pos].SetPosition(this->m_points[pos+1].GetPosition());
this->m_points[pos+1].SetPosition(tmp_pos);
}
}
}
for(std::size_t i = 0; i < this->m_points.size(); i++)
{
this->m_points[i].SetPosition(this->m_points[i].GetPosition().x, i);
//std::cout << "x: " << this->m_points[i].GetPosition().x << " y: " << this->m_points[i].GetPosition().y << std::endl;
App.Display(); // bad?
sf::Sleep(0.01); // not really that what I wanted.
App.Draw(this->m_points[i]);
}
}
};
int main()
{
Field fieldContext;
std::vector<int> field;
for(int i = 0; i < 1000; i++)
field.push_back(i);
std::random_shuffle(field.begin(), field.end());
std::cout << "Filling..." << std::endl;
fieldContext.fill(field);
App.Display();
std::cin.get();
std::cout << "Sorting..." << std::endl;
fieldContext.sort();
App.Display();
std::cin.get();
return 0;
}
thanks again dude! :wink:
-
Wow, I cleaned the code a little, and separate graphic from sorting (like I said you to do) :
#include <SFML/Graphics.hpp>
#include <iostream>
class Field
{
public:
// fill 'm_points'
void fill(const std::size_t number_of_points)
{
m_sorted = false;
//Creating the points
for(std::size_t i = 0; i < number_of_points; ++i)
{
m_points.push_back(i);
}
//Shuffling it
std::random_shuffle(m_points.begin(), m_points.end());
}
//bubble sort
bool sort()
{
bool exit = false;
for(std::size_t o = this->m_points.size()-1;o > 0; --o)
{
for(std::size_t pos = 0; pos < o; ++pos)
{
if(this->m_points[pos] < this->m_points[pos+1])
{
int tmp_pos = this->m_points[pos];
this->m_points[pos] = this->m_points[pos+1];
this->m_points[pos+1] = tmp_pos;
exit = true;
}
}
if (exit)
{
return m_sorted;
}
}
m_sorted = true;
return m_sorted;
}
//bubble sort
void show_points(sf::RenderWindow& App)
{
sf::Shape point(sf::Shape::Circle(0.0, 0.0, 2, sf::Color::Red));
for(std::size_t i = 0; i < this->m_points.size(); i++)
{
point.SetPosition(i, m_points[i]);
App.Draw(point);
}
}
ivate:
std::vector<int> m_points;
bool m_sorted;
};
int main()
{
sf::RenderWindow App;
sf::Event Event;
Field fieldContext;
bool sorting = false;
App.Create(sf::VideoMode(600, 600), "Bubble sort");
//Filling the field
std::cout << "Filling..." << std::endl;
fieldContext.fill(600);
//Let's start the app
while (App.IsOpened())
{
//Verifying events
while (App.GetEvent(Event))
{
// Window closed
if (Event.Type == sf::Event::Closed)
{
App.Close();
}
//Key pressed
if (Event.Type == sf::Event::KeyPressed)
{
switch (Event.Key.Code)
{
case sf::Key::Escape :
App.Close();
break;
case sf::Key::S :
if (!sorting)
{
std::cout << "Sorting..." << std::endl;
sorting = true;
}
break;
default :
break;
}
}
}
//Update objects
if (sorting)
{
sorting = !fieldContext.sort();
if (sorting == false)
{
std::cout << "Sorted !" << std::endl;
}
}
//Clearing screen
App.Clear();
//Dessin du test
fieldContext.show_points(App);
//Displaying result
App.Display();
}
return EXIT_SUCCESS;
}
-
Thanks Mindiell!
it does what I want! :shock:
I think I understand the "techniquè" of SFML.
I should better read the tutorials on the website and then start with graphic-programming, to avoid such a disaster like this one :oops:
thanks again dude :wink:
-
You're welcome ;)