반응형
충돌 처리와 반응
충돌 처리와 반응은 물리 기반 게임에서 중요한 요소입니다. 오늘은 Box2D를 사용하여 충돌을 처리하고, 충돌에 반응하는 방법을 학습하겠습니다.
충돌 처리 기초
Box2D는 충돌을 감지하고 처리하기 위해 충돌 콜백 시스템을 제공합니다. 이 시스템을 사용하면 두 물체가 충돌했을 때 특정 동작을 수행할 수 있습니다.
Box2D 충돌 콜백
Box2D에서 충돌을 처리하려면 b2ContactListener
클래스를 상속하고, BeginContact
와 EndContact
메서드를 재정의합니다. 이 메서드들은 충돌이 시작되거나 끝날 때 호출됩니다.
충돌 콜백 클래스 정의
#include <SFML/Graphics.hpp>
#include <Box2D/Box2D.h>
#include <iostream>
// 픽셀을 미터로 변환하는 비율
const float SCALE = 30.0f;
// 사용자 정의 충돌 리스너 클래스
class MyContactListener : public b2ContactListener {
public:
void BeginContact(b2Contact* contact) override {
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
std::cout << "Collision detected between fixture " << fixtureA->GetUserData().pointer
<< " and fixture " << fixtureB->GetUserData().pointer << std::endl;
}
void EndContact(b2Contact* contact) override {
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
std::cout << "Collision ended between fixture " << fixtureA->GetUserData().pointer
<< " and fixture " << fixtureB->GetUserData().pointer << std::endl;
}
};
// Box2D 세계와 객체를 설정하는 함수
void setupBox2DWorld(b2World& world) {
// 바닥 생성
b2BodyDef groundBodyDef;
groundBodyDef.position = b2Vec2(400.0f / SCALE, 550.0f / SCALE);
b2Body* groundBody = world.CreateBody(&groundBodyDef);
b2PolygonShape groundBox;
groundBox.SetAsBox(400.0f / SCALE, 10.0f / SCALE);
groundBody->CreateFixture(&groundBox, 0.0f);
// 상자 생성
b2BodyDef boxBodyDef;
boxBodyDef.type = b2_dynamicBody;
boxBodyDef.position = b2Vec2(400.0f / SCALE, 100.0f / SCALE);
b2Body* boxBody = world.CreateBody(&boxBodyDef);
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(25.0f / SCALE, 25.0f / SCALE);
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
fixtureDef.userData.pointer = reinterpret_cast<uintptr_t>(boxBody);
boxBody->CreateFixture(&fixtureDef);
}
int main() {
// SFML 창 생성
sf::RenderWindow window(sf::VideoMode(800, 600), "Box2D Collision Example");
// Box2D 세계 생성
b2Vec2 gravity(0.0f, 9.8f);
b2World world(gravity);
// 충돌 리스너 설정
MyContactListener contactListener;
world.SetContactListener(&contactListener);
setupBox2DWorld(world);
// 상자 그래픽 생성
sf::RectangleShape box(sf::Vector2f(50.0f, 50.0f));
box.setFillColor(sf::Color::Green);
box.setOrigin(25.0f, 25.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();
// Box2D 물리 시뮬레이션 업데이트
world.Step(deltaTime, 8, 3);
// 상자의 위치와 회전 업데이트
b2Body* boxBody = world.GetBodyList()->GetNext(); // 첫 번째 객체는 바닥이므로 다음 객체를 가져옴
b2Vec2 position = boxBody->GetPosition();
float32 angle = boxBody->GetAngle();
box.setPosition(position.x * SCALE, position.y * SCALE);
box.setRotation(angle * 180.0f / b2_pi);
// 화면 지우기
window.clear();
// 상자 그리기
window.draw(box);
// 화면에 그리기
window.display();
}
return 0;
}
충돌 처리
위의 예제에서는 Box2D의 b2ContactListener
를 사용하여 충돌이 시작될 때(BeginContact
)와 끝날 때(EndContact
) 메시지를 출력했습니다. 충돌 콜백을 사용하면 충돌 이벤트에 대해 다양한 반응을 구현할 수 있습니다. 예를 들어, 충돌 시 소리를 재생하거나 점수를 증가시키는 등의 동작을 추가할 수 있습니다.
결론
오늘은 Box2D의 충돌 콜백 시스템을 사용하여 충돌을 처리하고, 충돌에 반응하는 방법을 학습했습니다. 이를 통해 게임에서 충돌 이벤트를 감지하고 처리하는 방법을 이해할 수 있었습니다. 질문이나 추가적인 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "Day 14: 화면 전환과 UI 요소"에 대해 학습하겠습니다.
반응형
'-----ETC----- > C++ 게임 개발 시리즈' 카테고리의 다른 글
[C++ 게임 개발 시리즈] Day 15: 게임 이벤트 처리 (0) | 2024.08.01 |
---|---|
[C++ 게임 개발 시리즈] Day 12: 2D 물리 엔진 기초 (Box2D) (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 10: 애니메이션 기법 (프레임 기반 애니메이션) (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 11: 타일 맵과 맵 에디터 사용법 (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 8: 2D 그래픽 기본 개념 (0) | 2024.08.01 |