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

[SFML / Code::Blocks / Tiled] 캐릭터 스프라이트 애니메이션 및 컨트롤 테스트와 Tiled 맵 작업 (Top-Down RPG Game Style Map 탑-다운 롤플레잉 게임 형식 맵)

by byungwoo733 2023. 4. 29.
728x90
반응형
SMALL

캐릭터 스프라이트 애니메이션 및 컨트롤 테스트와 Tiled 맵 작업 (Top-Down RPG Game Style Map 탑-다운 롤플레잉 게임 형식 맵)

캐릭터 사이즈 128px X 128px

코드는 전과 동일

#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;
}

 

 

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

테스트용 Tiled 맵 작업 사진 (추후 맵을 tmx파일로 만들고 프로그래밍 언어에 맞게 지원하는 라이브러리로 import해서 프로그래밍 작업)

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

Tiled 맵 완성 사진 (테스트용이라서 대충 작업)

[Top-Down RPG 형식 Tile Map 1]

--------------------------------------------------

[Top-Down RPG 형식 Tile Map 2]

 

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

728x90
LIST

댓글