School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 300,499 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 1,855 people online right now. Registration is fast and FREE... Join Now!




making sprite animation slower (SFML and C++)

 

making sprite animation slower (SFML and C++)

vAlexv

15 Jun, 2009 - 08:01 PM
Post #1

New D.I.C Head
Group Icon

Joined: 12 Dec, 2008
Posts: 24



Thanked: 1 times
Dream Kudos: 75
My Contributions
CODE

#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <sfml/Graphics.hpp>

enum KeyType
{
    UP,DOWN,RIGHT,LEFT,SPACE
};
typedef std::map<KeyType, bool> mapType;

void SetMap(mapType & type, const sf::RenderWindow & win)
{
    type[UP]    = win.GetInput().IsKeyDown(sf::Key::Up);
    type[DOWN]  = win.GetInput().IsKeyDown(sf::Key::Down);
    type[RIGHT] = win.GetInput().IsKeyDown(sf::Key::Right);
    type[LEFT]  = win.GetInput().IsKeyDown(sf::Key::Left);
    type[SPACE] = win.GetInput().IsKeyDown(sf::Key::Space);
}

const int ScreenWidth  = 600;
const int ScreenHeight = 500;
const int Speed           = 300;

class Player
{
public:
    Player( const std::string & s) : frame(0)
    {
        static sf::Image image = sf::Image();
        image.LoadFromFile(s);
    
        sprite.SetImage(image);
        sprite.SetSubRect(    sf::IntRect(0,  61, 32, 127) );
        sprite.SetPosition(400,400);

        int x = 0;
        int y = 32;
        for(int i = 0; i < 6; ++i)
        {
                         //Sub rects of the sprite sheets
             leftSprites.push_back(sf::IntRect(x, 61, y, 127));
             rightSprites.push_back(sf::IntRect(x, 192, y, 255));
             upSprites.push_back(sf::IntRect(x, 126, y, 192));
             downSprites.push_back(sf::IntRect(x,0,y,62));

             x += 32;
             y += 32;
        }
    }
    void Move(const sf::RenderWindow & App)
    {
        WallCollision(App.GetFrameTime());
        SetMap(easierKey, App);

        float delta = App.GetFrameTime() * spriteSpeed;

        if(easierKey[LEFT])
        {
            sprite.SetSubRect(leftSprites[frame]);
            sprite.Move(-delta,0);
            ++frame;
        }
        if(easierKey[RIGHT])
        {
            sprite.SetSubRect(rightSprites[frame]);
            sprite.Move(delta,0);
            ++frame;
        }
        if(easierKey[UP])
        {
            sprite.SetSubRect(upSprites[frame]);
            sprite.Move(0,-delta);
            ++frame;
        }
        if(easierKey[DOWN])
        {
            sprite.SetSubRect(downSprites[frame]);
            sprite.Move(0, delta);
            ++frame;
        }
                //Return to first frame

        if(frame >= leftSprites.size() - 1)
            frame = 0;
    }
    void Show( sf::RenderWindow & App)
    {
        App.Draw(sprite);
    }
private:
    void WallCollision(float delta)
    {
        const float x = sprite.GetPosition().x;
        const float y = sprite.GetPosition().y;

        static const float WidthMinus  = ScreenWidth  - sprite.GetSize().x;
        static const float HeightMinus = ScreenHeight - sprite.GetSize().y;

        if(x <= 0)     sprite.Move(spriteSpeed * delta, 0);
        if(y <= 0)    sprite.Move(0, spriteSpeed * delta);

        if(y >= HeightMinus) sprite.Move(0, -spriteSpeed * delta);
        if(x >= WidthMinus)  sprite.Move(-spriteSpeed * delta, 0);
    }
private:
    sf::Sprite sprite;
    enum {spriteSpeed = 100};

    //Holds the sub rects of the sprites
    std::vector<sf::IntRect> leftSprites;
    std::vector<sf::IntRect> rightSprites;
    std::vector<sf::IntRect> upSprites;
    std::vector<sf::IntRect> downSprites;

    mapType easierKey;

    unsigned int frame;
};
class Background
{
public:
    Background(const std::string & s)
    {
        static sf::Image image = sf::Image();
        image.LoadFromFile(s);
        sprite.SetImage(image);
        sprite.SetPosition(0,0);

        back.SetImage(image);
        back.SetPosition(-sprite.GetSize().x + 10,0);
    }
    void Move(const sf::RenderWindow & App)
    {
        const float delta = App.GetFrameTime();
        sprite.Move(backSpeed * delta, 0);
        back.Move(backSpeed * delta, 00);

        if(sprite.GetPosition().x >= ScreenWidth)
            sprite.SetPosition(-sprite.GetSize().x + 10, 0);
        if(back.GetPosition().x >= ScreenWidth)
            back.SetPosition(-sprite.GetSize().x + 10, 0);
    }
    void Show( sf::RenderWindow &app)
    {
        app.Draw(sprite);
        app.Draw(back);
    }
private:
    sf::Sprite sprite;
    sf::Sprite back;
    enum{backSpeed = 250};
};

int main()
{
    sf::RenderWindow App(sf::VideoMode(ScreenWidth,ScreenHeight), "Main");
    
    Player player("sprites.png");
    Background background("fire.png");

    while(App.IsOpened())
    {
        sf::Event event;
        while(App.GetEvent(event))
        {
            if(event.Type == event.Closed)
                App.Close();    
            if(App.GetInput().IsKeyDown(sf::Key::Escape))
                App.Close();
        }

        //Sprite events
        player.Move(App);
        background.Move(App);

        App.Clear(sf::Color(100,100,100));

        //Sprite displays
        background.Show(App);
        player.Show(App);

        //Window draw
        App.Display();                                
    }
}

The sprite animation is really fast, and it looks really weird, how can I fix it?
This is the sprite sheet I am using for now, if you want to test it
http://www.allacrost.org/media/art/sprites_map_claudius.png

Thanks

This post has been edited by vAlexv: 15 Jun, 2009 - 08:02 PM

User is offlineProfile CardPM
+Quote Post


chuckb

RE: Making Sprite Animation Slower (SFML And C++)

15 Jun, 2009 - 08:53 PM
Post #2

D.I.C Head
**

Joined: 29 May, 2009
Posts: 176



Thanked: 4 times
My Contributions
Hi,
Let's take this snippet of yours:

CODE
        if(easierKey[RIGHT])
        {
            sprite.SetSubRect(rightSprites[frame]);
            sprite.Move(delta,0);
            ++frame;
        }

It seems that each time you press the right arrow key the sprite moves and the frame advances. Correct? The problem is that anytime you press the key, this code is called several times while the button is being pressed...which results in very fast animation. So, it's important for the code to recognize the first key press and ignore the other ones the follow immediately.

Here's the concept in code...needs tweaked...and isn't an elegant solution. I would actually separater updating of movement with rendering...but that's a different story.

CODE

static float keyTime = 0;
keyTime += delta;

if(easierKey[RIGHT] && keyTime > 0.2){
            sprite.SetSubRect(rightSprites[frame]);
            sprite.Move(keyTime,0);
            ++frame;
            keyTime = 0;
}

So, this code is processed only once every 200 milliseconds. The frame will only advance once every 200 milliseconds. You can adjust the 0.2 for faster/slower behavior.

Regards,
Chuck


User is offlineProfile CardPM
+Quote Post

stayscrisp

RE: Making Sprite Animation Slower (SFML And C++)

16 Jun, 2009 - 04:59 AM
Post #3

Mouth->Insert(Foot);
Group Icon

Joined: 14 Feb, 2008
Posts: 1,380



Thanked: 53 times
Dream Kudos: 300
My Contributions

If you want to get a good speed for animation then you will have to use some kind of time based animation and movement.

You need to cap your frame rate so that if your project is played on a different computer it is still the same speed, this is very important.

Basically you need to create a timer and then use it to get the frame rate, if the frame rate is over a certain level then you cap it or make it wait between frames.
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic

Time is now: 11/8/09 05:00AM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month