Melhor animação de elementos em SFML / C ++

7

Não se trata de animar personagens ou elementos individuais, estou feliz com as planilhas para isso. O que estou procurando é a animação de elementos na tela.

Por exemplo, meu jogo começa e o logotipo sai voando de uma direção aleatória, depois gira ou algo assim e para em uma posição; um personagem do jogo (um ou mais) sai do lado e faz alguma ação.

Ainda não fiz muitos projetos, escrevi apenas um jogo completo, por isso não sei se redigi corretamente a pergunta.

O que venho fazendo é dar ao elemento uma posição inicial e final e fazê-lo mover-se de acordo e usar sinalizadores de status para verificar seu estado. O problema é quando eu quero movê-lo de mais de uma maneira. Claro, eu posso apenas usar as variáveis ​​de estado e fazê-lo se mover, mas eu estive pensando que deve haver um método elegante para isso

EDIT: Estou vendo animações como no World of Goo etc.

tecfreak
fonte

Respostas:

4

Parece que você deseja manipular a posição e a rotação dos objetos ao longo do tempo. O AFAIK sfml não fornece essa funcionalidade imediatamente, mas deve ser bastante fácil e direto implementá-la por conta própria.

Certa vez, construí uma solução semelhante para uma simulação tridimensional, mas ela deve se traduzir bem em uma aplicação gráfica 2D.

Primeiro de você tem dois conceitos: o Manipulatore o acordo ManipulatorManager. Manipulatoré uma classe base abstrata para todos os tipos de manipulações de um objeto específico, por exemplo, um sprite. Manipuladas podem ser todas as propriedades, como posição ou rotação, mover-se em um caminho ou algo semelhante. O Managervigia o estado da Manipulatorse atualiza-los cada frame.

A interface do manipulador se parece com isso:

class Manipulator {
public:
    Manipulator(float expiration_time) : expiration_time(expiration_time);
    bool is_expired() { return expiration_time < 0.f; }
    void update(float dt) { this->expiration_time -= dt; }
protected:
    float expiration_time;
}

Uma implementação dessa classe é a SimpleLineManipulatorque influencia a posição de um sprite em um determinado período em uma linha reta:

class SimpleLineManipulator {
    SimpleLineManipulator(Sprite *spr, Vector2f begin, Vector2f end, float expiration_time);
    ...
private:
    Sprite* sprite;
    Vector2f begin, end;
    float total_time; // initialized with expiration_time
}

E é assim que o método de atualização se parece (onde ocorre a maior parte do trabalho):

void SimpleLineManipulator::update(float dt) {
    Manipulator::update(dt);
    Vector2f position = lerp(end, begin, total_time/expiration_time);
    spr->SetPosition(position.x, position.y);
}

Tudo o que você precisa fazer agora é chamar o update()método de cada quadro. Deve ser fácil implementar um manipulador rotatório ou manipuladores que funcionem em um caminho (uma lista de posições). Agora você também pode combinar esses manipuladores para criar efeitos combinados.

Espero poder delinear a arquitetura de uma maneira clara. Sinta-se a vontade para perguntar :)

Constantinius
fonte
Essa foi uma boa explicação! Obrigado. Apenas uma pergunta rápida, as classes de elemento devem herdar da classe Manipulator?
tecfreak
1

Constantinius já fornece um bom ponto de partida de onde você pode começar com a codificação real, mas caso queira saber sobre o que está fazendo aqui em geral, gostaria de adicionar algumas palavras.

A conversão de objetos ao longo do tempo do ponto A ao ponto B é feita aplicando uma função f (x) à posição do objeto, onde x pode ser qualquer coisa, variando simplesmente da posição atual do sprite até a quantidade de tempo decorrido entre dois quadros, etc.

Esse processo geralmente é realizado com a ajuda de um subcampo de análise numérica, chamado interpolação.

Um exemplo comum seria a interpolação linear. Se você conhece o ponto inicial constante A e o ponto final B, uma função possível seria simplesmente f (t) = A + (B - A) * (t_max - t), em que

  • t é o tempo decorrido desde que o objeto foi iniciado a partir do ponto A
  • t_max é o tempo que você deseja que o objeto demore até chegar ao seu destino
  • 0 <= t <= t_máx.

Como você vê, a função está retornando um vetor, para que você possa aplicá-lo à posição do seu objeto sem problemas.

É claro que esta é apenas uma introdução aproximada para talvez você provar um pouco de sangue e despertar seu interesse, portanto, eu o redirecionarei para o Google se você quiser saber mais sobre isso.

TravisG
fonte
Obrigado pela sua resposta! Eu estava pensando o que lerp estava na resposta de Constantinius e você acertou exatamente nesse ponto!
tecfreak