본문 바로가기
Game Programming Study 게임 개발 프로그래밍 공부

[SFML / Code::Blocks] example Man (Player) Spritesheet Test example Man (플레이어) 스프라이트시트 테스트

by byungwoo733 2023. 3. 3.
728x90
반응형
SMALL

SFML으로 example Man (플레이어) Spritesheet Test

게임 리소스 관리를 위해서 파일 분할 main.cpp (main loop, window, input 등등), player.cpp, player.h(.hpp) 파일

Packed Sprite를 Sprite 픽셀 사이즈에 맞춰 수정 필요 (SDL2 역시 똑같이 정리해야함)

Character(const sf::Vector2f& pos)
        :
        pos(pos)
    {

        sprite.setTextureRect({0,0,152,152});
        animations[int( AnimationIndex::WalkingUp )] = Animation(152,0,152,152);
        animations[int( AnimationIndex::WalkingDown )] = Animation(152,304,152,152);
        animations[int( AnimationIndex::WalkingLeft )] = Animation(152,152,152,152);
        animations[int( AnimationIndex::WalkingRight )] = Animation(152,456,152,152);
    }

#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include <chrono>
#include <iostream>
#include <SFML/Window.hpp>

using namespace sf;

class Animation
{
public:
    Animation() = default;
    Animation(int x, int y, int width, int height)
    {
        texture.loadFromFile("images/example_man_pack1.png");
        for(int i = 0; i < nFrames; i++)
        {
            frames[i] = {x + i * width,y,width,height};
        }
    }
    void ApplyToSprite(sf::Sprite& s) const
    {
        s.setTexture(texture);
        s.setTextureRect( frames[iFrame]);
    }
    void Update(float dt)
    {
        time += dt;
        while( time >= holdTime)
        {
            time -= holdTime;
            Advance();
        }
    }
private:
    void Advance()
    {
        if( ++iFrame >= nFrames )
        {
            iFrame = 0;
        }
    }
private:
    static constexpr int nFrames = 8;
    static constexpr float holdTime = 0.1f;
    sf::Texture texture;
    sf::IntRect frames[nFrames];
    int iFrame = 0;
    float time = 0.0f;
};

class Character
{
private:
    enum class AnimationIndex
    {
        WalkingUp,
        WalkingDown,
        WalkingLeft,
        WalkingRight,
        Count
    };
public:
    Character(const sf::Vector2f& pos)
        :
        pos(pos)
    {

        sprite.setTextureRect({0,0,152,152});
        animations[int( AnimationIndex::WalkingUp )] = Animation(152,0,152,152);
        animations[int( AnimationIndex::WalkingDown )] = Animation(152,304,152,152);
        animations[int( AnimationIndex::WalkingLeft )] = Animation(152,152,152,152);
        animations[int( AnimationIndex::WalkingRight )] = Animation(152,456,152,152);
    }
    void Draw(sf::RenderTarget& rt) const
    {
        rt.draw(sprite);
    }
    void SetDirection(const sf::Vector2f& dir)
    {
        vel = dir * speed;
        if( dir.x > 0.0f)
        {
            curAnimation = AnimationIndex::WalkingRight;
        }
        else if( dir.x < 0.0f)
        {
            curAnimation = AnimationIndex::WalkingLeft;
        }
        else if( dir.y < 0.0f)
        {
            curAnimation = AnimationIndex::WalkingUp;
        }
        else if( dir.y < 0.0f)
        {
            curAnimation = AnimationIndex::WalkingDown;
        }
    }
    void Update( float dt)
    {
        pos += vel *dt;
        animations[int( curAnimation )].Update( dt );
        animations[int( curAnimation )].ApplyToSprite( sprite );
        sprite.setPosition(pos);
    }

private:
    static constexpr float speed = 100.0f;
    sf::Vector2f pos;
    sf::Vector2f vel = {0.0f,0.0f};
    sf::Sprite sprite;
    Animation animations[int( AnimationIndex::Count )];
    AnimationIndex curAnimation = AnimationIndex::WalkingDown;
};
int main()
{
    // Create the main window
    sf::RenderWindow window(sf::VideoMode(1280, 720), "SFML window");

    Character fucker({100.0f, 100.0f});

    // timepoint for delta time measurement
    auto tp = std::chrono::steady_clock::now();

    // Load a sprite to display

    Texture textureBackground;
    textureBackground.loadFromFile("images/bg.png");
    return EXIT_FAILURE;
    sf::Texture texture;
    texture.loadFromFile("images/example_man_pack1.png");
    sprite.setTextureRect({0,0,152,152});

    // Start the game loop
    while (window.isOpen())
    {
        // Process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            // Close window: exit
            if (event.type == sf::Event::Closed)
                window.close();
        }

        // get dt
        float dt;
        {
            const auto new_tp = std::chrono::steady_clock::now();
            dt = std::chrono::duration<float>(new_tp - tp).count();
            tp = new_tp;
        }

        // handle input
        sf::Vector2f dir = { 0.0f, 0.0f};
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
        {
            dir.y -= 1.0f;
        }
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
        {
            dir.y += 1.0f;
        }
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
        {
            dir.x -= 1.0f;
        }
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
        {
            dir.x += 1.0f;
        }
        fucker.SetDirection(dir);

        //update model
        fucker.Update(dt);
        // Clear screen
        window.clear();
        // Draw the sprite
        fucker.Draw(window);
        // Update the window
        window.display();
    }
    return EXIT_SUCCESS;
}

=============================

sfml_player_test1

 

sfml_player_test2 (touch Input event)

 

 

* (주의) 여기 예제나 글들은 게임개발에 도움이 되는 정보 보다는 개인 공부을 위한 것이어서 옳은 방법이 아닐 수 있으니 참고바랍니다.

728x90
LIST

댓글