Как вы можете оживить спрайт в SFML - PullRequest
4 голосов
/ 21 апреля 2010

Допустим, у меня есть 4 изображения, и я хочу использовать эти 4 изображения для анимации персонажа. 4 изображения представляют ходьбу персонажа. Я хочу, чтобы анимация повторялась до тех пор, пока я нажимаю клавишу, чтобы двигаться, но останавливаться, когда я ее нажимаю. Если вы не знаете, это не обязательно должно быть специфично для SFML, просто базовая теория действительно помогла бы мне.

Спасибо.

Ответы [ 2 ]

10 голосов
/ 20 мая 2010

Вы можете захотеть какой-нибудь простой тип конечного автомата. Когда клавиша нажата (см. Метод IsKeyDown sf :: Input *1002*), поместите символ в «анимированное» состояние. Когда клавиша не нажата, персонаж находится в состоянии «без анимации». Конечно, вы всегда можете пропустить наличие этого «состояния» и просто делать то, что я упоминаю ниже (в зависимости от того, что именно вы делаете).

Затем, если персонаж находится в «анимированном» состоянии, получите следующее «изображение» (подробности см. В следующем абзаце). Например, если ваши изображения хранятся в простом массиве из 4 элементов, следующее изображение будет иметь значение (currentIndex + 1) % ARRAY_SIZE. В зависимости от того, что вы делаете, вы можете захотеть хранить ваши рамки изображений в более сложной структуре данных. Если персонаж не находится в «анимированном» состоянии, вы не будете обновлять его здесь.

Если ваши «4 изображения» находятся в одном и том же файле изображения, вы можете использовать метод sf :: Sprite SetSubRect , чтобы изменить часть отображаемого изображения. Если у вас на самом деле есть 4 разных изображения, то вам, вероятно, потребуется использовать метод sf :: Sprite SetImage для переключения изображений.

0 голосов
/ 05 октября 2018

Как бы вы увеличили частоту кадров, чтобы анимация не происходила слишком быстро?

Здравствуйте, посмотрите мой ответ здесь и примите это сообщение как лучшее решение.

https://stackoverflow.com/a/52656103/3624674

Вам необходимо указать длительность для каждого кадра и использовать общий прогресс для перехода к кадру.

В исходном файле анимации выполните

class Animation {
   std::vector<Frame> frames;
   double totalLength;
   double totalProgress;
   sf::Sprite *target;
   public:
     Animation(sf::Sprite& target) { 
       this->target = &target;
       totalProgress = 0.0;
     }

     void addFrame(Frame& frame) {
       frames.push_back(std::move(frame)); 
       totalLength += frame.duration; 
     }

     void update(double elapsed) {
        // increase the total progress of the animation
        totalProgress += elapsed;

        // use this progress as a counter. Final frame at progress <= 0
        double progress = totalProgress;
        for(auto frame : frames) {
           progress -= (*frame).duration;  

          // When progress is <= 0 or we are on the last frame in the list, stop
          if (progress <= 0.0 || &(*frame) == &frames.back())
          {
               target->setTextureRect((*frame).rect);  
               break; // we found our frame
          }
     }
};

Чтобы остановиться, когда вы нажимаете, просто анимируйте, только когда клавиша удерживается

if(isKeyPressed) {
    animation.update(elapsed); 
}

Для поддержки нескольких анимаций для разных ситуаций есть логическое значение для каждого состояния

bool isWalking, isJumping, isAttacking;

...

if(isJumping && !isWalking && !isAttacking) {
   jumpAnimation.update(elapsed);
} else if(isWalking && !isAttacking) {
   walkAnimation.update(elapsed);
} else if(isAttacking) { 
   attackAnimation.update(elapsed);
}

...

// now check for keyboard presses
if(jumpkeyPressed) { isJumping = true; } else { isJumping false; }
...