- 메이플 (참가비1추) 치킨뿌림 [567]
- FCO 뿌꾸 고소선언 [33]
- FCO 뿌꾸님 조금 경솔했다고 보임 [75]
- 걸그룹 르세라핌 김채원 인스타 [29]
- 차벤 아주머니 사람 칠뻔 했어요; [8]
- 명조 명조 스킬 공개 | 금희 [2]
Document Version : V1.3 - 2017.07.20 with cocos2d-x 3.15.1
Document Version : V1.2 - 2015.06.08 with cocos2d-x 3.6
제 책인 "시작하세요! Cocos2d-x 3.0 프로그래밍" 내용을 3.15.1 버전에 맞게 수정하여 올리고 있습니다.
개발환경 :
c:> cocos new Box2dEx19 -p com.study.box19 -l cpp ↵
Box2dEx02의 모든 코드를 방금 만든 Box2dEx19에 적용시킵니다.
Box2dEx02의 Classes 폴더의 다음 파일들을 Box2dEx19의 Classes 폴더에 덮어 쓰면 됩니다.
■ HelloWorldScene.h
■ HelloWorldScene.cpp
■ GLES-Render.h
■ GLES-Render.cpp
그러고 나서 다음의 디렉터리에서
{Cocos2d-x가 설치된 디렉터리} / tests / cpp-tests / Resources / Images
아래의 파일을 찾아 리소스 폴더에 추가합니다.
[ HelloWorldScene.h – 박스2D Click Velocity ]
#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:
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;
b2Body* addNewSprite(Vec2 point, Size size, b2BodyType bodytype,
const char* spriteName, int type);
b2Body* getBodyAtTab(Point p);
void addNewSpriteAtPosition(Vec2 location);
bool onTouchBegan(Touch* touch, Event* event);
void onTouchEnded(Touch* touch, Event* event);
};
#endif // __HELLOWORLD_SCENE_H__
[ HelloWorldScene.cpp – 박스2D Click Velocity ]
#include "HelloWorldScene.h"
Scene* HelloWorld::createScene()
{
… 생략 : Box2dEx02의 코드와 같음 …
}
bool HelloWorld::init()
{
… 생략 : Box2dEx02의 코드와 같음 …
}
bool HelloWorld::createBox2dWorld(bool debug)
{
… 생략 : Box2dEx02의 코드와 같음 …
}
void HelloWorld::setBox2dWorld()
{
playerIsFlying = false;
// 새로운 물리 객체의 바디와 해당 스프라이트를 추가한다.
addNewSpriteAtPosition(Vec2(240, 160));
}
HelloWorld::~HelloWorld()
{
… 생략 : Box2dEx02의 코드와 같음 …
}
void HelloWorld::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
… 생략 : Box2dEx02의 코드와 같음 …
}
void HelloWorld::onDraw(const Mat4 &transform, uint32_t flags)
{
… 생략 : Box2dEx02의 코드와 같음 …
}
void HelloWorld::onEnter()
{
Scene::onEnter();
// 싱글터치모드로 터치리스너 등록
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}
void HelloWorld::onExit()
{
… 생략 : Box2dEx02의 코드와 같음 …
}
void HelloWorld::tick(float dt)
{
int velocityIterations = 8;
int positionIterations = 3;
// Step : 물리 세계를 시뮬레이션한다.
_world->Step(dt, velocityIterations, positionIterations);
// 만들어진 객체 만큼 루프를 돌리면서 바디에 붙인 스프라이트를 여기서 제어한다.
for (b2Body* b = _world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != nullptr) {
Sprite* spriteData = (Sprite *)b->GetUserData();
spriteData->setPosition(Vec2(b->GetPosition().x * PTM_RATIO,
b->GetPosition().y * PTM_RATIO));
spriteData->setRotation(-1 * CC_RADIANS_TO_DEGREES(b->GetAngle()));
}
}
if (playerIsFlying)
{
myBall->ApplyLinearImpulse(b2Vec2(0, playerVelocity),
myBall->GetWorldCenter(),
true);
playerVelocity += 0.01f;
if (playerVelocity > 1.5f)
playerVelocity = 1.5f;
}
}
void HelloWorld::addNewSpriteAtPosition(Vec2 location)
{
// 바디데프 만들고 속성들을 지정한다.
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(location.x / PTM_RATIO, location.y / PTM_RATIO);
// 보통은 유져데이터에 스프라이트를 붙이는데
// 여기서는 아무 데이타를 넣지 않고 디버그 드로잉만 수행한다.
bodyDef.userData = nullptr;
// 월드에 바디데프의 정보로 바디를 만든다.
myBall = _world->CreateBody(&bodyDef);
// 바디에 적용할 물리 속성용 바디의 모양을 만든다. 여기서는 원을 만든다.
b2CircleShape circle;
// 바디의 크기 지정 - 원의 경우엔 반지름
circle.m_radius = 0.45f;
b2FixtureDef fixtureDef;
// 모양
fixtureDef.shape = &circle;
// 밀도
fixtureDef.density = 1.0f;
// 마찰력
fixtureDef.friction = 0.2f;
// 반발력
fixtureDef.restitution = 0.6f;
myBall->CreateFixture(&fixtureDef);
}
bool HelloWorld::onTouchBegan(Touch* touch, Event* event)
{
playerVelocity = 0.5f;
playerIsFlying = true;
return true;
}
void HelloWorld::onTouchEnded(Touch* touch, Event* event)
{
playerIsFlying = false;
playerVelocity = 0.0f;
}
코드를 완성했으면 실행시켜 봅니다.
상태를 표시하는 변수(playerIsFlying)를 통해 tick에서 힘을 주고 있기 때문에, 터치를 오래 하고 있으면 위쪽에 부딪히게 될 것이고, 터치를 오래동안 하지 않으면 바닥으로 떨어지게 됩니다.
내폰젤무거워