개요
별게임을 개발하면서 가장 많이 변경된 두 클래스라고 생각합니다.
그만큼 앞으로도 많이 변경될 것으로 보입니다.
먼저 코드 전에 간단하게 설명하자면
Bullet은 모든 Bullet 파생클래스들의 Base클래스 입니다.
모든 Bullet 들 에게 공통적으로 필요한 AI 조종행동 이나 이펙트, action 등을 정의합니다.
Shooter 역시 모든 Shooter 파생클래스의 Base클래스 입니다.
두 클래스가 공통적으로 가지고 있는 함수가 있다면 바로 operator new 와 operator delete 함수 입니다.
operator new 함수는 메모리를 실제로 할당하지 않고 PoolingManager에서 받아오기 위해 정의하였고
operator delete 는 operator new의 특성을 커버할 수 있도록 정의 되었습니다.
( operator new / delete 에 대한 자세한 설명은 아래 포스팅을 참조해주세요. )
[operator new / operator delete]
이제 코드를 보겠습니다.
(가독성을 위해 필요한 부분만 적절히 편집하였습니다.)
코드
operator new
1 2 3 4 5 6 | /* poolingManager에서 FreeMemory Block을 하나 가져옴 */ void* CBullet::operator new(size_t size, const std::nothrow_t) { // PoolingManager에서 메모리를 할당 받는다. return CPoolingManager::Instance()->BulletNew(); } | cs |
PoolingManager의 관리를 받기 위한 operator new
create함수에서 새롭게 메모리 생성하는 것이 아니라 미리 생성해 두었던 메모리를 사용합니다.
ReturnToMemoryBlock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /* 오브젝트의 메모리를 FreeMemoryBlock으로 변환 == 오브젝트 삭제 */ void CBullet::ReturnToMemoryBlock() { /*removeFromParent 의 이유 : 이유는 모든 CMover의 파생 객체들은 메모리 블럭에서 메모리를 할당 받는다. 그로인해 실행 중 addChild시 같은 메모리를 여러번 addChild할 수 있다. 때문에 메모리 블럭으로 되돌릴때에는 부모관계를 제거하여야한다. 또 ReferenceCount를 1 낮춰야 하는 이유도 있다.*/ this->removeFromParent(); this->removeAllChildren(); this->setVisible(false); this->setAlive(false); CPoolingManager::Instance()->Bullet_ReturnToFreeMemory(this); } | cs |
사용이 끝난 오브젝트의 메모리를 PoolingManager로 돌려보냅니다.
돌려 보내기 전에 현재 오브젝트에 붙어있는 Children들을 해제하고 오브젝트 역시 부모로 부터 관계를 끊습니다.
Rotation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /* 회전행렬을 이용하여 오브젝트 회전 및 이동 */ void CBullet::Rotation(float dir, float delta) { // 회전 속도와 방향을 이용하여 각도를 구하고 라디안으로 변환 float radian = CC_DEGREES_TO_RADIANS(dir * (m_fRotationSpeed * delta)); // 현재의 Direction Vector를 저장한다. Vec2 beforeRotation = getPosition() - m_pPlanet->getPosition(); // 거리도 저장 float length = beforeRotation.length(); /* 회전행렬을 구함 * rotate x = ((x_ * cos(angle)) - (y_ * sin(angle))) * rotate y = ((x_ * sin(angle)) + (y_ * cos(angle))) */ m_RotationVec = Vec2( (float)((beforeRotation.x * cos(radian)) - (beforeRotation.y * sin(radian))), (float)((beforeRotation.x * sin(radian)) + (beforeRotation.y * cos(radian)))); // 노말라이즈 m_RotationVec.normalize(); m_RotationVec *= length; // 기존의 좌표에 새로운 좌표를 더해준다. setPosition(m_pPlanet->getPosition() + m_RotationVec); // 오브젝트 자체도 회전 setRotation(getRotation() - (dir *( m_fRotationSpeed * delta))); } | cs |
오브젝트의 회전을 정의 합니다.
회전행렬을 이용하여 회전 후 좌표를 구하고 오브젝트 자체도 회전하여 줍니다.
R_BezierWithScale
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* 일정 위치로 베지어 곡선을 그리며 이동한 후 커지면서 FadeOut */ void CBullet::R_BezierWithScale( Vec2 targetPos, Vec2 controlPoint_1, Vec2 controlPoint_2, float time, float scale) { // 더이상 Execute 하지 않는다. setAlive(false); // 베지어 곡선 생성 ccBezierConfig bezier; bezier.controlPoint_1 = Vec2(controlPoint_1); bezier.controlPoint_2 = Vec2(controlPoint_2); bezier.endPosition = Vec2(targetPos); // 베지어 액션 및 다른 액션 순서대로 실행 auto bezierTo1 = BezierTo::create(time, bezier); this->setZOrder(101); auto action = Sequence::create( bezierTo1, ScaleBy::create(0.5f, scale), // 두 액션이 끝난후 스케줄을 걸어 오브젝트 삭제 CallFunc::create([&](){ this->scheduleOnce([=](float dt){ this->ReturnToMemoryBlock(); }, 1.0f, "BezierWithScale"); }), nullptr); this->runAction(action); // texture 페이드 아웃 auto textureAction = FadeOut::create(2.0f); m_pTexture->runAction(textureAction); } | cs |
오브젝트의 특정 action을 정의합니다. R_은 ReturnToMemoryBlock을 호출한다는 약자입니다.
'All > Project' 카테고리의 다른 글
별게임의 상태트리 (0) | 2016.04.12 |
---|---|
AI_ FSM / State (0) | 2016.04.12 |
ObjectManager (0) | 2016.04.12 |
PoolingManager (0) | 2016.04.12 |
게임 전체 클래스 UML 및 간단설명 (0) | 2016.04.12 |