Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Animation only animates on stand still (solved)  (Read 4738 times)

0 Members and 1 Guest are viewing this topic.

ingwik

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
Animation only animates on stand still (solved)
« on: September 23, 2011, 11:34:54 am »
I have made a simple project with the class anisprite, more or less direct copied from the wiki:
http://www.sfml-dev.org/wiki/en/sources/anisprite

I need just a simple way to animate sprites, and that class seemed sufficient for my needs. The problem is that when everything is in place, the figure (boy with green hair) is animated when he is standing still. As soon as I try to move him by code or by key down, he moves but the animation stops. I suppose I can use the class still for explosions and such that aren't moving, but the idea to have animated sprites that move seems more tempting. If anyone has a solution to the problem, I would be grateful.

Environment:
SFML 1.6
Windows 7 Enterprise 64
Microsoft VC++ 2010 express

The code in main.cpp this far, the comment are in swedish since I intended to show the code for teenagers that want to create simple games, but I assume it can be read quite easy anyway by the pros in here :) The AniSprite header and cpp-file are more or less unchanged.
-------------------

Code: [Select]

#include <iostream>
#include <SFML\System.hpp>
#include <SFML\Graphics.hpp>
#include <SFML\Window.hpp>
#include <AniSprite.h> //länk saknas i originaldokumentet


  int main()
    {  //Början av programkörningen

sf::RenderWindow App(sf::VideoMode(800, 600, 32), "Test - animation");

float pojkfart = 0.05f; //hastigheten när pojken flyttar sig
                               
 // Ladda in in sprite-karta, en uppsättning bilder som skall visas i sekvens
  sf::Image pojkkarta;
   if (!pojkkarta.LoadFromFile("character.png"))
        return EXIT_FAILURE;
  AniSprite Spritepojk(pojkkarta,47,64); //storleken på varje enskild bild
   Spritepojk.SetLoopSpeed(12); //12 fps
    Spritepojk.Play(0,1); //Visa första och andra bilden enbart, får inte vara 0,0
      Spritepojk.SetPosition(200.f, 200.f); //Placera ut bilden

while(App.IsOpened())
{
        sf::Event Event;

       
while (App.GetEvent(Event)) // Ta hand om händelser
   { //while 2

      if (Event.Type == sf::Event::Closed) //kryssat på [x] symbolen? stäng programmet
         App.Close();

      if (Event.Type == sf::Event::KeyPressed) // En tangent har tryckts ner

             { //if 1

               if (Event.Key.Code == sf::Key::Escape) // ESC tangenten = stäng programmet
                    App.Close();

              } //slut if 1

  } //slut, while 2


if (App.GetInput().IsKeyDown(sf::Key::Left))
         {
          Spritepojk.Move(-pojkfart, 0);
     Spritepojk.Play(12,15);
   } //Visa nedersta raden, pojken går åt vänster

else if (App.GetInput().IsKeyDown(sf::Key::Right))
         {
          Spritepojk.Move( pojkfart, 0);
      Spritepojk.Play(4,7); //Visa andra raden, pojken går åt höger
    }
else if (App.GetInput().IsKeyDown(sf::Key::Up))
        {
        Spritepojk.Move(0, -pojkfart);
   Spritepojk.Play(0,3); //Visa första raden, man ser ryggen på pojken
   }
else if (App.GetInput().IsKeyDown(sf::Key::Down))
        {
        Spritepojk.Move(0, pojkfart);
   Spritepojk.Play(8,11); //Visa tredje raden, man ser ansiktet på pojken
   }

// Rensa skärmen
    App.Clear();        
//updatera animation
    Spritepojk.Update();
    App.Draw(Spritepojk);
    App.Display();
}

return 0;
} //slut på programkörningen

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Animation only animates on stand still (solved)
« Reply #1 on: September 23, 2011, 11:39:01 am »
Moving the animated entity is left to the user of the class (at least in the class you got from the wiki).

The solution to your problem is simple, don't restart the animation (Spritepojk.Play(...)) everytime the entity moves. I don't know if this class has a way to test whether an animation is running or not.

Also, there may be more complete animation classes, see Thor for example.
Laurent Gomila - SFML developer

ingwik

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
Animation only animates on stand still (solved)
« Reply #2 on: September 23, 2011, 12:43:29 pm »
I took a quick look in Thor and it looks interesting but there seems to be no class for sprites or animation of sprites, or am I wrong?
http://www.bromeon.ch/thor/v1.0/doc/annotated.html

Furthermore, there's a lot of question in the SFML forum about animation, many new coders get stuck in it since there is no given class that show animations even though animated game sprites have been around for decades. A lot of questions when frustrated new game creators are asking for help with animations get the short answer "take a look at the animation class in the sfml wiki". So that was what I did also. But maybe I was looking for the wrong animation class?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Animation only animates on stand still (solved)
« Reply #3 on: September 23, 2011, 01:07:59 pm »
Quote
I took a quick look in Thor and it looks interesting but there seems to be no class for sprites or animation of sprites, or am I wrong?

Oh, it seems that animations are only in version 1.1
http://www.bromeon.ch/thor/v1.1/doc/group___animation.html
Laurent Gomila - SFML developer

ingwik

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
Animation only animates on stand still (solved)
« Reply #4 on: September 23, 2011, 01:22:20 pm »
But Thor 1.1 is only for SFML 2.0? Or am I wrong there too? Furthermore, the only pre-compiled dll:s I can find there for vc++ 2010 are for 32 bit system.

At the end of the day, it would be nice to have a simple animation class in SFML that actually worked and let the more advanced user delve into Thor and other systems. Otherwise, I'm quite sure more people are like me, the act of creating an animation class of my own is a daunting task that I really can't manage but there are no alternatives so I am stuck with making pong games and such that don't demand animations.

A lot of people in here seems quite skilled in c++ programing, how hard can it be for a good and kind programmer to make an animation class that use a sprite sheet of say 16 equally big pictures to show an explosion or a helicopter with moving rotor and give that for free to us newbies in the game programming world? Then, we would at least have something that moves around on the screen, compared to nothing as it is now.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Animation only animates on stand still (solved)
« Reply #5 on: September 23, 2011, 01:33:09 pm »
Ok, forget about Thor, I hadn't noticed that you were using SFML 1.6.

I never said that the wiki classes were bad. They are very simple, they work perfectly and anybody can use them. So pick one that you like (or keep the one you're currently using), and solve your problem with this:
Quote
The solution to your problem is simple, don't restart the animation (Spritepojk.Play(...)) everytime the entity moves.
Laurent Gomila - SFML developer

thePyro_13

  • Full Member
  • ***
  • Posts: 156
    • View Profile
Animation only animates on stand still (solved)
« Reply #6 on: September 23, 2011, 01:35:13 pm »
The animation doesn't work because you restart it with play() every frame that a key is down, you need to create a state enum for your entity and only play when you start moving. I can make an example by adding hasMoved bools to your code. Changes bold.

Code: [Select]
#include <iostream>
#include <SFML\System.hpp>
#include <SFML\Graphics.hpp>
#include <SFML\Window.hpp>
#include <AniSprite.h> //länk saknas i originaldokumentet


  int main()
    {  //Början av programkörningen

sf::RenderWindow App(sf::VideoMode(800, 600, 32), "Test - animation");

float pojkfart = 0.05f; //hastigheten när pojken flyttar sig
                               
 // Ladda in in sprite-karta, en uppsättning bilder som skall visas i sekvens
  sf::Image pojkkarta;
   if (!pojkkarta.LoadFromFile("character.png"))
        return EXIT_FAILURE;
  AniSprite Spritepojk(pojkkarta,47,64); //storleken på varje enskild bild
   Spritepojk.SetLoopSpeed(12); //12 fps
    Spritepojk.Play(0,1); //Visa första och andra bilden enbart, får inte vara 0,0
      Spritepojk.SetPosition(200.f, 200.f); //Placera ut bilden

   [b]bool left,  right, up, down;
   left = right = up = down = false;[/b]
while(App.IsOpened())
{
        sf::Event Event;

       
while (App.GetEvent(Event)) // Ta hand om händelser
   { //while 2

      if (Event.Type == sf::Event::Closed) //kryssat på [x] symbolen? stäng programmet
         App.Close();

      if (Event.Type == sf::Event::KeyPressed) // En tangent har tryckts ner

             { //if 1

               if (Event.Key.Code == sf::Key::Escape) // ESC tangenten = stäng programmet
                    App.Close();

              } //slut if 1

  } //slut, while 2


if (App.GetInput().IsKeyDown(sf::Key::Left))
         {
          Spritepojk.Move(-pojkfart, 0);
[b]if(!left)[/b]
     Spritepojk.Play(12,15);

     [b]left = true ;
     down = right = up = false;[/b]
   } //Visa nedersta raden, pojken går åt vänster

else if (App.GetInput().IsKeyDown(sf::Key::Right))
         {
          Spritepojk.Move( pojkfart, 0);
[b]if(!right)[/b]
      Spritepojk.Play(4,7); //Visa andra raden, pojken går åt höger

    [b] right = true;
     left = up = down = false;[/b]
    }
else if (App.GetInput().IsKeyDown(sf::Key::Up))
        {
        Spritepojk.Move(0, -pojkfart);

[b]if(!up)[/b]
   Spritepojk.Play(0,3); //Visa första raden, man ser ryggen på pojken

  [b] up = true;
     left = right = down = false;[/b]
   }
else if (App.GetInput().IsKeyDown(sf::Key::Down))
        {
        Spritepojk.Move(0, pojkfart);

[b]if(!down)[/b]
   Spritepojk.Play(8,11); //Visa tredje raden, man ser ansiktet på pojken


    [b] down = true;
     left = right = up = false;[/b]
   }
[b]else
 {
        left = right = up = down = false;
        Spritepojk.Play(0,1);
}[/b]

// Rensa skärmen
    App.Clear();        
//updatera animation
    Spritepojk.Update();
    App.Draw(Spritepojk);
    App.Display();
}

return 0;
} //slut på programkörningen

Untested code, but the logic should be sound.
You can use states like this to manage animations and entities logic, though you'll want to keep all of that in a class rather than by using bools like I did here.

Note: I think you have to upgrade to SFML2 to start using thor animations.

BAH: bold doesn't seem to work in code tags, that code I added is all surrounded by broken bold tags, to make it easier to find. :D

ingwik

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
Animation only animates on stand still (solved)
« Reply #7 on: September 23, 2011, 02:10:07 pm »
Thanks pyro it works.

I'm a bit confused though. Setting a member of a set (state enum) to false make it work? I really can't see why it works, but it does. In my mind, it should be enough to say " hey, you have pressed the left button then I'll play the animation for moving left and move in that direction".

Instead it says "hey, I'm false. Because of that I'll move to the left when you press left with my move left animation. Then I become true but all my friends become false so they will move and animate in the future but not me.

I also added a <animsprite>.Stop(); in the end too to make it stop using an animation when no key is pressed. I also set all set members to false when no key is pressed so it is possible to hit the same key two times in a row and still have the animation running the second time.

 I'm satisfied that I've made it work with your help. Thanks!


Thanks

EDIT
I learn a lot C++ along the way, and I admit it's quite obvious how it works if you just think about it. A better way to think about it is that each state is a lightbulb and it gets current when an arrow key is pressed, but you can't light up two bulbs at the same time.

aBallofWin

  • Jr. Member
  • **
  • Posts: 99
    • View Profile
Re: Animation only animates on stand still (solved)
« Reply #8 on: May 13, 2012, 04:19:06 am »
Just to build on this (because this really helped me too) some people won't want the character to return to a downwards postion after they've stopped moving so I added the following code:

Code: [Select]
bool leftstop, rightstop, upstop, downstop;
leftstop = rightstop = upstop = downstop = false;

&

left = true ;
leftstop = true; rightstop = false; upstop = false; downstop = false;
/* at every movement part, this is for left, as well as putting up down and right to false, put the relating stops to false too*/

&

left = right = up = down = false;
        if (leftstop == true && rightstop == false && upstop == false && downstop == false)
            Hero.Play(4,5);
        else if (leftstop == false && rightstop == true && upstop == false && downstop == false)
            Hero.Play(7,8);
        else if(leftstop == false && rightstop == false && upstop == true && downstop == false)
            Hero.Play(10,11);
        else if(leftstop == false && rightstop == false && upstop == false && downstop == true)
            Hero.Play(1,2);
/* this at the end, changing the Hero.Play to match the sprite used

Cheers for making the thread OP!

 

anything