Last active
February 7, 2016 07:11
-
-
Save takashi1975/d1ea2be790035a7fdbec to your computer and use it in GitHub Desktop.
Box2dを動かしてみた (Cocos2d-x v3.9)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "HelloWorldScene.h" | |
#include "GLES-Render.h" | |
USING_NS_CC; | |
#pragma mark | |
const float HelloWorld::PTM_RATIO = (32.0f); | |
#pragma mark - | |
HelloWorld::HelloWorld() | |
: _world(nullptr) | |
{ | |
} | |
HelloWorld::~HelloWorld() | |
{ | |
} | |
#pragma mark - | |
Scene * HelloWorld::createScene() | |
{ | |
auto scene = Scene::create(); | |
if (scene) | |
{ | |
if (auto layer = HelloWorld::create()) | |
{ | |
scene->addChild(layer); | |
} | |
} | |
return scene; | |
} | |
#pragma mark - | |
bool HelloWorld::init() | |
{ | |
bool result = false; | |
do | |
{ | |
if (! Layer::init()) | |
{ | |
break; | |
} | |
this->initPhysics(); | |
auto visibleRect = Rect::ZERO; | |
{ | |
visibleRect.origin = Director::getInstance()->getVisibleOrigin(); | |
visibleRect.size = Director::getInstance()->getVisibleSize(); | |
} | |
if (auto world = this->_world) | |
{ | |
//ボール | |
if (auto ball = Sprite::create("CloseNormal.png")) | |
{ | |
//TEST 読み込み時のサイズ | |
ball->setScale(3.0f); | |
const auto ballSize = ball->getBoundingBox().size; | |
{ | |
const auto pos = Point(visibleRect.getMidX(), visibleRect.getMidY()); | |
ball->setPosition(pos); | |
//TEST | |
ball->setRotation(45.0f); | |
ball->setName("ball"); | |
this->addChild(ball); | |
ball->setOpacity(64); | |
} | |
b2Body * body = nullptr; | |
{ | |
b2BodyDef bodyDef; | |
{ | |
bodyDef.type = b2_dynamicBody; | |
auto pos = Point::ZERO; | |
{ | |
pos = ball->getPosition(); | |
pos *= (1.0f / HelloWorld::PTM_RATIO); | |
} | |
bodyDef.position.Set(pos.x, pos.y); | |
auto angle = 0.0f; | |
{ | |
angle = ball->getRotation(); | |
angle = -1.0f * CC_DEGREES_TO_RADIANS(angle); | |
} | |
bodyDef.angle = angle; | |
bodyDef.userData = ball; | |
} | |
body = world->CreateBody(&bodyDef); | |
} | |
if (body) | |
{ | |
//スコープに注意 (iOSはOKでもAndroidで落ちる) | |
b2CircleShape shape; | |
{ | |
const auto size = ballSize; | |
const auto length = MAX(size.width, size.height); | |
//半径 | |
shape.m_radius = length * 0.5f * (1.0f / HelloWorld::PTM_RATIO); | |
} | |
b2FixtureDef fixtureDef; | |
{ | |
fixtureDef.shape = &shape; | |
fixtureDef.density = 0.4f; //密度 | |
fixtureDef.friction = 0.5f; //摩擦 | |
fixtureDef.restitution = 0.0f; //反発 | |
} | |
body->CreateFixture(&fixtureDef); | |
} | |
} | |
//壁 | |
{ | |
const Point point[] = { | |
Point(rect.getMinX(), rect.getMinY()) * (1.0f / HelloWorld::PTM_RATE), | |
Point(rect.getMaxX(), rect.getMinY()) * (1.0f / HelloWorld::PTM_RATE), | |
Point(rect.getMaxX(), rect.getMaxY()) * (1.0f / HelloWorld::PTM_RATE), | |
Point(rect.getMinX(), rect.getMaxY()) * (1.0f / HelloWorld::PTM_RATE), | |
}; | |
struct PointList { | |
b2Vec2 pos1; | |
b2Vec2 pos2; | |
}; | |
const PointList list[] = { | |
{ b2Vec2(point[0].x, point[0].y), b2Vec2(point[1].x, point[1].y) }, | |
{ b2Vec2(point[1].x, point[1].y), b2Vec2(point[2].x, point[2].y) }, | |
{ b2Vec2(point[2].x, point[2].y), b2Vec2(point[3].x, point[3].y) }, | |
{ b2Vec2(point[3].x, point[3].y), b2Vec2(point[0].x, point[0].y) }, | |
}; | |
{ | |
b2Body * body = nullptr; | |
{ | |
b2BodyDef bodydef; | |
{ | |
bodydef.type = b2BodyType::b2_staticBody; | |
const auto pos = list[0]; | |
bodydef.position.Set(pos.pos1.x, pos.pos1.y); | |
} | |
body = world->CreateBody(&bodydef); | |
} | |
if (body) | |
{ | |
const auto count = sizeof(list)/sizeof(*list); | |
for (int i = 0; i < count; i++) | |
{ | |
const auto pos = list[i]; | |
b2EdgeShape shape; | |
{ | |
shape.Set(pos.pos1, pos.pos2); | |
} | |
b2FixtureDef fixturedef; | |
{ | |
fixturedef.shape = &shape; | |
fixturedef.density = 0.0f; | |
fixturedef.friction = 0.0f; | |
fixturedef.restitution = 1.0f; | |
} | |
body->CreateFixture(&fixturedef); | |
} | |
} | |
} | |
} | |
} | |
result = true; | |
} while (0); | |
return result; | |
} | |
#pragma mark - | |
void HelloWorld::initPhysics() | |
{ | |
const auto gravity = b2Vec2(0.0f, -9.8f); | |
if (auto world = new b2World(gravity)) | |
{ | |
if (auto debug = new GLESDebugDraw(HelloWorld::PTM_RATIO)) | |
{ | |
uint32 flags = 0; | |
{ | |
flags += b2Draw::e_shapeBit; | |
// flags += b2Draw::e_jointBit; | |
// flags += b2Draw::e_aabbBit; | |
// flags += b2Draw::e_pairBit; | |
// flags += b2Draw::e_centerOfMassBit; | |
} | |
debug->SetFlags(flags); | |
world->SetDebugDraw(debug); | |
} | |
this->_world = world; | |
} | |
} | |
#pragma mark - | |
void HelloWorld::onEnter() | |
{ | |
//super | |
Layer::onEnter(); | |
} | |
void HelloWorld::onEnterTransitionDidFinish() | |
{ | |
//super | |
Layer::onEnterTransitionDidFinish(); | |
this->scheduleUpdate(); | |
} | |
void HelloWorld::onExitTransitionDidStart() | |
{ | |
//super | |
Layer::onExitTransitionDidStart(); | |
this->unscheduleUpdate(); | |
} | |
void HelloWorld::onExit() | |
{ | |
//super | |
Layer::onExit(); | |
} | |
#pragma mark - | |
void HelloWorld::update(float delta) | |
{ | |
if (auto world = this->_world) | |
{ | |
const auto velocityIterations = 10; | |
const auto positionIterations = 10; | |
world->Step(delta, velocityIterations, positionIterations); | |
for (auto body = world->GetBodyList(); body; body = body->GetNext()) | |
{ | |
if (auto sprite = static_cast<Sprite *>(body->GetUserData())) | |
{ | |
if (sprite->getName().compare("ball") == 0) | |
{ | |
auto pos = Point::ZERO; | |
{ | |
auto vec2Pos = body->GetPosition(); | |
pos = Point(vec2Pos.x, vec2Pos.y); | |
pos *= HelloWorld::PTM_RATIO; | |
} | |
auto angle = 0.0f; | |
{ | |
angle = body->GetAngle(); | |
angle = -1.0f * CC_RADIANS_TO_DEGREES(angle); | |
} | |
sprite->setRotation(angle); | |
sprite->setPosition(pos); | |
} | |
} | |
} | |
} | |
} | |
void HelloWorld::draw(Renderer *renderer, const Mat4& transform, uint32_t flags) | |
{ | |
//super | |
Layer::draw(renderer, transform, flags); | |
if (auto world = this->_world) | |
{ | |
if (auto director = Director::getInstance()) | |
{ | |
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION); | |
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); | |
world->DrawDebugData(); | |
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __HELLOWORLD_SCENE_H__ | |
#define __HELLOWORLD_SCENE_H__ | |
#include "cocos2d.h" | |
#include "Box2D/Box2D.h" | |
class HelloWorld : public cocos2d::Layer | |
{ | |
public: | |
static const float PTM_RATIO; | |
protected: | |
HelloWorld(); | |
virtual ~HelloWorld(); | |
public: | |
static cocos2d::Scene* createScene(); | |
CREATE_FUNC(HelloWorld); | |
protected: | |
virtual bool init() override; | |
private: | |
void initPhysics(); | |
protected: | |
virtual void onEnter() override; | |
virtual void onEnterTransitionDidFinish() override; | |
virtual void onExitTransitionDidStart() override; | |
virtual void onExit() override; | |
protected: | |
virtual void update(float delta) override; | |
virtual void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4& transform, uint32_t flags) override; | |
private: | |
b2World * _world; | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
iOS では問題なく動作する。
...が、Android は... コンパイルはOKだが、動作させると エラーで落ちる。
D/cocos2d-x debug info: create rendererRecreatedListener for GLProgramState
D/cocos2d-x debug info: create rendererRecreatedListener for GLProgramState
A/libc: Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1)
... ググったり、試した感じは... Android.mk, Application.mk は多分大丈夫?(soファイルができているし ^^;)
... コードが悪いので調査中... orz
[解決]
b2FixtureDef の shape を作るときのスコープが問題でした。
よく 処理の塊を { ... } で囲むので...自分はやらかしがちですね...。
iOSはOKだけど、Android ではダメ。
...やっぱりなるべくAndroid でも随時確認したほうがいいですね ^^;;