Skip to content

Instantly share code, notes, and snippets.

@sdkfz181tiger
Last active October 3, 2025 06:04
Show Gist options
  • Save sdkfz181tiger/cd74128ff3d32adb3678f4ec954e9068 to your computer and use it in GitHub Desktop.
Save sdkfz181tiger/cd74128ff3d32adb3678f4ec954e9068 to your computer and use it in GitHub Desktop.
Box2D基本1_四角や円を物理空間に描くクラス
#include "DrawerBase.h"
DrawerBase::DrawerBase(const b2WorldId &worldId,
float x, float y, Type type) :
NodeBase(x, y), type(type),
color(GetColor(255, 255, 255)),
b2dRate(UtilDebug::getInstance()->getGridSize() * 2),
worldId(worldId), bodyId(b2_nullBodyId) {
//LOGD("Main", "DrawerBase()");
}
DrawerBase::~DrawerBase() {
//LOGD("Main", "~DrawerBase()");
if (bodyId.index1 != 0) b2DestroyBody(bodyId);
}
float DrawerBase::p2m(float pixel) const {
return pixel / (float) b2dRate;
}
float DrawerBase::m2p(float meter) const {
return meter * (float) b2dRate;
}
#ifndef _DRAWERBASE_H_
#define _DRAWERBASE_H_
#include "NodeBase.h"
#include <box2d/box2d.h>
class DrawerBase : public NodeBase {
public:
enum Type {
TYPE_DYNAMIC, TYPE_STATIC, TYPE_REMOVER
};
protected:
const Type type;
const uint color;
const int b2dRate;
const b2WorldId &worldId;
b2BodyId bodyId;
public:
DrawerBase(const b2WorldId &worldId,
float x, float y, Type type);
virtual ~DrawerBase();
bool isRemover() { return type == TYPE_REMOVER; }
b2BodyId &getBodyId() { return bodyId; }
float p2m(float pixel) const;
float m2p(float meter) const;
};
#endif // _DRAWERBASE_H_
#include "DrawerBox.h"
DrawerBox *DrawerBox::create(const b2WorldId &worldId,
float x, float y, Type type,
int w, int h, int deg) {
// New
auto obj = new DrawerBox(worldId, x, y, type);
if (obj && obj->init(w, h, deg)) return obj;
DX_SAFE_DELETE(obj);
return nullptr;
}
DrawerBox::DrawerBox(const b2WorldId &worldId,
float x, float y, Type type) :
DrawerBase(worldId, x, y, type),
widthM(0.0f), heightM(0.0f) {
//LOGD("Main", "DrawerBox()");
}
DrawerBox::~DrawerBox() {
//LOGD("Main", "~DrawerBox()");
}
bool DrawerBox::init(int w, int h, int deg) {
// Pixel to Meter
const float mX = this->p2m(pos.x);
const float mY = this->p2m(pos.y) * -1.0f;
widthM = this->p2m(w);
heightM = this->p2m(h);
// Define the body
b2BodyDef bodyDef = b2DefaultBodyDef();
if (type == TYPE_DYNAMIC) bodyDef.type = b2_dynamicBody;
bodyDef.position = (b2Vec2) {mX, mY};
bodyDef.rotation = b2MakeRot(DEG_TO_RAD * deg);
bodyId = b2CreateBody(worldId, &bodyDef);
// ShapeDef
b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.isSensor = false;
shapeDef.enableContactEvents = true;// Important
shapeDef.userData = this;
// Polygon
b2Polygon polygon = b2MakeBox(widthM / 2, heightM / 2);
b2CreatePolygonShape(bodyId, &shapeDef, &polygon);
// Points
points.at(0).x = -w / 2;
points.at(0).y = -h / 2;
points.at(1).x = w / 2;
points.at(1).y = -h / 2;
points.at(2).x = w / 2;
points.at(2).y = h / 2;
points.at(3).x = -w / 2;
points.at(3).y = h / 2;
return true;
}
void DrawerBox::update(const float delay) {
// Draw
this->draw();
}
void DrawerBox::draw() {
// Rotation
const auto position = b2Body_GetPosition(bodyId);
const auto rotation = b2Body_GetRotation(bodyId);
const auto angle = b2Rot_GetAngle(rotation);
const float cosA = cosf(angle);
const float sinA = sinf(angle);
// Meter to Pixel
const float cX = this->m2p(position.x);
const float cY = this->m2p(position.y);
for (int i = 0; i < points.size(); i++) {
const float aX = points.at(i).x;
const float aY = points.at(i).y;
const int j = (i + 1) % points.size();
const float bX = points.at(j).x;
const float bY = points.at(j).y;
const float fX = aX * cosA - aY * sinA;
const float fY = aX * sinA + aY * cosA;
const float tX = bX * cosA - bY * sinA;
const float tY = bX * sinA + bY * cosA;
UtilCamera::getInstance()->drawLine(cX + fX, -(cY + fY),
cX + tX, -(cY + tY),
color, true);
}
}
#ifndef _DRAWERBOX_H_
#define _DRAWERBOX_H_
#include "DrawerBase.h"
#include <box2d/box2d.h>
class DrawerBox : public DrawerBase {
private:
array<b2Vec2, 4> points;
float widthM, heightM;
public:
static DrawerBox *create(const b2WorldId &worldId,
float x, float y, Type type,
int w, int h, int deg);
DrawerBox(const b2WorldId &worldId,
float x, float y, Type type);
virtual ~DrawerBox();
virtual bool init(int w, int h, int deg);
void update(const float delay) override;
void draw() override;
float getWidthM() const { return widthM; }
float getHeightM() const { return heightM; }
};
#endif // _DRAWERBOX_H_
#include "DrawerCircle.h"
DrawerCircle *DrawerCircle::create(const b2WorldId &worldId,
float x, float y, Type type,
int radius) {
// New
auto obj = new DrawerCircle(worldId, x, y, type);
if (obj && obj->init(radius)) return obj;
DX_SAFE_DELETE(obj);
return nullptr;
}
DrawerCircle::DrawerCircle(const b2WorldId &worldId,
float x, float y, Type type) :
DrawerBase(worldId, x, y, type), radiusM(0.0f) {
//LOGD("Main", "DrawerCircle()");
}
DrawerCircle::~DrawerCircle() {
//LOGD("Main", "~DrawerCircle()");
}
bool DrawerCircle::init(int radius) {
// Pixel to Meter
const float mX = this->p2m(pos.x);
const float mY = this->p2m(pos.y) * -1.0f;
radiusM = this->p2m(radius);
// Define the body
b2BodyDef bodyDef = b2DefaultBodyDef();
if (type == TYPE_DYNAMIC) bodyDef.type = b2_dynamicBody;
bodyDef.position = (b2Vec2) {mX, mY};
bodyId = b2CreateBody(worldId, &bodyDef);
// ShapeDef
b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.isSensor = false;
shapeDef.enableContactEvents = true;// Important
shapeDef.userData = this;
// Polygon
b2Circle circle = {0};
circle.center = (b2Vec2) {0.0f, 0.0f};
circle.radius = radiusM;
b2CreateCircleShape(bodyId, &shapeDef, &circle);
return true;
}
void DrawerCircle::update(const float delay) {
// Draw
this->draw();
}
void DrawerCircle::draw() {
// Rotation
const auto position = b2Body_GetPosition(bodyId);
const auto rotation = b2Body_GetRotation(bodyId);
const auto angle = b2Rot_GetAngle(rotation);
// Meter to Pixel
const float cX = this->m2p(position.x);
const float cY = this->m2p(position.y);
const float radiusP = this->m2p(radiusM);
const int segments = 12;
const float step = M_PI * 2.0f / segments;
for (int i = 0; i < segments; i++) {
float angle1 = step * i;
float angle2 = step * (i + 1);
float fX = cX + radiusP * cosf(angle1);
float fY = -(cY + radiusP * sinf(angle1));
float tX = cX + radiusP * cosf(angle2);
float tY = -(cY + radiusP * sinf(angle2));
UtilCamera::getInstance()->drawLine(fX, fY, tX, tY,
color, true);
}
}
#ifndef _DRAWERCIRCLE_H_
#define _DRAWERCIRCLE_H_
#include "DrawerBase.h"
#include <box2d/box2d.h>
class DrawerCircle : public DrawerBase {
private:
float radiusM;
public:
static DrawerCircle *create(const b2WorldId &worldId,
float x, float y, Type type,
int radius);
DrawerCircle(const b2WorldId &worldId,
float x, float y, Type type);
virtual ~DrawerCircle();
virtual bool init(int radius);
void update(const float delay) override;
void draw() override;
float getRadiusM() const { return radiusM; }
};
#endif // _DRAWERCIRCLE_H_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment