SFML community forums

Help => General => Topic started by: Hooch on February 24, 2014, 08:20:24 pm

Title: Implementing gamle loop with alpha state blending
Post by: Hooch on February 24, 2014, 08:20:24 pm
Hello.
I don't know how to call it.

I was reading this article: http://gafferongames.com/game-physics/fix-your-timestep/
Author of this article updates game to "state" and in more advanced timesteps methods he is blending those states.

How somehing like that would look in code?
Title: Re: Implementing gamle loop with alpha state blending
Post by: Lo-X on February 24, 2014, 08:47:42 pm
You're looking for Game States or a State Machine (google's your friend).

In pseudo-not-working code, it looks like :

class State
{
public:
     virtual void handleEvents() = 0; // handle player, world events
     virtual void update() = 0; // do the logic
     virtual void render() = 0; // draws on screen

private:
     sf::Window& mWindow;
};

// Inherit from State to do some MenuState, GameState, GameOverState and stuff

class Game
{
public:
     void changeState(State* state);
     void play()
     {
          mState = new MenuState(this);
          while(mWindow.isOpen())
          {
               mState->handleEvents();
               mState->update();
               mState->render();
          }
     }

private:
     sf::RenderWindow     mWindow;
     State*                        mState;
};

This would be a *very* simple implementation of States. You will probably need to give states more data (a context about your app), make pointers be smart, etc.

Have a look at the book SFML "Game Programming", there's such a thing implemented. Sources are available on GitHub (you'll find the link to the repo somewhere on the forum).
Title: Re: Implementing gamle loop with alpha state blending
Post by: Nexus on February 24, 2014, 08:55:12 pm
You're looking for Game States or a State Machine (google's your friend).
That's not the way the term is used in the article; furthermore I wouldn't mix both ideas:
In the article, the first meaning is used. A state simply denotes an object that stores the game logic data for each time step (e.g. position and velocities of all entities).
Title: Re: Implementing gamle loop with alpha state blending
Post by: Lo-X on February 24, 2014, 09:03:24 pm
Isn't the way of handling States called a State Machine (I mean, generally speaking, not only in the book) ? Because I made my very first Game States following an article about States Machines.
Possible I mix up something.
Title: Re: Implementing gamle loop with alpha state blending
Post by: Nexus on February 24, 2014, 09:09:33 pm
No, a (finite) state machine is a discrete set of states where only one state can be active at any given time. This model fits nicely for different menus and surfaces (although sometimes a stack is more flexible).

The idea of the article is to interpolate states, i.e. introduce continuity.
Title: Re: Implementing gamle loop with alpha state blending
Post by: Lo-X on February 24, 2014, 09:11:49 pm
Yeah I just googled for more info about State Machines, sorry for the mistake, I learned something :)
Title: Re: Implementing gamle loop with alpha state blending
Post by: kloffy on February 26, 2014, 03:03:56 pm
The OP question is an interesting one. I would love to see an elegant implementation of a system that interpolates between states as described in Gaffer's article.
Title: Re: Implementing gamle loop with alpha state blending
Post by: MadMartin on February 26, 2014, 04:49:40 pm
You mean state as the state of physics as Glenn wrote? If so, I think it wouldn't be that hard to implement. Just make sure that the elements you use to describe actual data (vectors for position, quaternions for orientation) would implement lerp/slerp (e.g. sf::Vector2 c = lerp(a,b, alpha); for vectors a and b). You certainly would have to preserve the previous state in your game objects. So if there is an object which sprite's being moved, you would save two positions inside the object's instance.

A quick and dirty try on this (can certainly be improved  ;) ):
sf::Vector2 lerp(const sf::Vector2& a, const sf::Vector2& b, float alpha)
{
        return sf::Vector2(a * alpha + b * (1.0f - alpha));
}

class GameObjectInstance
{
public:
        void UpdateLogicPos(sf::Vector2& offset)
        {
                oldPos = actualPos;
                actualPos += offset;
        };

        void UpdateRenderPos(float alpha)
        {
                mySprite.setPosition(lerp(oldPos, actualPos, alpha));
        };

        sf::Sprite& Sprite()
        {
                return mySprite;
        };

private:
        sf::Sprite mySprite;
        sf::Vector2 oldPos;
        sf::Vector2 actualPos;
};



// main drawing loop
// ..

        for (auto goi : myObjects)
        {
                goi.UpdateRenderPos(currentFrameAlpha);
                window.draw(goi.Sprite());
        }

// ..