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

Author Topic: How to make things happen for a duration of time? / Pokémon movement  (Read 3886 times)

0 Members and 1 Guest are viewing this topic.

WhiteWind

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
I'm new to SFML and I'm wondering how I'd do this.

Right now I have a sprite (spritesheet) which animatesusing IntRect correctly depending on which direction button you press. The character moves in that direction too. However, I have no limit on the animation, so it's incredibly fast. I tried adding sf::sleep which made the sprite animate at a nice speed, but this stopped my character's movement. So one or the other is broken right now, whether I use sleep or not.

My eventual goal is to make Pokémon movement:
- Press right, control is taken from the player
- the sprite moves right one grid space (say 14.f)
- one animation cycle happens during this movement
- the movement takes .5f seconds to elapse

I have no idea how to do this. I'm guessing something either to do with the Clock class or threading the animation and movement separately.

Thanks in advance for you help (:

        // Game Loop:
        while(Screen.isOpen())
        {
            // Check if the window is closed:
            sf::Event event;

            while(Screen.pollEvent(event))
            {
                if(event.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
                    Screen.close();
            }

            // Set drawing positions and velocities:
            // - Left and Right:
            if(sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
                src.y = sL;
                vel.x = -moveSpeed;
            } else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
                src.y = sR;
                vel.x = moveSpeed;
            } else {
                vel.x = 0;
            }
            // - Up and Down:
            if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
                src.y = sU;
                vel.y = -moveSpeed;
            } else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
                src.y = sD;
                vel.y = moveSpeed;
            } else {
                vel.y = 0;
            }

            // Move the player:
            pos.x += vel.x;
            pos.y += vel.y;

            // Animate image:
            if(vel.x != 0 || vel.y != 0) {
                src.x += spritesheet.getSize().x / 4;
                // - No limit in here..
            } else {
                src.x = 0;
            }

            // - reset to the first frame:
            if(src.x == spritesheet.getSize().x)
                src.x = 0;

            // Refresh the screen:
            Screen.clear();

            // Draw and display the player:
            player.setTextureRect(sf::IntRect(src.x, src.y, spritesheet.getSize().x / 4, spritesheet.getSize().y / 4));
            player.setPosition(pos.x, pos.y);
            Screen.draw(player);

            // Show the screen:
            Screen.display();
        }
« Last Edit: February 08, 2013, 12:20:12 pm by WhiteWind »

fatum

  • Newbie
  • *
  • Posts: 47
    • MSN Messenger - bowsers7@hotmail.com
    • AOL Instant Messenger - therealblah569
    • View Profile
    • http://boards.psynetfm.com
Re: How to make things happen for a duration of time? / Pokémon movement
« Reply #1 on: February 08, 2013, 12:43:46 pm »
You could use an sf::Clock object before you call your sprite's setTextureRect(); method.  Here's an example:

Code: [Select]
sf::Clock animateTime;

if (animateTime.getElapsedTime().asMilliseconds() >= 50)
{
        player.setTextureRect(sf::IntRect(src.x, src.y, spritesheet.getSize().x / 4, spritesheet.getSize().y / 4));
animateTime.restart();
}

Good luck!

WhiteWind

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: How to make things happen for a duration of time? / Pokémon movement
« Reply #2 on: February 08, 2013, 01:20:12 pm »
I tried messing around with that before, I kinda got somewhere but not completely. I tested with pos.x += moveSpeed; in the game loop, then did if(clock.getElapsedTime() >= duration) moveSpeed = 0;. That made my character move right for a duration (1 second for example) then stop - which is part of what I want. I'm not sure how to trigger that for if you hit a key though. I tried putting a keypress check around it, but then it just didn't move and when I pressed the key it moved like normal - ie didn't automatically move then stop.

As for your suggestion, it didn't effect anything. The section you've wrapped the test around is just for finding the correct area to draw, I think you mean to put it around if(moving) src.x += spritesheet.getSize().x / 4;. It still doesn't limit the animation though. :/
« Last Edit: February 08, 2013, 01:22:43 pm by WhiteWind »

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: How to make things happen for a duration of time? / Pokémon movement
« Reply #3 on: February 08, 2013, 04:49:03 pm »
I recently wrote a class for frame-based sprite animations. You can find the source code on the wiki. It's under the same license as SFML so you can either use it directly or take a look at the code and copy the technique. I use a sf::Time object which is updated with the frame time.

WhiteWind

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: How to make things happen for a duration of time? / Pokémon movement
« Reply #4 on: February 08, 2013, 05:45:35 pm »
That is WAY more work than I would have thought, though your class seems pretty versatile. I'm just trying to get my specific game up and running, I won't be making anything as detailed. I'll to have to look through it for a while though because I don't like using code that I don't fully understand. Thanks for posting it, it'll be useful.