#include <iostream>
#include "SDL.h"
#include "box2d/box2d.h"
class DebugDrawer : public b2Draw
{
public:
DebugDrawer(SDL_Renderer* renderer) {
this->renderer = renderer;
}
private:
SDL_Renderer* renderer;
void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {}
void DrawPoint(const b2Vec2& p, float size, const b2Color& color) {}
void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {
SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
SDL_FRect* rect = new SDL_FRect{ vertices[0].x, vertices[0].y, vertices[1].x
- vertices[0].x, vertices[3].y - vertices[0].y };
SDL_RenderDrawRectF(renderer, rect);
}
void DrawCircle(const b2Vec2& center, float radius, const b2Color& color) {}
void DrawSolidCircle(const b2Vec2& center, float radius, const b2Vec2& axis, const b2Color& color) {}
void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) {}
void DrawTransform(const b2Transform& xf) {}
};
int main(int argc, char* argv[]) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("SDL Test", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_RESIZABLE);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface* playerSurface = SDL_LoadBMP("player.bmp");
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, playerSurface);
// World 정의
b2Vec2 gravity(0.0f, 9.8f);
b2World world(gravity);
// DebugDraw 정의
DebugDrawer* debugDrawer = new DebugDrawer(renderer);
debugDrawer->SetFlags(b2Draw::e_shapeBit | b2Draw::e_jointBit |
b2Draw::e_centerOfMassBit | b2Draw::e_aabbBit | b2Draw::e_pairBit);
world.SetDebugDraw(debugDrawer);
// Player 정의
b2BodyDef playerBodyDef;
playerBodyDef.type = b2_dynamicBody;
playerBodyDef.position.Set(0.0f, 0.0f);
playerBodyDef.linearVelocity = b2Vec2(50.0f, 0.0f);
playerBodyDef.angularVelocity = 0.2f;
b2Body* playerBody = world.CreateBody(&playerBodyDef);
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox((float)playerSurface->w / 2, (float)playerSurface->h / 2);
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
fixtureDef.restitution = 0.5f;
playerBody->CreateFixture(&fixtureDef);
// Ground 정의
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0.0f, 400.0f);
b2Body* groundBody = world.CreateBody(&groundBodyDef);
b2PolygonShape groundBox;
groundBox.SetAsBox(500.0f, 0.0f);
SDL_Rect groundRect = { 0, 400, 500, 10 };
groundBody->CreateFixture(&groundBox, 0.0f);
// Wall 정의
b2BodyDef wallBodyDef;
wallBodyDef.position.Set(300.0f, 0.0f);
b2Body* wallBody = world.CreateBody(&wallBodyDef);
b2PolygonShape wallBox;
wallBox.SetAsBox(0.0f, 480.0f);
SDL_Rect wallRect = { 300, 0, 10, 480 };
wallBody->CreateFixture(&wallBox, 0.0f);
float timeStep = 1.0f / 500.0f;
int velocityIterations = 6;
int positionIterations = 2;
SDL_Event event;
bool quit = false;
while (!quit) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
quit = true;
break;
case SDL_KEYDOWN:
printf("Key pressed: %s\n", SDL_GetKeyName(event.key.keysym.sym));
if (event.key.keysym.sym == SDLK_SPACE) {
playerBody->SetTransform(b2Vec2(0.0f, 0.0f), 0.0f);
playerBody->SetLinearVelocity(b2Vec2(50.0f, 0.0f));
playerBody->SetAngularVelocity(0.2f);
}
if (event.key.keysym.sym == SDLK_ESCAPE)
quit = true;
break;
default:
break;
}
}
world.Step(timeStep, velocityIterations, positionIterations);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
// Ground 그리기
SDL_SetRenderDrawColor(renderer, 220, 140, 20, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(renderer, &groundRect);
// Wall 그리기
SDL_SetRenderDrawColor(renderer, 64, 64, 64, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(renderer, &wallRect);
// Player 그리기
b2Vec2 playerPosition = playerBody->GetPosition();
SDL_Rect destRect = { (int)playerPosition.x - playerSurface->w / 2,
(int)playerPosition.y - playerSurface->h / 2, playerSurface->w, playerSurface->h };
SDL_RendererFlip flip = SDL_FLIP_NONE;
float angle = playerBody->GetAngle() * (180 / (float)M_PI);
SDL_RenderCopyEx(renderer, texture, NULL, &destRect, angle, NULL, flip);
// 가장 마지막에 DebugDraw 그리기
world.DebugDraw();
SDL_RenderPresent(renderer);
}
// debugDrawer 해제
delete debugDrawer;
SDL_DestroyTexture(texture);
SDL_FreeSurface(playerSurface);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}