본문 바로가기
-----ETC-----/C++ 게임 개발 시리즈

[C++ 게임 개발 시리즈] Day 10: 애니메이션 기법 (프레임 기반 애니메이션)

by cogito21_cpp 2024. 8. 1.
반응형

애니메이션 기법 (프레임 기반 애니메이션)

애니메이션은 게임에서 캐릭터의 움직임, 환경의 변화 등을 생동감 있게 표현하는 중요한 요소입니다. 오늘은 프레임 기반 애니메이션 기법을 사용하여 애니메이션을 구현하는 방법을 학습하겠습니다.

프레임 기반 애니메이션

프레임 기반 애니메이션은 여러 개의 이미지(프레임)를 순차적으로 표시하여 움직임을 표현하는 방식입니다. 각 프레임은 일정한 시간 동안 화면에 표시되며, 모든 프레임이 순서대로 표시되면 하나의 애니메이션이 완성됩니다.

애니메이션 구현 예시

다음 예제에서는 SFML을 사용하여 간단한 캐릭터 애니메이션을 구현합니다.

  1. 텍스처와 스프라이트 설정

먼저, 애니메이션에 사용할 텍스처와 스프라이트를 설정합니다.

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <vector>

int main() {
    // 창 생성
    sf::RenderWindow window(sf::VideoMode(800, 600), "Frame-based Animation Example");

    // 텍스처 로드
    sf::Texture texture;
    if (!texture.loadFromFile("character_animation.png")) {
        std::cerr << "Error loading texture" << std::endl;
        return -1;
    }

    // 애니메이션 프레임 설정
    std::vector<sf::IntRect> frames;
    int frameWidth = 50;
    int frameHeight = 50;
    for (int i = 0; i < 4; i++) { // 4개의 프레임을 가정
        frames.push_back(sf::IntRect(i * frameWidth, 0, frameWidth, frameHeight));
    }

    // 스프라이트 생성
    sf::Sprite sprite;
    sprite.setTexture(texture);
    sprite.setPosition(400.0f, 300.0f); // 창 중앙에 위치
    sprite.setTextureRect(frames[0]); // 첫 번째 프레임으로 설정

    // 애니메이션 변수
    int currentFrame = 0;
    float frameTime = 0.1f; // 프레임 시간 (초)
    float elapsedTime = 0.0f;

    sf::Clock clock;

    // 게임 루프
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        // deltaTime 계산
        float deltaTime = clock.restart().asSeconds();
        elapsedTime += deltaTime;

        // 애니메이션 업데이트
        if (elapsedTime >= frameTime) {
            currentFrame = (currentFrame + 1) % frames.size();
            sprite.setTextureRect(frames[currentFrame]);
            elapsedTime = 0.0f;
        }

        // 화면 지우기
        window.clear();

        // 스프라이트 그리기
        window.draw(sprite);

        // 화면에 그리기
        window.display();
    }

    return 0;
}

애니메이션 클래스 구현

애니메이션을 더욱 체계적으로 관리하기 위해 애니메이션 클래스를 구현할 수 있습니다. 다음은 Animation 클래스를 구현한 예제입니다.

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <vector>

class Animation {
public:
    Animation(sf::Texture& texture, int frameWidth, int frameHeight, int numFrames, float frameTime)
        : texture(texture), frameTime(frameTime), currentFrame(0), elapsedTime(0.0f) {
        for (int i = 0; i < numFrames; i++) {
            frames.push_back(sf::IntRect(i * frameWidth, 0, frameWidth, frameHeight));
        }
        sprite.setTexture(texture);
        sprite.setTextureRect(frames[0]);
    }

    void update(float deltaTime) {
        elapsedTime += deltaTime;
        if (elapsedTime >= frameTime) {
            currentFrame = (currentFrame + 1) % frames.size();
            sprite.setTextureRect(frames[currentFrame]);
            elapsedTime = 0.0f;
        }
    }

    sf::Sprite& getSprite() {
        return sprite;
    }

private:
    sf::Texture& texture;
    std::vector<sf::IntRect> frames;
    sf::Sprite sprite;
    float frameTime;
    int currentFrame;
    float elapsedTime;
};

int main() {
    // 창 생성
    sf::RenderWindow window(sf::VideoMode(800, 600), "Animation Class Example");

    // 텍스처 로드
    sf::Texture texture;
    if (!texture.loadFromFile("character_animation.png")) {
        std::cerr << "Error loading texture" << std::endl;
        return -1;
    }

    // 애니메이션 객체 생성
    Animation animation(texture, 50, 50, 4, 0.1f);
    animation.getSprite().setPosition(400.0f, 300.0f); // 창 중앙에 위치

    sf::Clock clock;

    // 게임 루프
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        // deltaTime 계산
        float deltaTime = clock.restart().asSeconds();

        // 애니메이션 업데이트
        animation.update(deltaTime);

        // 화면 지우기
        window.clear();

        // 스프라이트 그리기
        window.draw(animation.getSprite());

        // 화면에 그리기
        window.display();
    }

    return 0;
}

결론

오늘은 프레임 기반 애니메이션 기법을 사용하여 애니메이션을 구현하는 방법을 학습했습니다. 스프라이트 애니메이션의 기본 개념과 이를 체계적으로 관리하기 위한 애니메이션 클래스를 구현해 보았습니다. 질문이나 추가적인 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "Day 11: 타일 맵과 맵 에디터 사용법"에 대해 학습하겠습니다.

반응형