SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › непонятки в setOrigin › Ответ в теме: непонятки в setOrigin
*Headbang* Sprite::setTextureRect принимает в качестве аргумента IntRect который указывает с какого места текстуры нужно брать картинку.
Ну и мы же используем язык по большей части ориентированый на ООП, дак почему же нам не использовать это?
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
//AnimatedSprite.h /// \brief A sprite that can be animated by Animation objects. class AnimatedSprite : public sf::Sprite { public: /// \brief Default Constructor. AnimatedSprite(); ~AnimatedSprite(); /// \brief Add an animation to the sprite. void addAnimation(const std::string& name, Animation animation); /// \brief Remove an animation. void removeAnimation(const std::string& name); /// \brief Play an animation. Optional looping parameter. void playAnimation(const std::string& name, bool loop = false); /// \brief Stops the currently running animation. void stopAnimation(); /// \brief Returns true if a animation is currently being played bool isAnimationPlaying(); /// \brief Returns the name of the playing animation std::string getCurrentAnimationName(); /// \brief Updates the sprite. Should be called every frame. /// or by param 's' you can get void update(sf::Time frameTime, int Frames = -1); private: std::map<std::string, Animation> animations; std::string currentAnimation; bool looping; }; |
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
//AnimatedSprite.cpp #include "AnimatedSprite.h" AnimatedSprite::AnimatedSprite() : looping(false), currentAnimation("") { //ctor } AnimatedSprite::~AnimatedSprite() { //dtor } void AnimatedSprite::addAnimation(const std::string& name, Animation animation) { animations[name] = animation; } void AnimatedSprite::removeAnimation(const std::string& name) { auto pos = animations.find(name); if(pos != animations.end()) animations.erase(pos); } void AnimatedSprite::playAnimation(const std::string& name, bool loop) { if(animations.find(name) != animations.end()) { currentAnimation = name; looping = loop; } } void AnimatedSprite::stopAnimation() { currentAnimation = ""; } bool AnimatedSprite::isAnimationPlaying() { return (!currentAnimation.empty()); } std::string AnimatedSprite::getCurrentAnimationName() { return currentAnimation; } void AnimatedSprite::update(sf::Time frameTime,int Frame) { if(!currentAnimation.empty()) //Are we actually running an animation? { if(!animations[currentAnimation].update(frameTime, Frame) && !looping) //If the animation is finished and we are not looping, stop the animation. currentAnimation = ""; else //Else we just update our subrect setTextureRect(animations[currentAnimation].getCurrentFrame()); } } |
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
//Animation.h #ifndef ANIMATION_H #define ANIMATION_H #include <SFML/System/Time.hpp> #include <SFML/Graphics/Rect.hpp> #include <vector> /// \brief A class that stores animation data. class Animation { friend class AnimatedSprite; public: /// \brief Constructor. Animation(sf::Time duration = sf::Time::Zero, bool Manual = false); ~Animation(); /// \brief Sets the duration of the animation. void setDuration(sf::Time duration); /// \brief Add a frame to the animation. /// /// A frame is actually just an IntRect object which specifies the subrectangle of the texture. void addFrame(sf::IntRect rect); /// \brief Add a siquence of frames to the animation. void addComplexyUpToDown(int frameCount, int W, int H, int xStart = 0, int yStart = 0); /// \brief Add a siquence of frames to the animation. void addComplexyLeftToRight(int frameCount, int W, int H, int xStart = 0, int yStart = 0); /// \brief Add a siquence of frames to the animation. void addComplexyRightToLeft(int frameCount, int W, int H, int xStart, int yStart); private: sf::IntRect getCurrentFrame(); bool update(sf::Time frametime, int Frames = -1); void reset(); bool manual; sf::Time duration; sf::Time passedTime; std::vector<sf::IntRect> frames; unsigned currentFrame; }; #endif // ANIMATION_H |
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
//Animation.cpp #include "Animation.h" Animation::Animation(sf::Time dur, bool Manual) : passedTime(sf::Time::Zero), currentFrame(0) { duration = dur; manual = Manual; } Animation::~Animation() { //dtor } void Animation::setDuration(sf::Time dur) { duration = dur; } bool Animation::update(sf::Time frametime, int Frames) { passedTime += frametime; if (!manual && Frames < 0) currentFrame = std::floor((passedTime.asSeconds()/duration.asSeconds()) * (frames.size()-1) + 0.5); else if (Frames == -2) { currentFrame++; if (currentFrame > frames.size()-1) { currentFrame = 0; return false; } } else if (Frames == -3) { currentFrame--; if (currentFrame < 0) { currentFrame = frames.size()-1; return false; } } else if (Frames > -1) { currentFrame = Frames; if (currentFrame > frames.size() - 1) { reset(); return false; } } if(passedTime > duration && !manual) { reset(); return false; } return true; } sf::IntRect Animation::getCurrentFrame() { return frames[currentFrame]; } void Animation::addFrame(sf::IntRect rect) { frames.push_back(rect); } void Animation::addComplexyLeftToRight(int frameCount, int W, int H,int xStart, int yStart) { for (int i = 1; i < frameCount; i++) { addFrame(sf::IntRect(xStart+(W*i-W),yStart,W,H)); } } void Animation::addComplexyRightToLeft(int frameCount, int W, int H, int xStart, int yStart) { for (int i = frameCount; i > 0; i--) { addFrame(sf::IntRect(xStart + (W*i - W), yStart, W, H)); } } void Animation::addComplexyUpToDown(int frameCount, int W, int H, int xStart, int yStart) { for (int i = 1; i < frameCount; i++) { addFrame(sf::IntRect(xStart, yStart + (H*i - H), W, H)); } } void Animation::reset() { passedTime = sf::Time::Zero; } |
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//Пример AnimatedSprite sprite = AnimatedSprite(); sprite.setTexture(texture);//Подгружаем текстуру как к обычному спрайту Animation anim1 = Animation(sf::milliseconds(1200));//В параметре указываем длительность анимации, сейчас 1,2 секунды anim1.addComplexyLeftToRight(7, 32, 64, 0, 65);//Можно добавлять и по кадрам, но этот метод позволяет добавлять кадры если они стоят в ряд куда проще //1 аргумент количество кадров, 2 - длинна каждого кадра, 3 - высота, 4 и 5 это оффсеты на текстуре по X и Y соответственно sprite.addAnimation("anim1", anim1);//Передаём анимацию спрайту с заданым именем. sprite.playAnimation("anim1");//Запускаем анимацю с заданым именем Clock clock; Time time = clock.restart(); sprite.update(time);//Ну и каждый тик спрайт автоматически подгонит нужный кадр если ему передавать время |