Study/C++

[C++/Console] 테트리스 만들어 보기 - 5 (충돌 판정 - 벽, 블럭)

2023. 2. 20. 20:44
목차
  1. 충돌 판정
  2. 현재 까지의 진행 프로젝트 다운로드
 

[C++/Console] 테트리스 만들어 보기 - 4 (플레이어(블럭) 움직임)

[C++/Console] 테트리스 만들어 보기 - 3 (화면 출력에 대한 고찰) [C++/Console] 테트리스 만들어 보기 - 2 (키보드 입력 및 블럭) [C++/Console] 테트리스 만들어 보기 - 1 (간단 소개 및 더블 버퍼링) Window 환

eskeptor.tistory.com

지난 시간에는 플레이어(블럭)의 움직임에 관련하여 알아보았습니다.

오늘은 플레이어(블럭) 충돌 판정에 대해서 알아보겠습니다.

충돌 판정

지난 시간에 했던 프로젝트를 실행해서 움직여보면 좌, 우, 하단 끝에 도달하여도 계속 가는 것을 볼 수 있습니다.

이것을 방지하기 위해서는 충돌 판정을 통해서 움직이지 못하도록 해야합니다.

 

그럼 어떻게 하면 충돌 판정을 시킬 수 있을 까요?

 

void InputKey()
{
    int nKey = 0;

    if (_kbhit() > 0)
    {
        nKey = _getch();

        switch (nKey)
        {
            case eKeyCode::KEY_UP:
            {
                break;
            }
            case eKeyCode::KEY_DOWN:
            {
                g_player.AddPosition(0, 1);    // <-- 움직이기
                break;
            }
            case eKeyCode::KEY_LEFT:
            {
                g_player.AddPosition(-1, 0);   // <-- 움직이기
                break;
            }
            case eKeyCode::KEY_RIGHT:
            {
                g_player.AddPosition(1, 0);    // <-- 움직이기
                break;
            }
            case eKeyCode::KEY_SPACE:
            {
                break;
            }
            case eKeyCode::KEY_R:
            {
                break;
            }
        }
    }
}

현재 우리는 InputKey 함수에서 키를 누름과 동시에 플레이어(블럭)의 좌표를 증가하도록 하였습니다.

그래서 누름과 동시에 이동을 하게 됩니다.

 

그럼 좌표를 증가시키기 전에 그 위치로 이동해도 되는지 확인하는 과정(충돌을 하는지 안하는지)을 거치게 되면 벽을 넘어서지 못하도록 할 수 있습니다.

 

먼저 이전 맵의 데이터를 기록하는 배열을 전역으로 하나 만듭니다.

// Map Data (Backup Data)
int g_nArrMapBackup[MAP_HEIGHT][MAP_WIDTH] = { 0, };

이제부터 이 배열은 이전의 테트리스 맵을 백업하도록 할겁니다.

(이전이라고 함은 현재 블럭이 ㄴ 이고 이전 블럭이 ㅡ 일 때 ㄴ 블럭 이전의 맵 데이터)

 

그리고 충돌을 확인하는 IsCollision 함수를 작성합니다.

// pBlock : 블럭 데이터
// coordPlayer : 블럭의 위치
bool IsCollision(int* pBlock, const COORD& coordPlayer)
{
    int nColision = 0;

    for (int nY = 0; nY < BLOCK_HEIGHT; ++nY)
    {
        for (int nX = 0; nX < BLOCK_WIDTH; ++nX)
        {
            // 벽 충돌 유무
            nColision = pBlock[(nY * BLOCK_HEIGHT) + nX] & (g_nArrMapBackup[coordPlayer.Y + nY][coordPlayer.X + nX] << 1);
            // 다른 블럭과 충돌 유무
            nColision += pBlock[(nY * BLOCK_HEIGHT) + nX] & g_nArrMapBackup[coordPlayer.Y + nY][coordPlayer.X + nX];

            // 벽 또는 블럭과 충돌 했다면 충돌로 판정
            if (nColision > 0)
                return true;
        }
    }

    return false;
}

 

그리고 IsCollision 함수를 이용하여 키가 눌렸을 때 그 위치로 이동할 수 있는지 유무를 판단하는 함수인 IsMoveAvailable 함수를 작성합니다.

// nXAdder : 플레이어(블럭)이 이동할 X 위치(증가)
// nYAdder : 플레이어(블럭)이 이동할 Y 위치(증가)
bool IsMoveAvailable(int nXAdder, int nYAdder)
{
    // 현재 플레이어의 위치
    COORD coorNext = g_player.GetCursor();
    // 다음 위치를 미리 시뮬레이션
    coorNext.X += nXAdder;
    coorNext.Y += nYAdder;
    // 다음 위치로 이동한 블럭의 데이터
    int* pBlock = GetRotateBlock(g_player.GetBlock(), g_player.GetDirection());

    // 다음 위치로 이동 했을 때 충돌을 했는지 유무
    return !IsCollision(pBlock, coorNext);
}

 

이제 IsMoveAvailable 함수를 이용하여 충돌 감지하여 벽을 벗어나지 못하도록 해봅시다.

void InputKey()
{
    int nKey = 0;

    if (_kbhit() > 0)
    {
        nKey = _getch();

        switch (nKey)
        {
            case eKeyCode::KEY_UP:
            {
                break;
            }
            case eKeyCode::KEY_DOWN:
            {
                if (IsMoveAvailable(0, 1))
                    g_player.AddPosition(0, 1);
                break;
            }
            case eKeyCode::KEY_LEFT:
            {
                if (IsMoveAvailable(-1, 0))
                    g_player.AddPosition(-1, 0);
                break;
            }
            case eKeyCode::KEY_RIGHT:
            {
                if (IsMoveAvailable(1, 0))
                    g_player.AddPosition(1, 0);
                break;
            }
            case eKeyCode::KEY_SPACE:
            {
                break;
            }
            case eKeyCode::KEY_R:
            {
                break;
            }
        }
    }
}

 

그리고 이전의 테트리스 맵을 기억하는 백업용 배열을 초기화 합시다.

void InitGame(bool bInitConsole = true)
{
    // Initialize Player Data
    {
        // 생략 ......
    }

    if (bInitConsole)
    {
        // 생략 ......
    }

    // Map Backup
    {
        int nMapSize = sizeof(int) * MAP_WIDTH * MAP_HEIGHT;
        memcpy_s(g_nArrMap, nMapSize, ORIGIN_MAP, nMapSize);
        memcpy_s(g_nArrMapBackup, nMapSize, g_nArrMap, nMapSize);  // <-- 백업맵 초기화
    }
}

 

이제 실행하여 봅시다.

이렇게 벽에 닿으면 더이상 움직이지 않게 되었습니다.

 

다음 시간에는 블럭이 바닥에 닿았을 때 해당 블럭은 바닥에 남고 다음 블럭이 랜덤으로 생성되는 것에 대해서 알아보도록 하겠습니다.

 

현재 까지의 진행 프로젝트 다운로드

TetrisCpp_5편.7z
0.01MB

저작자표시 비영리 변경금지 (새창열림)

'Study > C++' 카테고리의 다른 글

[C++11] unordered_map  (0) 2023.03.20
[C++/Console] 테트리스 만들어 보기 - 6 (바닥 충돌, 블럭 랜덤 생성)  (0) 2023.03.06
[C++/Console] 테트리스 만들어 보기 - 4 (플레이어(블럭) 움직임)  (0) 2023.02.09
[C++/Console] 테트리스 만들어 보기 - 3 (화면 출력에 대한 고찰)  (0) 2023.02.02
[C++/Console] 테트리스 만들어 보기 - 2 (키보드 입력 및 블럭)  (0) 2023.01.29
  • 충돌 판정
  • 현재 까지의 진행 프로젝트 다운로드
'Study/C++' 카테고리의 다른 글
  • [C++11] unordered_map
  • [C++/Console] 테트리스 만들어 보기 - 6 (바닥 충돌, 블럭 랜덤 생성)
  • [C++/Console] 테트리스 만들어 보기 - 4 (플레이어(블럭) 움직임)
  • [C++/Console] 테트리스 만들어 보기 - 3 (화면 출력에 대한 고찰)
Eskeptor
Eskeptor
Eskeptor
Hello World
Eskeptor
전체
오늘
어제
  • 분류 전체보기 (138)
    • Computer (5)
      • Linux (1)
      • Hardware (2)
      • Software (0)
      • Tips (1)
      • Website (0)
    • Mobile (1)
      • Application (1)
    • Study (108)
      • Android (9)
      • C언어 (45)
      • C++ (17)
      • Unity 5(유니티5) (11)
      • Qt 프로그래밍 (2)
      • MFC (12)
      • C#, Winform (12)
    • My World (24)
      • OpenPad(Android) (12)
      • 한글 패치 (1)
      • C#으로 만든 귀요미들 (5)
      • MFC로 만든 귀요미들 (6)
    • Life Goes On (0)
      • Hip Hop (0)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록

공지사항

인기 글

태그

  • C#
  • 테트리스
  • Unity
  • C언어
  • 프로그래밍
  • 초보
  • 포인터
  • 슈팅게임
  • 유니티
  • openpad
  • MFC
  • C++
  • 배열
  • 기본
  • 오픈패드
  • 강좌
  • c++11
  • 만들기
  • Tetris
  • 메모장
  • 기초
  • Java
  • 강의
  • 자바
  • 자료구조
  • Android
  • 왕초보
  • 안드로이드
  • 알고리즘
  • 비행기

최근 댓글

최근 글

hELLO · Designed By 정상우.
Eskeptor
[C++/Console] 테트리스 만들어 보기 - 5 (충돌 판정 - 벽, 블럭)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.