Skip to content

Transitions

Modar Nasser edited this page Sep 24, 2020 · 4 revisions

When changing game screens or levels, you will probably need a way to use a Transition.

In NasNas, Transitions are special objects. After creating them, they are totally handled by the framework (updating, rendering and destroying). Thus, Transition objects should not be stored by the user.

Right now, only 2 transitions are provided out of the box (CircleOpen and Circleclose), but you can easily create your own transitions by inheriting the ns::Transition class.

Let's look at an example using Circle transitions :

Game::Game() {
    // setting Window clear color to white so we can actually see the transition
    this->getWindow().setClearColor(sf::Color::White);
}

Game::onEvent(const sf::Event& event) {
    if (event.type == sf::Event::Closed) 
        this->getWindow().close();
    if (event.type == sf::Event::KeyPressed) {
        if (event.key.code == sf::Keyboard::T)
            (new ns::transition::CircleClose())->start();
        if (event.key.code == sf::Keyboard::Y)
            (new ns::transition::CircleOpen())->start();      
    }
}

Game::update() {}

Pressing T or Y keys will start a CircleClose or CircleOpen transition, it is that simple !

Let's say we want to switch game screen when the CircleClose transition ends, and then directly play a CircleOpen transition; we can do this by using the setOnEndCallback method that takes a lambda function as argument:

Game::Game() {
    this->getWindow().setClearColor(sf::Color::White);
}

Game::onEvent(const sf::Event& event) {
    if (event.type == sf::Event::Closed) 
        this->getWindow().close();
    if (event.type == sf::Event::KeyPressed) {
        if (event.key.code == sf::Keyboard::T) {
            auto* tr = new ns::transition::CircleClose();
            tr->start();
            tr->setOnEndCallback([&](){
                // load next level, change game screen ...etc  here
                this->getWindow().setClearColor(sf::Color::Green);
                (new ns::transition::CircleOpen())->start();
            });
        }
    }
}

Game::update() {}

To create your own transition, you need to inherit from ns::Transition and implement the onUpdate virtual method. In this method, when your transition should end, just call the end method.

The example below implements very basic FadeIn and FadeOut transitions :

class FadeOut : public ns::Transition {
    sf::RectangleShape bg;
public:
    FadeOut() {
        // creating the transition background
        this->bg.setSize(app->getWindow().getAppView().getSize());
        this->bg.setFillColor(sf::Color::Transparent);
        this->addShape(this->bg);
    }
    void onUpdate() override {
        // updating background opacity
        this->bg.setFillColor(this->bg.getFillColor()+sf::Color(0, 0, 0, 5));
        // when the background is opaque, end the transition
        if (this->bg.getFillColor().a >= 255)
            end();
    }
};

class FadeIn : public ns::Transition {
    sf::RectangleShape bg;
public:
    FadeIn() {
        // creating the transition background
        this->bg.setSize(app->getWindow().getAppView().getSize());
        this->bg.setFillColor(sf::Color::Black);
        this->addShape(this->bg);
    }
    void onUpdate() override {
        // updating background opacity
        this->bg.setFillColor(this->bg.getFillColor()-sf::Color(0, 0, 0, 5));
        // when the background is transparent, end the transition
        if (this->bg.getFillColor().a <= 0)
            end();
    }
};

Note : ns::Transition inherits from ns::AppComponent, which means it can access the main App methods by using the ns::Transition::app property.

Transitions offer a lot of flexibility and are a powerful tool to create easily customized transitions for your game.

For more details, see the documentation.