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

Author Topic: Card flipping animation  (Read 5418 times)

0 Members and 1 Guest are viewing this topic.

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
Card flipping animation
« on: August 26, 2014, 08:48:36 am »
I'm making a memory game and I'd like to animate flipping over a card. A card is just an sf::Sprite.

The card (or: sprite) should revolve around its own axis, maybe something like this http://davidwalsh.name/demo/css-flip.php but I haven't found any code that could help me.

sf::Sprite::rotate exists and it rotates the sprite, but I need a rotation around the sprite's y-axis.

Can someone please help me?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Card flipping animation
« Reply #1 on: August 26, 2014, 08:55:00 am »
There's no way to do this with SFML, the graphics module only supports 2D operations in the XY plane. You'll have to use plain OpenGL, or fake the rotation with an animation (probably overkill, especially if you have to do it for every card).
Laurent Gomila - SFML developer

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
Re: Card flipping animation
« Reply #2 on: August 26, 2014, 09:01:51 am »
Hm, I see, thanks. I'll look into OpenGL then.

Stauricus

  • Sr. Member
  • ****
  • Posts: 369
    • View Profile
    • A Mafia Graphic Novel
    • Email
Re: Card flipping animation
« Reply #3 on: August 26, 2014, 03:03:56 pm »
you could shrink the card sprite, creating an illusion.
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
int main(){
    sf::RenderWindow window(sf::VideoMode(170, 225, 32), "Card");
    sf::Texture texture;
    texture.loadFromFile("queenst.gif");
    sf::Sprite sprite(texture);
    while(window.isOpen()){
        sf::Event event;
        while(window.pollEvent(event)){
            if( event.type == sf::Event::Closed){
                window.close();
            }
        }
        for (int s=100; s>=0; s--){
            sprite.setScale(s*0.01, 1);
            sprite.setPosition(window.getSize().x/2-sprite.getGlobalBounds().width/2, 0);
            window.clear();
            window.draw(sprite);
            window.display();
        }
    }
    return 0;
}



it's just an idea, you'd have to fix and finish the code.
Visit my game site (and hopefully help funding it? )
Website | IndieDB

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Card flipping animation
« Reply #4 on: August 26, 2014, 04:48:42 pm »
I think this would be possible to get an "acceptable" effect using a VertexArray and animating the corners elliptically, depending on your level of acceptability as there would be no perspective and both sides must be animated equally as a mirror otherwise there will be texture distortion.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
Re: Card flipping animation
« Reply #5 on: August 27, 2014, 01:56:19 am »
you could shrink the card sprite, creating an illusion.


it's just an idea, you'd have to fix and finish the code.

Thanks, that actually looks pretty good. I'll see if I can use that and report back

I think this would be possible to get an "acceptable" effect using a VertexArray and animating the corners elliptically, depending on your level of acceptability as there would be no perspective and both sides must be animated equally as a mirror otherwise there will be texture distortion.

Yeah but I reckon it's going to be a lot of work

moonfirefly

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Card flipping animation
« Reply #6 on: August 27, 2014, 04:52:16 am »
I think I got the rotation around y-axis to fly but it only works on origin, which makes it rather useless.

This example generates a pattern texture sprite and rotates it on y-axis in the top left corner:
(click to show/hide)

I was not able to blend the center translation in the matrix as it is done in the Transform::rotate method, doing so might solve the problem:
(click to show/hide)

With that said, seems Transformable::getTransform() does not support rotation other than z axis:
(click to show/hide)

Was worth the shot, I need something similar in a project. Someone with math skills might make it work  :P
Blokade: Source

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: Card flipping animation
« Reply #7 on: August 27, 2014, 11:52:16 am »
Just a quick hacked together example for a card spinning effect (source and example images are attached):

#include <SFML/Graphics.hpp>
#include <cmath>

int main(int argc, char **argv) {
        sf::RenderWindow window(sf::VideoMode(256, 256), "SPACE to Flip!");
       
        sf::Texture front;
        front.loadFromFile("front.png");
       
        sf::Texture back;
        back.loadFromFile("back.png");
       
        sf::Sprite cardFace(front);
        cardFace.setOrigin(36, 48); // Move origin to center of card
        cardFace.setPosition(128, 128); // Move card to center of window
       
        sf::Sprite cardBack(back);
        cardBack.setOrigin(36, 48); // Move origin to center of card
        cardBack.setPosition(128, 128); // Move card to center of window
       
        // Used to determine current status
        bool frontShown = false;
        char spindir = 0; // 0 -> don't spin, 1 -> show, -1 -> hide
        sf::Time currentTime = sf::Time::Zero;
       
       
        const sf::Time spinTime = sf::seconds(1);
        const sf::Time halfSpinTime = spinTime / 2.f;
        const float pi = std::acos(-1);
       
        sf::Event event;
        sf::Clock clock;
        while (window.isOpen()) {
                while (window.pollEvent(event)) {
                        if (event.type == sf::Event::Closed)
                                window.close();
                        else if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space && !spindir) {
                                if (frontShown)
                                        spindir = -1;
                                else
                                        spindir = 1;
                        }
                }
                window.clear(sf::Color(0, 127, 127));
                sf::Time delta = clock.restart();
                if (spindir == 1) {
                        if (currentTime < spinTime - delta)
                                currentTime += delta;
                        else {
                                currentTime = spinTime;
                                spindir = 0;
                        }
                }
                else if (spindir == -1) {
                        if (currentTime > delta)
                                currentTime -= delta;
                        else {
                                currentTime = sf::Time::Zero;
                                spindir = 0;
                        }
                }
               
                frontShown = currentTime >= spinTime / 2.f;
               
                if (frontShown) {
                        // Just scale the sprite based on time:
                        float scale = (currentTime - halfSpinTime) / halfSpinTime;
                       
                        // The upscaling is really optional
                        cardFace.setScale(std::sin(scale * pi / 2) * 2, 2);
                        window.draw(cardFace);
                }
                else {
                        // Same here
                        float scale = 1.f - currentTime / halfSpinTime;
                        cardBack.setScale(std::sin(scale * pi / 2) * 2, 2);
                        window.draw(cardBack);
                }
                window.display();
        }
        return 0;
}

Note that the sinus calculation for scaling is really optional. Not doing it (i.e. just pass the linear scaling as scale) works as well, although it will result in slightly different animation speed).

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
Re: Card flipping animation
« Reply #8 on: August 27, 2014, 12:43:29 pm »
@Mario

Your example looks neat.

I put together something similar based on Stauricus's answer but it's not as good as your code. I'll use it if you don't mind?

By the way, your code won't compile for me. In lines 67 and 75 (float scale = ...) I had to add .asSeconds() to all the time variables but now it's working fine.

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: Card flipping animation
« Reply #9 on: August 27, 2014, 01:08:10 pm »
I wouldn't post it, if I'd mind someone reusing my code. ;)

I've been using latest master revision from GitHub, it's possible that you had to make the adjustments, if you're using an older version.