I'm using VS2013 with SFML Simple and Fast Installer for VS2013 ( http://en.sfml-dev.org/forums/index.php?topic=14127.0 ), and I have tried some types of codes for fading, any of which ended up with freezing:
(1)
bool MsgBox::showTitleLogo(sf::RenderWindow &window)
{
window.clear(sf::Color::White);
sf::Sprite spr;
sf::Texture logo;
if (!logo.loadFromFile("splash/logo.png"))
return false;
spr.setTexture(logo);
spr.setPosition(Config::center(spr));
sf::Clock clk;
while (clk.getElapsedTime() < sf::milliseconds(1000));
bool fade = true;
sf::Color c = spr.getColor();
while (fade)
{
if (c.a = 0)
{
fade = false;
break;
}
window.draw(spr);
if (c.a >= 5)
c.a -= 5;
else
c.a = 0;
spr.setColor(c);
}
return true;
}
(2)
bool MsgBox::fade(sf::RenderWindow &window, bool isIn, sf::Time t, sf::Color c)
{
sf::Color _c = c;
if (isIn)
_c.a = 255;
else
_c.a = 0;
sf::Time grade = sf::seconds(t.asSeconds() / 256.0f);
sf::Clock clk;
bool loop = true;
sf::RectangleShape screen;
screen.setFillColor(_c);
screen.setPosition(0, 0);
screen.setSize(sf::Vector2f(Config::scrWidth(), Config::scrHeight()));
while (loop)
{
window.draw(screen);
clk.restart();
if (clk.getElapsedTime() == grade)
{
if (isIn)
--_c.a;
else
++_c.a;
}
if (isIn)
if (_c.a == 0)
loop = false;
else
if (_c.a == 255)
loop = false;
}
return true;
}
(3)
int main()
{
sf::Sprite sprt;
sf::Texture img;
img.loadFromFile("image.png");
sprt.setTexture(img);
sf::RenderWindow App(sf::VideoMode(1600, 800, 32), "SFML Alpha Demo");
App.setFramerateLimit(60);
App.setVerticalSyncEnabled(false);
int a = 255;
while (App.isOpen())
{
if (a<0){ a = 255; }
sprt.setColor(sf::Color(255, 255, 255, a));
a--;
App.clear(sf::Color::Green);
App.draw(sprt);
App.display();
}
return EXIT_SUCCESS;
}
// This one came from http://en.sfml-dev.org/forums/index.php?topic=2693.msg17638#msg17638 , modified to 2.1 style by myself.
Was there any problem on these codes?
Edit: I intended to make a splash screen, which would be shown up at the startup.
@Laurent
Then how about (1) and (2)? Each of them is just one function, not the full code.
Edit: (2) was used with this code.
(2+)
bool MsgBox::showTitleLogo(sf::RenderWindow &window)
{
window.clear(sf::Color::White);
sf::Sprite spr;
sf::Texture logo;
if (!logo.loadFromFile("splash/logo.png"))
return false;
spr.setTexture(logo);
spr.setPosition(Config::center(spr));
window.draw(spr);
sf::Clock clk;
while (clk.getElapsedTime() < sf::milliseconds(1000));
fade(window, false, sf::milliseconds(10000)); // here!
return true;
}
You can't have a blocking loop inside your main loop. Because as long as this inner loop is active, nothing else can happen (event processing, drawing of other stuff, etc.). Your main loop has to be executed, it can't be interrupted. And at each iteration of your main loop, you must update your color based on the elapsed time.
A typical approach looks like this (pseudo-code):
sf::Clock clock;
while (window.isOpen())
{
// process events...
sf::Event event;
while (window.pollEvent(event))
{
...
}
// update logic...
sf::Time elapsed = clock.restart();
for (all entities)
entity.update(elapsed);
// draw everything...
window.clear();
for (all entities)
window.draw(entity);
window.display();
}
...
void MsgBox::update(sf::Time elapsed)
{
if (m_fading)
{
m_accumulatedTime += elapsed;
if (m_accumulatedTime < m_fadeDelay)
{
m_opacity = m_accumulatedTime.asSeconds() * 255 / m_fadeDelay.asSeconds();
m_sprite.setColor(255, 255, 255, m_opacity);
}
else
{
m_fading = false;
}
}
}