반응형
2D 그래픽 기본 개념
2D 그래픽은 게임 개발에서 시각적 요소를 표현하는 중요한 부분입니다. 오늘은 2D 그래픽의 기본 개념을 학습하고, 이를 SFML을 사용하여 구현하는 방법을 알아보겠습니다.
2D 그래픽 기본 요소
- 스프라이트(Sprite):
- 스프라이트는 게임에서 캐릭터, 아이템, 배경 등의 이미지를 나타내는 2D 비트맵입니다.
- 스프라이트는 텍스처(Texture)를 사용하여 렌더링됩니다.
- 텍스처(Texture):
- 텍스처는 스프라이트에 적용되는 이미지입니다.
- 텍스처는 이미지 파일에서 로드하여 스프라이트에 매핑됩니다.
- 애니메이션(Animation):
- 애니메이션은 여러 스프라이트 프레임을 순차적으로 표시하여 움직임을 표현하는 기술입니다.
- 프레임 기반 애니메이션과 보간 기반 애니메이션이 있습니다.
- 타일 맵(Tile Map):
- 타일 맵은 타일(Tile)이라고 하는 작은 이미지들을 배열하여 큰 지도를 만드는 기술입니다.
- 타일 맵은 주로 게임의 배경이나 맵 디자인에 사용됩니다.
- 그리기 순서(Draw Order):
- 그리기 순서는 화면에 요소가 그려지는 순서를 의미합니다. 일반적으로 배경, 중간 요소, 전경 순으로 그려집니다.
SFML을 사용한 2D 그래픽 구현
스프라이트와 텍스처
- 텍스처 로드 및 스프라이트 생성:
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;
}
애니메이션
- 애니메이션 프레임 설정:
- 여러 프레임을 사용하여 애니메이션을 구현합니다.
#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;
}
타일 맵
- 타일 맵 생성:
- 타일을 배열하여 맵을 생성합니다.
#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: 스프라이트와 텍스처"에 대해 학습하겠습니다.
반응형
'-----ETC----- > C++ 게임 개발 시리즈' 카테고리의 다른 글
[C++ 게임 개발 시리즈] Day 10: 애니메이션 기법 (프레임 기반 애니메이션) (0) | 2024.08.01 |
---|---|
[C++ 게임 개발 시리즈] Day 11: 타일 맵과 맵 에디터 사용법 (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 9: 스프라이트와 텍스처 (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 6: 첫 번째 게임 프로젝트: 간단한 2D 게임 만들기 (3) (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 7: 게임 루프와 기본 게임 구조 (0) | 2024.08.01 |