Software Development/C, C++

C언어로 게임만들기 - 5. 첫번째 게임_4)충돌처리

huiyu 2017. 3. 21. 22:01

이제 게임에서 충돌처리를 구현합니다.

공과 골대의 충돌처리를 통해 스코어를 낼 수 있게 처리하면 됩니다.


먼저, 공과 골대의 충돌을 구현하기 전에 Player의 양 옆에 경계 이상으로 넘어가지 않도록 처리합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void KeyProcess(int key)
{
    int remain;
    switch (key)
    {
    case 'j':
        if (g_Player.position.x <= 0break;
        g_Player.position.x--;
        ....
        break;
    case'l':
        if (g_Player.position.x + 1 >= GAME_MAX_WIDTH) break;
        g_Player.position.x++;
        ....
        break;
    case'k':
        ....
        break;
    }
}
cs

j키(왼쪽)로 이동할땐 0보다 작아진 경우 더 이상 이동하지 않게 처리하고,
l키(오른쪽)로 이동할 땐 게임사이즈보다 커지면 이동하지 않게 처리하면 됩니다.

이제 스코어를 내기위한 공의 충돌처리를 구현합니다.
아래 코드의 15라인~ 주석처리된 부분에 축가하면 됩니다.

공이 위쪽으로 이동할때마다 공이 골대에 부딪혔는지를 확인하는 코드를 추가하면 됩니다.

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
 
void Update()
{
    //공의 이동처리
    clock_t CurTime = clock();
int nLength = g_Post.nLength * 2 + 1;
    if (g_Ball.isReady == 0)
    {
        if ((CurTime - g_Ball.oldTime) > g_Ball.moveTime)
        {
            if (g_Ball.position.y > 0)
            {
                g_Ball.position.y--;
                g_Ball.oldTime = CurTime;
 
                //충돌처리 추가부분
                //~
                //~
            }
            else
            {
                g_Ball.isReady = 1;
                g_Ball.position.x = g_Player.position.x;
                g_Ball.position.y = g_Player.position.y - 1;
            }
        }
    }
 
    //골대 처리
    if (CurTime - g_Post.oldTime > g_Post.moveTime)
    {
        g_Post.oldTime = CurTime;
        if (g_Post.position.x + g_Post.nDist >= 0 && ((g_Post.nLineX[nLength - 1+ 3+ g_Post.nDist)<=GAME_MAX_WIDTH)
        {
            g_Post.position.x += g_Post.nDist;
            for(int i = 0; i < nLength; i++)
            {
                g_Post.nLineX[i] = g_Post.position.x + 2 * (i + 1);
            }
        }
        else
        {
            g_Post.nDist *= (-1);
        }
    }
    
}

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
void ResetBall()
{
    g_Ball.isReady = 1;
    g_Ball.position.x = g_Player.position.x;
    g_Ball.position.y = g_Player.position.y - 1;
}
 
void Update()
{
    ...
    //충돌처리
    //골대 라인충돌 시
    if (g_Ball.position.x >= g_Post.nLineX[0&& g_Ball.position.x + 1 <= g_Post.nLineX[nLength - 1])
    {
        if (g_Ball.position.y <= g_Post.position.y)
        {
            ResetBall();
        }
    }
    //골대 충돌
    else if ((g_Ball.position.x >= g_Post.nLineX[0- 2 && g_Ball.position.x <= g_Post.nLineX[0- 1|| 
             (g_Ball.position.x+1 >= g_Post.nLineX[0- 2 && g_Ball.position.x + 1 <= g_Post.nLineX[0- 1||
             (g_Ball.position.x>=g_Post.nLineX[nLength-1]+2 && g_Ball.position.x <= g_Post.nLineX[nLength-1+ 3||
             (g_Ball.position.x+1>=g_Post.nLineX[nLength-1]+2 && g_Ball.position.x+1 <= g_Post.nLineX[nLength - 1+ 3))
    {
        if (g_Ball.position.y <= g_Post.position.y)
        {
            ResetBall();
        }
    }
}
cs

1. 공의 칼럼의 크기는 2이므로, 모든 충돌 체크를 x와 x+1을 같이 하고 있다.
2. 마찬가지로 골대도 두칸씩 체크하고 있다. 그래서 골대충돌부분이 복잡해보이지만 골대 두칸, 골포스트 두칸씨 충돌 체크하고 있는 것이다.


마지막으로 골대 라인을 맞았을 경우 score를 올려주는 부분을 추가하면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int score = 0;
 
...
void Update(){
...
//골대 라인 충돌시
if(공이 골대라인에 부딪혔을 경우)
    score++;
...
}
 
void Render()
{
    ...
    char string[100= { 0, };
    sprintf(string"Score: %d", score);
    ScreenPrint(02string);
    ...
    ...
}
 
 
 
cs


실행시켜보면, 골대라인에 맞췄을 경우 정상적으로 스코어가 올라가는 것을 확인할 수 있습니다.


728x90