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

Author Topic: moving a character through a class and a spritesheet class  (Read 9778 times)

0 Members and 1 Guest are viewing this topic.

Engineer

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: moving a character through a class and a spritesheet class
« Reply #15 on: August 15, 2013, 02:03:12 am »
I'm so dumb I had to forget that I needed to push_back the sprite. Forgive me.
Problem now is that my sprites got a white background (even if those are transparent background!) and they don't move when I press the keys up/down/right/left :(
working code:
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <string>
#include <vector>

#define SIZE 12

sf::Event event;

class Spritesheet
{
    public:
    sf::Sprite mainSprite;
    sf::Texture textureHero[SIZE];
    int vectorPX[SIZE];
    int vectorPY[SIZE];
    void setVectorSprite(int vectorX[SIZE], int vectorY[SIZE]);
    std::vector<sf::Sprite> & getVectorSprite();
    sf::Sprite & getVectorSpriteJ(int j);
    std::string filenameS;
    std::vector<sf::Sprite> vectorSprite;

    private:
    //std::vector<sf::Sprite> vectorSprite;


};




class Hero
{
public:
    Spritesheet spriteSheetHero;
    void setHealth(int health);
    int & getlastX();
    int & getlastY();
    void setPos(int posX, int posY);

private:
    int healthH;
    int lastposX, lastposY;
    int curX, curY;


};



int main()
{
    sf::Clock clock;
    sf::Time elapse;
    // sf::Time elapse;
    // elapse = clock.getTimeElapsed();
    sf::RenderWindow window(sf::VideoMode(800,600), "SFML Hero");
    // window.setFramerateLimit(10);
    while(window.isOpen())
    {
        while(window.pollEvent(event))
        {
            switch(event.type)
            {
                case sf::Event::Closed:
                window.close();
                break;

                default:
                break;
            }

        }
        window.clear(sf::Color::White); // orange = sf::Color(250,127,0)
        // setting the hero
        Hero hero;
        hero.setHealth(100);
        int testX[SIZE] = { 14, 49, 78, 109, 170, 360, 536, 695, 861, 1020, 1145, 1180 };
        int testY[SIZE] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
        hero.spriteSheetHero.setVectorSprite(testX, testY );
        hero.spriteSheetHero.mainSprite.setTexture(*((hero.spriteSheetHero.getVectorSpriteJ(2)).getTexture()));

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
        {
            elapse = clock.getElapsedTime();
            hero.spriteSheetHero.mainSprite.setTexture(*((hero.spriteSheetHero.getVectorSpriteJ(1)).getTexture()));
            hero.spriteSheetHero.mainSprite.move(-10, 0);
            if(elapse.asMilliseconds() == 300)
            {
                hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(4)).getTexture());
            }
            if(elapse.asMilliseconds() == 600)
            {
                hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(5)).getTexture());
                clock.restart();
            }
        }
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
        {
            elapse = clock.getElapsedTime();
            hero.spriteSheetHero.mainSprite.setTexture(*((hero.spriteSheetHero.getVectorSpriteJ(3)).getTexture()));
            hero.spriteSheetHero.mainSprite.move(10, 0);
            if(elapse.asMilliseconds() == 300)
            {
                hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(10)).getTexture());
            }
            if(elapse.asMilliseconds() == 600)
            {
                hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(11)).getTexture());
            }
            clock.restart();
        }
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
        {
            elapse = clock.getElapsedTime();
            hero.spriteSheetHero.mainSprite.setTexture(*((hero.spriteSheetHero.getVectorSpriteJ(0)).getTexture()));
            hero.spriteSheetHero.mainSprite.move(0, 10);
            if(elapse.asMilliseconds() == 300)
            {
                hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(8)).getTexture());
            }
            if(elapse.asMilliseconds() == 600)
            {
                hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(9)).getTexture());
            }
            clock.restart();
        }
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
        {
            elapse = clock.getElapsedTime();
            hero.spriteSheetHero.mainSprite.setTexture(*(((hero.spriteSheetHero.getVectorSpriteJ(2)).getTexture())));
            hero.spriteSheetHero.mainSprite.move(0, -10);
            if(elapse.asMilliseconds() == 300)
            {
                hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(6)).getTexture());
            }
            if(elapse.asMilliseconds() == 600)
            {
                hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(7)).getTexture());
            }
            clock.restart();
        }
        hero.setPos(100,100);
        window.draw(hero.spriteSheetHero.mainSprite);

        window.display();
    }
    return 0;

}

void Hero::setHealth(int health)
{
    healthH = health;
}

void Spritesheet::setVectorSprite(int vectorX[3], int vectorY[3])
{
    sf::Sprite spritetest;
    for(int i = 0; i < SIZE; i++)
    {
        vectorPX[i] = vectorX[i];
        vectorPY[i] = vectorY[i];
        textureHero[i].loadFromFile("spritesheet.png", sf::IntRect(vectorX[i] ,vectorY[i] ,18 , 26 ));
        //getVectorSpriteJ(i).setTexture(textureHero[i]);
        spritetest.setTexture(textureHero[i]);
        getVectorSprite().push_back(spritetest);
    }
}


std::vector<sf::Sprite> & Spritesheet::getVectorSprite()
{
    return vectorSprite;
}

int & Hero::getlastX()
{
    return lastposX;
}

int & Hero::getlastY()
{
    return lastposY;
}

void Hero::setPos(int posX, int posY)
{
    curX = posX;
    curY = posY;
    spriteSheetHero.mainSprite.setPosition(curX, curY);
}

sf::Sprite & Spritesheet::getVectorSpriteJ(int j)
{
    return vectorSprite[j];
}

 

But the sprites can't move :/
« Last Edit: August 15, 2013, 02:32:36 am by Engineer »

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: moving a character through a class and a spritesheet class
« Reply #16 on: August 15, 2013, 02:37:48 am »
That might be because of the hero.setPos(100,100); line just after you finish processing all the keyboard input.

Incidentally, you should learn to use a debugger. If you stepped through your code after it detected a key press you'd have very quickly noticed the erroneous setPos line.
« Last Edit: August 15, 2013, 02:39:34 am by Ixrec »

Engineer

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: moving a character through a class and a spritesheet class
« Reply #17 on: August 15, 2013, 02:42:59 am »
had seen that long ago before your post and removed and still doesn't work... :(
also, I'm using this spritesheet http://www.spriters-resource.com/gameboy_advance/lozminish/sheet/6369/ and its transparent but when displaying sprite, background is white. If somebody can tell me if the spritesheet is really transparent or not, I will need to do a sf::Image for each sprite and remove mask, that would be boring :(
« Last Edit: August 15, 2013, 02:50:06 am by Engineer »

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: moving a character through a class and a spritesheet class
« Reply #18 on: August 15, 2013, 03:05:41 am »
Or you could get a decent image editor like Paint.net and make those sections transparent yourself.  Just click the white parts with the magic wand tool and use ctrl+x to delete those pixels (which in Paint.net makes them transparent).

Also, could you upload your spritesheet so I can test your code myself?

Engineer

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: moving a character through a class and a spritesheet class
« Reply #19 on: August 15, 2013, 12:21:09 pm »
Here you go http://imgur.com/P9rhBlx (by the way its just a test for my sprite). And thanks for the tip for PAINT.NET, I didn't know that :)

Engineer

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: moving a character through a class and a spritesheet class
« Reply #20 on: August 15, 2013, 12:32:35 pm »
I figured that if I put the intializations of the hero outside of the window.isOpen loop, it would make the character move, but if I remove the "hero.spriteSheetHero.mainSprite.setTexture(*((hero.spriteSheetHero.getVectorSpriteJ(2)).getTexture()));" it would make him disappear. Why is that?
Here is a code where you can move the character, also got one problem with my animation system :  it only display one frame of the two

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <string>
#include <vector>

#define SIZE 12

sf::Event event;

class Spritesheet
{
    public:
    sf::Sprite mainSprite;
    sf::Texture textureHero[SIZE];
    int vectorPX[SIZE];
    int vectorPY[SIZE];
    void setVectorSprite(int vectorX[SIZE], int vectorY[SIZE]);
    std::vector<sf::Sprite> & getVectorSprite();
    sf::Sprite & getVectorSpriteJ(int j);
    std::string filenameS;
    std::vector<sf::Sprite> vectorSprite;

    private:
    //std::vector<sf::Sprite> vectorSprite;


};




class Hero
{
public:
    Spritesheet spriteSheetHero;
    void setHealth(int health);
    int & getlastX();
    int & getlastY();
    void setPos(int posX, int posY);

private:
    int healthH;
    int lastposX, lastposY;
    int curX, curY;


};



int main()
{
    sf::Clock clock;
    sf::Time elapse;
    Hero hero;
    hero.setHealth(100);
    int testX[SIZE] = { 14, 49, 78, 109, 170, 360, 536, 695, 861, 1020, 1145, 1180 };
    int testY[SIZE] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
    hero.spriteSheetHero.setVectorSprite(testX, testY );
    sf::RenderWindow window(sf::VideoMode(800,600), "SFML Hero");
    window.setFramerateLimit(30);
    while(window.isOpen())
    {
        while(window.pollEvent(event))
        {
            switch(event.type)
            {
                case sf::Event::Closed:
                window.close();
                break;

                default:
                break;
            }

        }
        window.clear(sf::Color(250,127,0)); // orange = sf::Color(250,127,0)
        hero.spriteSheetHero.mainSprite.setTexture(*((hero.spriteSheetHero.getVectorSpriteJ(2)).getTexture()));
        // setting the herz
        clock.restart();
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
        {
            elapse = clock.getElapsedTime();
            hero.spriteSheetHero.mainSprite.setTexture(*((hero.spriteSheetHero.getVectorSpriteJ(1)).getTexture()));
            hero.spriteSheetHero.mainSprite.move(-5, 0);
                if(elapse.asMilliseconds() <= 300)
                {
                    hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(4)).getTexture());
                }
                if(elapse.asMilliseconds() >= 600)
                {
                    hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(5)).getTexture());
                    clock.restart();
                }
        }
        clock.restart();
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
        {
            elapse = clock.getElapsedTime();
            hero.spriteSheetHero.mainSprite.setTexture(*((hero.spriteSheetHero.getVectorSpriteJ(3)).getTexture()));
            hero.spriteSheetHero.mainSprite.move(5, 0);
                if(elapse.asMilliseconds() <= 300)
                {
                    hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(10)).getTexture());
                }
                if(elapse.asMilliseconds() >= 600)
                {
                    hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(11)).getTexture());
                    clock.restart();
                }
        }
        clock.restart();
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
        {
            elapse = clock.getElapsedTime();
            hero.spriteSheetHero.mainSprite.setTexture(*((hero.spriteSheetHero.getVectorSpriteJ(0)).getTexture()));
            hero.spriteSheetHero.mainSprite.move(0, 5);
                if(elapse.asMilliseconds() <= 300)
                {
                    hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(8)).getTexture());
                }
                if(elapse.asMilliseconds() >= 600)
                {
                    hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(9)).getTexture());
                    clock.restart();
                }
        }
        clock.restart();
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
        {
            elapse = clock.getElapsedTime();
            hero.spriteSheetHero.mainSprite.setTexture(*(((hero.spriteSheetHero.getVectorSpriteJ(2)).getTexture())));
            hero.spriteSheetHero.mainSprite.move(0, -5);

                if(elapse.asMilliseconds() <= 300)
                {
                    hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(6)).getTexture());
                }
                if(elapse.asMilliseconds() >= 600)
                {
                    hero.spriteSheetHero.mainSprite.setTexture(*(hero.spriteSheetHero.getVectorSpriteJ(7)).getTexture());
                    clock.restart();
                }
        }
        clock.restart();
        window.draw(hero.spriteSheetHero.mainSprite);

        window.display();
    }
    return 0;

}

void Hero::setHealth(int health)
{
    healthH = health;
}

void Spritesheet::setVectorSprite(int vectorX[3], int vectorY[3])
{
    sf::Sprite spritetest;
    for(int i = 0; i < SIZE; i++)
    {
        vectorPX[i] = vectorX[i];
        vectorPY[i] = vectorY[i];
        textureHero[i].loadFromFile("spritesheet.png", sf::IntRect(vectorX[i] ,vectorY[i] ,18 , 26 ));
        spritetest.setTexture(textureHero[i]);
        getVectorSprite().push_back(spritetest);
    }
}


std::vector<sf::Sprite> & Spritesheet::getVectorSprite()
{
    return vectorSprite;
}

int & Hero::getlastX()
{
    return lastposX;
}

int & Hero::getlastY()
{
    return lastposY;
}

void Hero::setPos(int posX, int posY)
{
    curX = posX;
    curY = posY;
    spriteSheetHero.mainSprite.setPosition(curX, curY);
}

sf::Sprite & Spritesheet::getVectorSpriteJ(int j)
{
    return vectorSprite[j];
}
 

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: moving a character through a class and a spritesheet class
« Reply #21 on: August 15, 2013, 05:40:09 pm »
That line should also be outside the isOpen loop in the initialization block, because it's giving the hero his initial sprite.  With it there, he always reverts to that same sprite when you stop holding a key.  If it's not there at all, then he has no initial sprite, which I assume is what you meant by "make him disappear," even though simply pressing an arrow key will give him a sprite.

The movement/animation stuff is a totally different set of issues.  Basically, your code is trying to assume that certain things always take the exact same amount of time, and that just isn't true.
1) You have if statements testing if *exactly* 30 or *exactly* 60 milliseconds have passed.  Nothing but dumb luck determines whether that happens or not.
2) Not only that, but your tests for whether to use the "running" sprites use only the elapsed time since the previous frame.  It doesn't make any sense to use that as a running test.  What you should be doing is keeping track of how long the key has been pressed (say, adding elapse to a variable like "up_held_for") and then use the other sprites based on that value (you might use a condition like up_held_for%1000 > 300)
3) Perhaps most important, you have your character move 10 pixels every frame.  Not only is that probably a lot faster than you want, but frames don't always take the same amount of time.  You need to multiply the speed by the elapsed time between frames so that you get the same movement speed regardless of framerate (that or you can try artificially limiting the framerate, but I don't really understand why people like to do that).

Engineer

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: moving a character through a class and a spritesheet class
« Reply #22 on: August 15, 2013, 09:16:10 pm »
Thanks, I removed the line,
maked one variable for each key pressed (a, b, c, d) for which I add the elapsed time as milliseconds,
changed the speed to 5 pixels, but animation still doesn't work :(
Here is the code:

hipsterdufus

  • Newbie
  • *
  • Posts: 28
    • View Profile
    • Email
Re: moving a character through a class and a spritesheet class
« Reply #23 on: August 16, 2013, 08:41:43 am »
I would guess you're not seeing any animation because

<code>
        clock.restart();
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
        {
            elapse = clock.getElapsedTime();

</code>

since you reset your clock right before you set elapse the time passed is always going to be very small. Just a quick guess from glancing at your code.