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

Author Topic: Loop problems with animation (AniSprite)  (Read 4504 times)

0 Members and 1 Guest are viewing this topic.

aBallofWin

  • Jr. Member
  • **
  • Posts: 99
    • View Profile
Loop problems with animation (AniSprite)
« on: January 09, 2012, 01:03:59 am »
I've recently decided to move my game from a top down view to a more 2d view with animated sprites and I've got the main sprite animated using AniSprite, apart when I've put it into my main game .hpp to play the animation when the character moves.

I've spent about 5 hours trying to get it to work, tried everything I could think off to get it to move when I hold down an arrow key, even rewriting most of this part of the program.

The thing is, is that when I move left for example, I want the animation to keep on playing until I release the left key, here's the initial movement coding:
Code: [Select]
if (cantmove == 0) ///cant move if 1

{
if(App.GetInput().IsKeyDown(sf::Key::Left))

{
map.Move(speed,0); map3.Move(speed,0);

guy.Move(speed,0); woman.Move(speed,0);

woman2.Move(speed,0);

if (Collision::PixelPerfectTest(map, aniCross)
|| Collision::PixelPerfectTest(guy, aniCross) || Collision::PixelPerfectTest(woman, aniCross) || Collision::PixelPerfectTest(woman2, aniCross))
{
map.Move(-speed,0); map3.Move(-speed,0);

guy.Move(-speed,0); woman.Move(-speed,0);

woman2.Move(-speed,0);
}
}

if(App.GetInput().IsKeyDown(sf::Key::Right))

{
map.Move(-speed,0); map3.Move(-speed,0);

guy.Move(-speed,0); woman.Move(-speed,0);

woman2.Move(-speed,0);

if (Collision::PixelPerfectTest(map, aniCross) || Collision::PixelPerfectTest(guy, aniCross) || Collision::PixelPerfectTest(woman, aniCross)
|| Collision::PixelPerfectTest(woman2, aniCross))
{
map.Move(speed,0); map3.Move(speed,0);

guy.Move(speed,0); woman.Move(speed,0);

woman2.Move(speed,0);
}
}

if(App.GetInput().IsKeyDown(sf::Key::Up))

{
map.Move(0,speed); map3.Move(0,speed);

guy.Move(0,speed); woman.Move(0,speed);

woman2.Move(0,speed);

if (Collision::PixelPerfectTest(map, aniCross) || Collision::PixelPerfectTest(guy, aniCross)
|| Collision::PixelPerfectTest(woman, aniCross) || Collision::PixelPerfectTest(woman2, aniCross))
{
map.Move(0,-speed); map3.Move(0,-speed);

guy.Move(0,-speed); woman.Move(0,-speed);

woman2.Move(0,-speed);
}
}

if(App.GetInput().IsKeyDown(sf::Key::Down))

{
map.Move(0,-speed); map3.Move(0,-speed);

guy.Move(0,-speed) ;woman.Move(0,-speed);

woman2.Move(0,-speed);

if (Collision::PixelPerfectTest(map, aniCross) || Collision::PixelPerfectTest(guy, aniCross)
|| Collision::PixelPerfectTest(woman, aniCross) || Collision::PixelPerfectTest(woman2, aniCross))
{
map.Move(0,speed); map3.Move(0,speed);

guy.Move(0,speed); woman.Move(0,speed);

woman2.Move(0,speed);
}
            }
}

*aniCross is the crosshair which is used as the center of the screen and the character; guy, woman and woman2 are npcs*

Then I put in this piece of code, which gets it to do the animation, but only once:
Code: [Select]
if (App.GetEvent(Event))
    {
        if (Event.Type == sf::Event::KeyPressed)
            {
                switch (Event.Key.Code)
                {
                    case sf::Key::Left:
                            aniCross.Play(3, 6);
                           // break;
                }
            }

        if (Event.Type == sf::Event::KeyReleased)
            {
                switch (Event.Key.Code)
                {
                    case sf::Key::Left:
                        aniCross.Stop();
                        //break;    not making a difference
                }
            }
    }


I put this in just before the last bracket in the first code, and the peculiar thing is that when holding left, it will go through the 3 frames once then leave me with a static image of the first, but if i'm holding left, and then tap up or down, it will start looping like i want it to. Very weird indeed :/

(I've also tried placing it everywhere else in the program, but this is the best place so far)

It would be awesome if someone could help with this, otherwise my only other option would be to copy and paste the sprite sheet onto itself so it will be one massive picture, but that will be inefficient, it will eventually end, and it's the lazy way out :(

Cheers in advance!

Jake


P.S I can also give out the entire source code if that's needed! (be on tomorrow)

EDIT:   I removed the (3, 6) from aniCross.Play() and found out that it will only play 3 sprites altogether, maybe some problem with it accessing it?

justcolorado

  • Newbie
  • *
  • Posts: 16
    • View Profile
There is a better way
« Reply #1 on: January 14, 2012, 04:11:50 am »
Looks like a cool program you are writing  8)

I thought about doing animation with multiple sprites but everywhere I read advised strongly against it.  It seems the most efficient way to do it is with a sheet of sprites.  Check out this thread http://www.sfml-dev.org/forum/viewtopic.php?p=27588&sid=dbf53e03d0bada800e5d622830c6d2b2 for more details.

I have been using sheets and they work really nice.

aBallofWin

  • Jr. Member
  • **
  • Posts: 99
    • View Profile
Loop problems with animation (AniSprite)
« Reply #2 on: January 14, 2012, 07:14:42 pm »
Isn't that thread talking about a class in sfml2? I'm only going to use 1.6 for this game, and I am doing it using a sheet of sprites, the problem here, is that it goes through the sequence once then stops, which is a loop problem somewhere.

In the end i just went to it making it look the way, instead of making it animate

justcolorado

  • Newbie
  • *
  • Posts: 16
    • View Profile
Loop problems with animation (AniSprite)
« Reply #3 on: January 15, 2012, 12:46:47 am »
I use SFML 1.6.  And the same applies.  According to everything I have read, sheets are the way to go.  Images are heavy clunky objects.  Sprites are just tiny little data structures.  That don't contain the image at all.  They just have a reference of where to get it from.  For this reason you want more sprites and less image files.

Even if you only have a 2 or 3 frame animation.  Multiple sprites for animation is discouraged everywhere I look.  You can look around further and I think you will find the same.  I don't think it is a good practice to use.

Using a spritesheet is pretty easy with SFML.  All you need to do is load up your sheet for the sprite and you can move from frame to frame with setsubrect like this:

Code: [Select]


// Frame 1
mySprite.SetSubRect(IntRect(0,0,32,32));
// Frame 2
mySprite.SetSubRect(IntRect(32,0,64,32));






.

aBallofWin

  • Jr. Member
  • **
  • Posts: 99
    • View Profile
Loop problems with animation (AniSprite)
« Reply #4 on: January 15, 2012, 02:45:20 pm »
Tried that and it didn't work, something about IntRect not being declared

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Loop problems with animation (AniSprite)
« Reply #5 on: January 15, 2012, 02:55:45 pm »
aBallofWin, you could solve the half of your problems if you just reflected two minutes before posting on the forum. You really have to learn how to solve such trivial issues on your own.

If something is not declared, include the corresponding header or qualify the right namespace.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

justcolorado

  • Newbie
  • *
  • Posts: 16
    • View Profile
Loop problems with animation (AniSprite)
« Reply #6 on: January 15, 2012, 05:28:10 pm »
IntRect is from the sprite class.  You can fix it with sf::IntRect or simply by using namespace SFML; in your header

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Loop problems with animation (AniSprite)
« Reply #7 on: January 15, 2012, 05:56:47 pm »
Quote from: "justcolorado"
IntRect is from the sprite class.
Actually it's an own class (a class template instantiation, to be precise).

Quote from: "justcolorado"
or simply by using namespace SFML; in your header
The namespace is called sf. And using namespace in headers is very bad practice because it irreversibly pollutes the global namespace in every file that (directly or indirectly) includes the header. So only do it in .cpp files, or better locally in functions, or not at all.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

justcolorado

  • Newbie
  • *
  • Posts: 16
    • View Profile
Loop problems with animation (AniSprite)
« Reply #8 on: January 17, 2012, 05:40:13 pm »
Nexus is right.  I probably shouldn't post technical answers from my i-Phone while watching Star Trek Re-runs.  

Did you get it to work?

aBallofWin

  • Jr. Member
  • **
  • Posts: 99
    • View Profile
Loop problems with animation (AniSprite)
« Reply #9 on: January 18, 2012, 06:00:24 pm »
At the moment I'm coding the core of my game before I start fussing over things like animation and that :) I will try to update it when I do get round to solving the issue. At the moment I'm just making it point the character to the way you turn, instead of animating it :(

Elgan

  • Jr. Member
  • **
  • Posts: 77
    • AOL Instant Messenger - Flat+1,+17+st+Cl
    • View Profile
Loop problems with animation (AniSprite)
« Reply #10 on: January 18, 2012, 06:27:20 pm »
I have in dev my animation system,
Which is totally dynamic.

Which loads all animation sets from an xml file like this

Code: [Select]


<?xml version="1.0" encoding="utf-8" ?>
<sprite src="spritesheet.png">
<animnation name="down"  loop="true">
<frame name="down_1" x ="0" y="0" w="16" h="32"/>
<frame name="down_2" x ="17" y="0" w="16" h="32"/>
<frame name="down_3" x ="34" y="0" w="16" h="32"/>
<frame name="down_4" x ="51" y="0" w="16" h="32"/>
</animnation>
<animnation name="left" loop="true">
<frame name="left_1" x ="68" y="0" w="16" h="32"/>
<frame name="left_2" x ="85" y="0" w="16" h="32"/>
<frame name="left_3" x ="0" y="33" w="16" h="32"/>
<frame name="left_4" x ="17" y="33" w="16" h="32"/>
</animnation>
<animnation name="right" loop="true">
<frame name="right_1" x ="0" y="66" w="16" h="32"/>
<frame name="right_2" x ="34" y="33" w="16" h="32"/>
<frame name="right_3" x ="17" y="66" w="16" h="32"/>
<frame name="right_4" x ="51" y="33" w="16" h="32"/>
</animnation>
<animnation name="up" loop="true">
<frame name="up_1" x ="34" y="66" w="16" h="32"/>
<frame name="up_2" x ="68" y="33" w="16" h="32"/>
<frame name="up_3" x ="51" y="66" w="16" h="32"/>
<frame name="up_4" x ="85" y="33" w="16" h="32"/>
</animnation>
<image name="head" x ="68" y="66" w="16" h="16"/>
</sprite>



Then ive written an exporter for a sprite packer which creates the file. All packed up in one texture.

I can then access each animation sequence as follows:

in my player class
Quote
   g_spritesheet playerSheet;
   

The player/object class will eventually turn into a base ent class which controls the sprite class.

then I have


Quote
   player.loadPlayer("playerimage");
   player.setAnim("right");
   player.setSpeed(4);


If anyone is really having a lot of trouble with the above, and are interested I might try and move it out so I can post it.

right now, trouble is...using tinyxml I find if any error occurs it will just crash (ie, an xml file is invalid)
Also I load my xml files and images from a resource manager which streams them from pack files..I would need to remove this back to loadfrom file (not that hard)...but only if someone is interested.
Right now I am working on a system of variables, so I can set speed multipliers. which you will have to either have static or in your own variable system..ini or xml or whatever..