개요

별게임을 개발하면서 가장 많이 변경된 두 클래스라고 생각합니다.

그만큼 앞으로도 많이 변경될 것으로 보입니다.

먼저 코드 전에 간단하게 설명하자면 

Bullet은 모든 Bullet 파생클래스들의 Base클래스 입니다.

모든 Bullet 들 에게 공통적으로 필요한 AI 조종행동 이나 이펙트, action 등을 정의합니다.


Shooter 역시 모든 Shooter 파생클래스의 Base클래스 입니다.


두 클래스가 공통적으로 가지고 있는 함수가 있다면 바로 operator new 와 operator delete 함수 입니다.

operator new 함수는 메모리를 실제로 할당하지 않고 PoolingManager에서 받아오기 위해 정의하였고 

operator delete 는 operator new의 특성을 커버할 수 있도록 정의 되었습니다.

( operator new / delete 에 대한 자세한 설명은 아래 포스팅을 참조해주세요. )

[MemoryPooling_1]

[MemoryPooling_2]

[operator new / operator delete]



이제 코드를 보겠습니다.

(가독성을 위해 필요한 부분만 적절히 편집하였습니다.)



코드


operator new

1
2
3
4
5
6
/* poolingManager에서 FreeMemory Block을 하나 가져옴 */
void* CBullet::operator new(size_t sizeconst 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

+ Recent posts