Document Version : V1.3 - 2017.07.26 with cocos2d-x 3.15.1
Document Version : V1.2 - 2015.06.08 with cocos2d-x 3.6
개발환경 :
one way platformsone sided platformsone way walls다 같은 말입니다.
c:> cocos new Box2dEx20 -p com.study.box20 -l cpp ↵
Box2dEx19의 모든 코드를 방금 만든 Box2dEx20에 적용시킵니다.
Box2dEx19의 Classes 폴더의 다음 파일들을 Box2dEx20의 Classes 폴더에 덮어 쓰면 됩니다.
■ HelloWorldScene.h
■ HelloWorldScene.cpp
■ GLES-Render.h
■ GLES-Render.cpp
그러고 나서 다음의 디렉터리에서
{Cocos2d-x가 설치된 디렉터리} / tests / cpp-tests / Resources / Images
아래의 파일을 찾아 리소스 폴더에 추가합니다.
[ HelloWorldScene.h – 박스2D One Way Platform ]
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#pragma execution_character_set("utf-8")
#endif
#include "cocos2d.h"
#include "Box2D/Box2D.h"
#include <GLES-Render.h>
#define PTM_RATIO 32
using namespace cocos2d;
class HelloWorld
: public cocos2d::Scene
, public b2ContactListener
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(HelloWorld);
Size winSize;
Texture2D* texture;
b2World* _world;
// For debugging
GLESDebugDraw* m_debugDraw;
cocos2d::CustomCommand _customCmd;
bool createBox2dWorld(bool debug);
void setBox2dWorld();
~HelloWorld();
virtual void draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform,
uint32_t flags) override;
void onDraw(const cocos2d::Mat4& transform, uint32_t flags);
void onEnter();
void onExit();
void tick(float dt);
b2Body* myBall;
float playerVelocity;
bool playerIsFlying;
void addNewSpriteAtPosition(Vec2 location);
bool onTouchBegan(Touch* touch, Event* event);
void onTouchEnded(Touch* touch, Event* event);
// 19.Box2dEx19 - ClickVelocity 에 추가
void BeginContact(b2Contact* contact);
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);
void EndContact(b2Contact* contact);
};
#endif // __HELLOWORLD_SCENE_H__
[ HelloWorldScene.cpp – 박스2D One Way Platform ]
#include "HelloWorldScene.h"
Scene* HelloWorld::createScene()
{
… 생략 : Box2dEx19의 코드와 같음 …
}
bool HelloWorld::init()
{
if ( !Scene::init() )
{
return false;
}
/////////////////////////////
// 윈도우 크기를 구한다.
winSize = Director::getInstance()->getWinSize();
// 이미지의 텍스쳐를 구한다.
texture = Director::getInstance()->getTextureCache()->addImage("blocks.png");
// 월드 생성
if (this->createBox2dWorld(true))
{
//월드에 충돌함수 클래스를 리스너에 추가함
_world->SetContactListener((b2ContactListener *)this);
this->setBox2dWorld();
this->schedule(schedule_selector(HelloWorld::tick));
}
return true;
}
bool HelloWorld::createBox2dWorld(bool debug)
{
… 생략 : Box2dEx19의 코드와 같음 …
}
void HelloWorld::setBox2dWorld()
{
playerIsFlying = false;
// staticBody 스프라이트를 추가한다.
Sprite* pSprite1 = Sprite::createWithTexture(texture, Rect(0, 0, 64, 64));
pSprite1->setPosition(Vec2(winSize.width / 2, winSize.height / 2));
this->addChild(pSprite1);
// 바디데프 만들고 속성들을 지정한다.
b2BodyDef bodyDef1;
bodyDef1.type = b2_staticBody;
bodyDef1.position.Set(winSize.width / 2 / PTM_RATIO,
winSize.height / 2 / PTM_RATIO);
bodyDef1.userData = pSprite1;
b2Body* body1 = _world->CreateBody(&bodyDef1);
// 바디에 적용할 물리 속성용 바디의 모양을 만든다.
b2PolygonShape staticBox;
// 바디의 크기 지정 - 상자의 크기에서 가운데 위치를 지정한다.
staticBox.SetAsBox((pSprite1->getContentSize().width / 2) / PTM_RATIO,
(pSprite1->getContentSize().height / 2) / PTM_RATIO);
b2FixtureDef fixtureDef1;
fixtureDef1.shape = &staticBox;
fixtureDef1.density = 1.0f;
body1->CreateFixture(&fixtureDef1);
//-------------------------------------------------------------------------------
// 새로운 물리 객체의 바디와 해당 스프라이트를 추가한다.
addNewSpriteAtPosition(Vec2(240, 100));
}
HelloWorld::~HelloWorld()
{
… 생략 : Box2dEx19의 코드와 같음 …
}
void HelloWorld::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
… 생략 : Box2dEx19의 코드와 같음 …
}
void HelloWorld::onDraw(const Mat4 &transform, uint32_t flags)
{
… 생략 : Box2dEx19의 코드와 같음 …
}
void HelloWorld::onEnter()
{
… 생략 : Box2dEx19의 코드와 같음 …
}
void HelloWorld::onExit()
{
… 생략 : Box2dEx19의 코드와 같음 …
}
void HelloWorld::tick(float dt)
{
… 생략 : Box2dEx19의 코드와 같음 …
}
void HelloWorld::addNewSpriteAtPosition(Vec2 location)
{
… 생략 : Box2dEx19의 코드와 같음 …
}
bool HelloWorld::onTouchBegan(Touch* touch, Event* event)
{
… 생략 : Box2dEx19의 코드와 같음 …
}
void HelloWorld::onTouchEnded(Touch* touch, Event* event)
{
… 생략 : Box2dEx19의 코드와 같음 …
}
void HelloWorld::BeginContact(b2Contact* contact)
{
}
void HelloWorld::PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
{
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
b2Body* bodyA = fixtureA->GetBody();
b2Body* bodyB = fixtureB->GetBody();
if (bodyA->GetUserData() == nullptr || bodyB->GetUserData() == nullptr) {
return;
}
Sprite* spr1 = (Sprite *)bodyA->GetUserData();
Sprite* spr2 = (Sprite *)bodyB->GetUserData();
float pos1 = spr1->getPosition().y + (spr1->getContentSize().height / 2);
//float pos2 = spr2->getPosition().y - (spr2->getContentSize().height / 2);
float pos2 = spr2->getPosition().y;
if (pos2 < pos1)
{
contact->SetEnabled(false);
}
}
void HelloWorld::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
{
}
void HelloWorld::EndContact(b2Contact* contact)
{
contact->SetEnabled(true);
}
코드를 완성했으면 실행시켜 봅니다.
간단하게 One Way Platform 이 구현되었습니다.
내폰젤무거워