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

[C++ 게임 개발 시리즈] Day 8: 2D 그래픽 기본 개념

by cogito21_cpp 2024. 8. 1.
반응형

2D 그래픽 기본 개념

2D 그래픽은 게임 개발에서 시각적 요소를 표현하는 중요한 부분입니다. 오늘은 2D 그래픽의 기본 개념을 학습하고, 이를 SFML을 사용하여 구현하는 방법을 알아보겠습니다.

2D 그래픽 기본 요소

  1. 스프라이트(Sprite):
    • 스프라이트는 게임에서 캐릭터, 아이템, 배경 등의 이미지를 나타내는 2D 비트맵입니다.
    • 스프라이트는 텍스처(Texture)를 사용하여 렌더링됩니다.
  2. 텍스처(Texture):
    • 텍스처는 스프라이트에 적용되는 이미지입니다.
    • 텍스처는 이미지 파일에서 로드하여 스프라이트에 매핑됩니다.
  3. 애니메이션(Animation):
    • 애니메이션은 여러 스프라이트 프레임을 순차적으로 표시하여 움직임을 표현하는 기술입니다.
    • 프레임 기반 애니메이션과 보간 기반 애니메이션이 있습니다.
  4. 타일 맵(Tile Map):
    • 타일 맵은 타일(Tile)이라고 하는 작은 이미지들을 배열하여 큰 지도를 만드는 기술입니다.
    • 타일 맵은 주로 게임의 배경이나 맵 디자인에 사용됩니다.
  5. 그리기 순서(Draw Order):
    • 그리기 순서는 화면에 요소가 그려지는 순서를 의미합니다. 일반적으로 배경, 중간 요소, 전경 순으로 그려집니다.

SFML을 사용한 2D 그래픽 구현

스프라이트와 텍스처

  1. 텍스처 로드 및 스프라이트 생성:
    • SFML을 사용하여 텍스처를 로드하고 스프라이트를 생성합니다.
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <iostream>

int main() {
    // 창 생성
    sf::RenderWindow window(sf::VideoMode(800, 600), "2D Graphics");

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

    // 스프라이트 생성
    sf::Sprite sprite;
    sprite.setTexture(texture);
    sprite.setPosition(400.0f, 300.0f); // 창 중앙에 위치

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

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

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

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

    return 0;
}

애니메이션

  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), "2D Graphics Animation");

    // 텍스처 로드
    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); // 창 중앙에 위치

    // 애니메이션 변수
    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;
}

타일 맵

  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), "Tile Map");

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

    // 타일 맵 데이터 (0, 1, 2는 타일 인덱스를 의미)
    const int tileSize = 32;
    const int mapWidth = 10;
    const int mapHeight = 10;
    int mapData[mapHeight][mapWidth] = {
        {0, 0, 1, 1, 2, 2, 1, 1, 0, 0},
        {0, 1, 2, 2, 1, 1, 2, 2, 1, 0},
        {1, 2, 2, 1, 0, 0, 1, 2, 2, 1},
        {2, 2, 1, 0, 0, 0, 0, 1, 2, 2},
        {1, 2, 1, 0, 0, 0, 0, 1, 2, 1},
        {0, 1, 2, 0, 0, 0, 0, 2, 1, 0},
        {0, 0, 1, 1, 2, 2, 1, 1, 0, 0},
        {1, 1, 2, 2, 1, 1, 2, 2, 1, 1},
        {2, 2, 1, 1, 0, 0, 1, 1, 2, 2},
        {1, 1, 0, 0, 1, 1, 0, 0, 1, 1}
    };

    // 타일 맵 생성
    sf::VertexArray tileMap(sf::Quads, mapWidth * mapHeight * 4);
    for (int i = 0; i < mapHeight; i++) {
        for (int j = 0; j < mapWidth; j++) {
            int tileIndex = mapData[i][j];
            int tu = tileIndex % 3; // 타일셋 가로 타일 수
            int tv = tileIndex / 3; // 타일셋 세로 타일 수

            sf::Vertex* quad = &tileMap[(i * mapWidth + j) * 4];
            quad[0].position = sf::Vector2f(j * tileSize, i * tileSize);
            quad[1].position = sf::Vector2f((j + 1) * tileSize, i * tileSize);
            quad[2].position = sf::Vector2f((j + 1) * tileSize, (i + 1) * tileSize);
            quad[3].position = sf::Vector2f(j * tileSize, (i + 1) * tileSize);

            quad[0].texCoords = sf::Vector2f(tu * tileSize, tv * tileSize);
            quad[1].texCoords = sf::Vector2f((tu + 1) * tileSize, tv * tileSize);
            quad[2].texCoords = sf::Vector2f((tu + 

1) * tileSize, (tv + 1) * tileSize);
            quad[3].texCoords = sf::Vector2f(tu * tileSize, (tv + 1) * tileSize);
        }
    }

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

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

        // 타일 맵 그리기
        sf::RenderStates states;
        states.texture = &tileTexture;
        window.draw(tileMap, states);

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

    return 0;
}

결론

오늘은 2D 그래픽의 기본 개념과 이를 SFML을 사용하여 구현하는 방법을 학습했습니다. 스프라이트, 텍스처, 애니메이션, 타일 맵 등을 이해하고 적용해 보았습니다. 질문이나 추가적인 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "Day 9: 스프라이트와 텍스처"에 대해 학습하겠습니다.

반응형