[Cocos2d-x] Day 2 - Create Box / Box CollisionCheck

|


 <DAY> 2016.05.19

 < WORK LIST >
 <Class> Object_Box.cpp & Box_Manager.cpp

 - Box Create & Box CollisionCheck

 - Box_Manager.h & Box_Manager.cpp

 


   1

  Box Create & Box CollisionCheck

충돌 체크 함수

1
2
3
4
5
6
7
bool Object_Box::CollisionCheck( CGPoint _pos )
{
    CGRect rc;
    rc.origin = ccp( this->getPosition().x, this->getPosition().y );
    rc.size   = CGSize( 100100 );
    return CGRect::CGRectContainsPoint( rc, _pos );
}
cs


박스 이미지 생성

그리고, 충돌체크 함수를 하나 만들었다.

기본적으로 박스의 위치, 사이즈가 들어있다.

매개 변수로는 플레이어의 위치를 받는다.

1
2
3
4
5
6
7
8
9
bool Object_Box::init( CGSize _size )
{
    if!CCSprite::initWithFile("TestImage/BOX.png") ) return false;
 
    this->setAnchorPoint( ccp(0,0) );
    this->setScaleX( _size.width / 100 );
    this->setScaleY( _size.height / 100 );
    return true;
}
cs



   2

  Box_Manager.h & Box_Manager.cpp


여러개의 박스를 관리하기 위한 박스 매니저 클래스 생성.

1
2
3
4
5
6
7
8
9
10
#define MAXBOX    50
 
class Box_Manager : public CCSprite{
public:
    Object_Box * m_pBox[MAXBOX];
 
    void init(){ memset( m_pBox, NULLsizeof(m_pBox) ); }
    Object_Box * AddBox( CGPoint _pos );
    Object_Box * CollisionCheck( CGPoint _pos );
};
cs


AddBox 함수를 만들어서 씬_타워 init에서 박스를 추가한다.

화면에 실질적으로 박스가 추가된다.

그리고 충돌체크 함수를 만들었다.

플레이어가 실질적으로 충돌 했을 때 부딪힌 블럭을 for문을 통해 검사하여 플레이어의 

위치를 매개변수로 보내고 

부딪힌 블럭을 반환 받는다.

만약 부딪힌 블럭이 충돌되지 않았을 때 if( Box == NULL ),

setPosition을 하지 않으 므로써

플레이어가 박스 안으로 들어가지 않게 된다.

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
Object_Box * Box_Manager::AddBox( CGPoint _pos )
{
    for(int i = 0; i < MAXBOX; i++)
    {
        if( m_pBox[i] == NULL )
        {
            m_pBox[i] = new Object_Box;
            m_pBox[i]->init( CGSize(50,10) );
            m_pBox[i]->setAnchorPoint( ccp( 00 ) );
            m_pBox[i]->setPosition( _pos );
            return m_pBox[i];
        }
    }
    return NULL;
}
 
Object_Box * Box_Manager::CollisionCheck( CGPoint _pos )
{
    for(int i = 0; i < MAXBOX; i++ )
    {
        if( m_pBox[i] == NULL ) continue;
        if( m_pBox[i]-> CollisionCheck( _pos ))
            return m_pBox[i];
    }
    return NULL;
}
 
cs


결과



평 가

 .난이도 : 쉬움

 별   점 : ★★☆ 

 한 마디: 맵의 토대 마련.




<Progress List> 

 - Key Control

 - Gravity Jump

 - Box Create

 - Box CollisionCheck


<Complete List> 

  - No Data

  - No Data

  - No Data

  - No Data






And

[Cocos2d-x] Day 1 - KeyInput & Gravity Jump

|


 <DAY> 2016.05.18
 < WORK LIST >
 <Class> Object_Hero.cpp
 - Image output
 - Key Input Control <RIGHT / LEFT / UP / DOWN >
 - GRAVITY JUMP


   1

  Image Outpu


키 입력 확인을 위한 이미지를 임시로 출력.

1
2
3
4
5
6
7
8
9
bool Object_Hero::init()
{
    if!CCSprite::initWithFile("TestImage/boom1.png")) return false;
 
    m_iState        = IDLE;
    this->schedule( schedule_selector( Object_Hero::update ));
    return true;
}
 

cs


   2

  Key Input


키 입력에 따라 달라질 상태를 #define, enum으로 선언한다.

1
2
3
4
5
6
#define JUMPPOWER    700
#define GRAVITY      1500
 
enum State{
    IDLE, WALK, JUMP, DROP
};
cs


키 입력에 따른 변화
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
void Object_Hero::KeyInput(float dt)
{
    CGPoint pos = this->getPosition();
    float MoveSpeed = 300.* dt;
 
    if(GetAsyncKeyState(VK_RIGHT))
    {
        pos.x += MoveSpeed;
        ST::call()->vi.vec.x = 1;
        if( m_iState != JUMP && m_iState != DROP )
            m_iState = WALK; 
    }
    if(GetAsyncKeyState(VK_LEFT))
    {
        ST::call()->vi.vec.x = -1;
        pos.x -= MoveSpeed;
        if( m_iState != JUMP && m_iState != DROP )
            m_iState = WALK; 
    }
    if(GetAsyncKeyState(VK_UP))
    {
        ST::call()->vi.vec.y = 1;
        pos.y += MoveSpeed;
    }
    if(GetAsyncKeyState(VK_DOWN))
    {
        ST::call()->vi.vec.y = -1;
        pos.y -= MoveSpeed;
    }
 
    static bool KeyPress = false;
    if(GetAsyncKeyState('C') && KeyPress == false )
    {
        if( m_iState != DROP && m_iState != JUMP )
        {
            m_iState = JUMP;
            m_fJumpPower = JUMPPOWER;
            KeyPress = true;
        }
    }
    else if(!GetAsyncKeyState('C')) KeyPress = false;
 
 
    Object_Box * Box = ST::call()->BM.CollisionCheck( pos );
 
    if( Box == NULL ) 
    {
        this->setPosition(pos);
    }
    /*else
    {
        pos.y -= Box->getPosition().y;
        if( Box->getPosition().y + 50 > pos.y )
        {
            pos.y = Box->getPosition().y;
            m_iState = IDLE;
            m_fJumpPower = 0;
        }
        this->setPosition(pos);
    }*/
}
 
cs



   3

  Gravity Jump


중력을 임시로 구현.

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
void Object_Hero::Animation(float dt)
{
    CGPoint pos = this->getPosition();
 
    switch(m_iState)
    {
        case IDLE:
            {
                break;
            }
        case JUMP:
            {
                pos.y       += m_fJumpPower * dt;
                m_fJumpPower -= GRAVITY * dt;
 
                if( m_fJumpPower <= 0 )
                {
                    m_iState = DROP;
                    m_fJumpPower = 0;
                }
                break;
            }
        case DROP:
            {
                pos.y        -= m_fJumpPower * dt;
                m_fJumpPower += GRAVITY * dt;
                 
                if( pos.y <= 0 )
                {
                    pos.y = 0;
                    m_iState = IDLE;
                }
                break;
            }
    }
 
    this->setPosition( pos );
}
cs


결과



평 가

 .난이도 : 쉬움

 별   점 : ★ 

 한 마디: 시작을 위한 한 걸음.



And

캐릭터 이동제한, y축 점프이동거리 감소, 홀드

|

우선 캐릭터 이동거리 제한을 합시다.



빨간색 칸 안에서만 이동할 수 있도록 합시다.

첫 번째로 할 일은 캐릭터의 시작 지점을 바꿔주는 일입니다.


캐릭터의 시작 지점을 정해 주는 변수는 m_Position인데 Object클래스에서 상속받아서 사용하고 있습니다.

그렇기 때문에 Object클래스에 있는 변수의 값을 바꿔주도록 하겠습니다.


1
2
3
4
5
void Object::Init( HBITMAP _m_hResource )
{
    m_hResource   = _m_hResource;
    m_Position    = MakePoint(100,500);
}
cs


그러면 위 이미지와 같이 캐릭터가 저만한 위치에 서게 됩니다.


그리고 이동제한을 걸도록 하죠

1
2
if(pos.x > 0 && pos.x < 1080 && pos.y > 340 && pos.y < 570 )
    this->SetPos(pos.x, pos.y);
cs


저 if범위가 저 빨간색 칸의 범위 입니다.

캐릭터가 저 범위의 안에 있을때만 좌표를 Set하게 해서 범위 밖을 벗어나면 Set을 안하게 됨으로

캐릭터가 밖으로 나가지 못하게 됩니다.


1
2
3
void Hero::Action( float _dt )
{
}
cs

액션 함수 안에 넣어주시면 되겠습니다.


두 번째로 점프시 y축 이동 감소를 하도록 하겠습니다.

간단합니다

1
2
3
4
5
6
7
8
9
10
if(GetAsyncKeyState(VK_UP))
{
    if( m_iState != JUMP && m_iState != DROP ){ m_iState = WALK; pos.y -= m_MoveSpeed; }
    else pos.y -= m_MoveSpeed / 3;
}
if(GetAsyncKeyState(VK_DOWN))
{
    if( m_iState != JUMP && m_iState != DROP ){ m_iState = WALK; pos.y += m_MoveSpeed; }
    else pos.y += m_MoveSpeed / 3;
}
cs

점프중이 아니고 떨어지는 중이 아니면 일반적인 속도를

점프 중일때는 m_MoveSpeed / 3 스피드를 3/1로 감소 시킵니다.


마지막으로 홀드를 적용 시킵시다.

홀드는 점프를 시작할 때 움직일수 없게 하고

착지 할때 움직일 수 없게 하기 위한 것입니다.


클래스 맴버변수로

1
bool m_hold;
cs

를 추가 시킵시다.

초기화는

1
m_hold            =    FALSE;
cs

FALSE로 주시고


1
2
3
4
5
6
7
8
9
10
if(GetAsyncKeyState(VK_RIGHT))
{
    if(m_hold == FALSE ){ pos.x += m_MoveSpeed; m_iDirection = RIGHT; }
    if( m_iState != JUMP && m_iState != DROP ) m_iState = WALK;
}
if(GetAsyncKeyState(VK_LEFT))
{
    if(m_hold == FALSE ){ pos.x -= m_MoveSpeed; m_iDirection = LEFT; }
    if( m_iState != JUMP && m_iState != DROP ) m_iState = WALK;
}
cs

액션 함수에서의 키 값은

홀드가 FALSE일때만 움직일 수 있게 하면 됩니다.



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
case JUMP:
    {
        m_srcPos        =    MakePoint(85,135);
        m_srcSize       =    MakePoint(m_iDirection == RIGHT ? 0 : 610610);
        m_offset        =    MakePoint(-m_srcPos.x / 2-m_srcPos.y);
 
        m_dFrameDelay += _dt;
        if(m_dFrameDelay < 0.1f)
        {
            m_JumpPower = JUMP_POWER;
            m_nFreame = 0;
            m_hold = TRUE;
            break;
        }
            
        m_fz += m_JumpPower * _dt;
        m_JumpPower -= GRAVITY * _dt;
 
        if(m_dFrameDelay > 0.1f){m_nFreame = 1; m_hold = FALSE;}
        if(m_dFrameDelay > 0.2f) m_nFreame = 2;
        if(m_dFrameDelay > 0.3f) m_dFrameDelay = 0.1f;
 
        if(m_JumpPower <= 0)
        {
            m_iState = DROP;
            m_JumpPower = 0;
            m_hold = FALSE;
        }
        break;
    }
cs


1
2
3
4
5
6
7
if(m_dFrameDelay < 0.1f)
{
    m_JumpPower = JUMP_POWER;
    m_nFreame = 0;
    m_hold = TRUE;
    break;
}
cs

점프 파워를 셋팅하는 부분에 홀드를 TRUE로 주겠습니다.

TRUE가 됬으니 움직이지 못할 겁니다.

하지만 게속 그 상태를 유지하면 안되므로


1
if(m_dFrameDelay > 0.1f){m_nFreame = 1; m_hold = FALSE;}
cs

시간 딜레이가 0.1보다 커지면 홀드를 FALSE로 바꿔주어 풀어 줍니다.


그리고 착지 할때도 움직이게 하면 안되므로

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    case DROP:
        {
            m_srcPos        =    MakePoint(85,135);
            m_srcSize       =    MakePoint(m_iDirection == RIGHT ? 0 : 610610);
            m_offset        =    MakePoint(-m_srcPos.x / 2-m_srcPos.y);
 
            m_fz -= m_JumpPower * _dt;
            m_JumpPower += GRAVITY * _dt;
            m_dFrameDelay += _dt;
 
            if(m_fz <= 0)
            {
                m_fz = 0;
                if(m_dFrameDelay > 0.2f) m_nFreame = 5;
                if(m_dFrameDelay > 0.3f) m_nFreame = 6;
                if(m_dFrameDelay > 0.4f){m_iState = IDLE; m_hold = TRUE; }
            }
            else
            {
                m_nFreame = 3;
                if(m_dFrameDelay > 0.1f) m_nFreame = 4;
            }
            break;
        }
cs


1
2
if(m_dFrameDelay > 0.4f){m_iState = IDLE; m_hold = TRUE; }
 
cs

딜레이 시간이 0.4보다 커질때 홀드를 TRUE시켜줍니다.

그럼 언제 홀드를 해제(FALSE)해 주느냐?


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
case IDLE:
        {
            m_srcPos        =    MakePoint(54,144);
            m_srcSize       =    MakePoint(m_iDirection == RIGHT ? 0 : 61010);
            m_offset        =    MakePoint(-m_srcPos.x / 2-m_srcPos.y);
 
            m_dFrameDelay += _dt;
            if(m_dFrameDelay > 0.1f)
            {
                m_dFrameDelay = 0;
                m_nFreame++;
                m_hold = FALSE;
                if(m_nFreame >= 4) m_nFreame = 0;
            }
            break;
        }
    case WALK:
        {
            m_srcPos        =    MakePoint(75,143);
            m_srcSize       =    MakePoint(m_iDirection == RIGHT ? 0 : 610310);
            m_offset        =    MakePoint(-m_srcPos.x / 2-m_srcPos.y);
 
            m_dFrameDelay += _dt;
            if(m_dFrameDelay > 0.1f)
            {
                m_dFrameDelay = 0;
                m_nFreame++;
                m_hold = FALSE;
                if(m_nFreame >= 8) m_nFreame = 0;
            }
            break;
        }
 
cs

IDLE상태와  WALK상태 일때 하시면 됩니다.



결과




'API > 이론' 카테고리의 다른 글

캐릭터 점프  (0) 2016.05.01
메모리 생성을 각 클래스 안으로 넣기.  (0) 2016.04.30
싱글턴을 이용한 메인함수의 메모리 버퍼 정리  (0) 2016.04.30
싱글턴 패턴  (0) 2016.04.30
이미지 깜박거림 없앰.  (0) 2016.04.29
And
prev | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ··· | 15 | next