보드(게임판) 구성

   

 

앞에서 만든 7가지의 벽돌들이 놀 수 있는 Board(게임판)을 만들어 보겠습니다.

필요한 속성과 메소드는 다음과 같습니다.

속성

설명

COneBlock m_iBoard[BOARD_Y_SIZE+1][BOARD_X_SIZE+2]

Board 의 데이터

CClientDC *m_pDC;

출력디바이스

CShape *m_Shape;

움직이는 벽돌 포인터

CPoint m_ptOffsetDisplay;

보드의 출력 옵셋

BOOL m_bGameStart;

게임이 시작되었는가

CShapeArray m_arrayShape;

벽돌을 array로 관리

   

 

메소드는 다음과 같습니다.

메소드

설명

BOOL IsGameEnd();

게임이 끝났는지 확인

BOOL BlockDrop();

벽돌을 마지막 까지 내림

void RemoveLineDirect(int _line);

_line 번째 줄을 제거

void RemoveLine();

삭제할 수 있는 줄을 제거

void Refresh(BOOL bShape=TRUE);

화면 갱신

void NewShape();

새로운 벽돌 생성

void NewGame();

새로운 게임 시작

void MergeNowBlock();

벽돌를 보드에 포함

BOOL BlockRotate();

벽돌 회전

BOOL BlockMoveRight();

벽돌 우측 이동

BOOL BlockMoveLeft();

벽돌 좌측 이동

BOOL BlockMoveDown();

벽돌 아래로 한 칸 이동

BOOL IsOverlap(CShape s);

겹치는지 체크

void SetShape(CShape *_shape);

벽돌 설정

void SetOffsetDisplay(CPoint _pt);

화면 출력 옵셋 설정

void DrawOneBlock(int y,int x,int iSize,CClientDC *pDC, COLORREF crRGB, COLORREF crLine=RGB(255,255,255)) ;

벽돌 그리기

void DrawBoard(BOOL bShape=TRUE);

벽돌 그리기

void SetPDC(CClientDC *dc);

출력 디바이스 설정

   
   

 

 

 

 

 

Board.h

 

 

typedef CTypedPtrArray<CObArray, CShape*> CShapeArray;

 

class CBoard : public CObject

{

public:

    BOOL IsGameEnd();

    BOOL BlockDrop();

    void RemoveLineDirect(int _line);

    void RemoveLine();

    void Refresh(BOOL bShape=TRUE);

    void NewShape();

    void NewGame();

    void MergeNowBlock();

    BOOL BlockRotate();

    BOOL BlockMoveRight();

    BOOL BlockMoveLeft();

    BOOL BlockMoveDown();

 

    BOOL IsOverlap(CShape s);

    void SetShape(CShape *_shape);

    void SetOffsetDisplay(CPoint _pt);

 

    void DrawOneBlock(int y,int x,int iSize,CClientDC *pDC, COLORREF crRGB, COLORREF crLine=RGB(255,255,255)) ;

    void DrawBoard(BOOL bShape=TRUE);

    void SetPDC(CClientDC *dc);

 

    CShapeArray m_arrayShape;    // 벽돌들을 array로 관리

    CClientDC *m_pDC;

    COneBlock m_iBoard[BOARD_Y_SIZE+1][BOARD_X_SIZE+2];

    CShape *m_Shape;

    CPoint m_ptOffsetDisplay;    // 보드의 옵셋

    BOOL m_bGameStart;

 

    CBoard();

    virtual ~CBoard();

 

};

 

 

 

 

Board.cpp

 

 

CBoard::CBoard()

{

    m_Shape = NULL;

    m_bGameStart = false;

 

    m_ptOffsetDisplay = CPoint(0,0);

 

 

    // 랜덤 벽돌을 위한 함수

    srand( (unsigned)time( NULL ) );

 

 

    m_arrayShape.Add(new CShape1());

    m_arrayShape.Add(new CShape2());

    m_arrayShape.Add(new CShape3());

    m_arrayShape.Add(new CShape4());

    m_arrayShape.Add(new CShape5());

    m_arrayShape.Add(new CShape6());

    m_arrayShape.Add(new CShape7());

    NewGame();

 

}

 

CBoard::~CBoard()

{

    if(m_Shape)

    {

        delete m_Shape;

        m_Shape = NULL;

    }

}

 

void CBoard::SetPDC(CClientDC *dc)

{

    m_pDC = dc;

    m_Shape->SetPDC(dc);

}

 

void CBoard::DrawBoard(BOOL bShape)

{

    int tempY;

 

    for(tempY = 0;tempY<BOARD_Y_SIZE+1;tempY++){

        for(int tempX=0; tempX<BOARD_X_SIZE+2; tempX++)

        {

            if(0 != m_iBoard[tempY][tempX].m_iValue){

                DrawOneBlock((m_ptOffsetDisplay.y+tempY),m_ptOffsetDisplay.x+tempX,ONE_BLOCK_SIZE,m_pDC,RGB(200,200,200));

 

            }

        }

    }

 

    if(m_Shape)

    {

        m_Shape->SetPDC(m_pDC);

        m_Shape->DrawBlock();

 

    }

}

 

 

void CBoard::DrawOneBlock(int y,int x,int iSize,CClientDC *pDC, COLORREF crRGB, COLORREF crLine)

{

    pDC->FillSolidRect((x)*iSize, (y)*iSize,     iSize, iSize, crRGB);

    pDC->Draw3dRect((x)*iSize, (y)*iSize,         iSize, iSize, crLine,crLine);

}

 

 

void CBoard::SetOffsetDisplay(CPoint _pt)

{

    this->m_ptOffsetDisplay = _pt;

    m_Shape->SetOffsetDisplay(_pt);

}

 

 

void CBoard::SetShape(CShape *_shape)

{

    this->m_Shape = _shape;

}

 

 

void CBoard::NewGame()

{

    int tempY;

    int tempX;

 

    for(tempY = 0;tempY<BOARD_Y_SIZE+1;tempY++){

        for(tempX=0; tempX<BOARD_X_SIZE+2; tempX++)

        {

            m_iBoard[tempY][tempX].m_iValue = 0;

        }

    }

 

 

    // 보드의 좌측 벽

    for(int i=0;i<BOARD_Y_SIZE;i++){

        m_iBoard[i][0].m_iValue=50;

    }

 

    // 보드의 우측 벽

    for( i=0;i<BOARD_Y_SIZE;i++){

        m_iBoard[i][BOARD_X_SIZE+1].m_iValue=50;

    }

 

    // 보드의 하단 벽

    for( i=0;i<BOARD_X_SIZE+2;i++){

            m_iBoard[BOARD_Y_SIZE][i].m_iValue=50;

    }

 

 

    NewShape();

 

}

 

BOOL CBoard::BlockMoveDown()

{

    CShape s;

    s.Copy(m_Shape);

    

    s.m_ptPosition.y++;

    if(IsOverlap(s))

    {

//        LOGOUT(" 겹친다.");

        MergeNowBlock();

        RemoveLine();

        NewShape();

        Refresh();

 

        return FALSE;

    }

    else

    {

//        LOGOUT(" 안 겹친다.");

        m_Shape->MoveDown();

 

        return TRUE;

    }

}

 

BOOL CBoard::BlockMoveLeft()

{

    CShape s;

    s.Copy(m_Shape);

    

    s.m_ptPosition.x--;

    if(IsOverlap(s))

    {

        return FALSE;

 

    }

    else

    {

        m_Shape->MoveLeft();

        return TRUE;

 

    }

}

 

BOOL CBoard::BlockMoveRight()

{

    CShape s;

    s.Copy(m_Shape);

    

    s.m_ptPosition.x++;

    if(IsOverlap(s))

    {

        return FALSE;

    }

    else

    {

        m_Shape->MoveRight();

        return TRUE;

 

    }

}

 

BOOL CBoard::BlockRotate()

{

    CShape s;

    s.Copy(m_Shape);

    

    s.ChangeRotate();

    if(IsOverlap(s))

    {

        return FALSE;

    }

    else

    {

        m_Shape->RotateCCW();

        return TRUE;

 

    }

}

 

BOOL CBoard::BlockDrop()

{

    while(BlockMoveDown())

    {

 

    }

    return true;

}

 

 

BOOL CBoard::IsOverlap(CShape s)

{

    for (int iTemp = 0;iTemp<4;iTemp++)

    {

        COneBlock b =s.GetOneBlock(s.GetRotate(),iTemp);

 

        int x = s.m_ptPosition.x + b.iPosX;

        int y = s.m_ptPosition.y+ b.iPosY;

 

        if(0 != m_iBoard[y][x].m_iValue){

            return TRUE;

 

 

        }

    }

    return FALSE;}

 

 

void CBoard::MergeNowBlock()

{

 

    for (int iTemp = 0;iTemp<4;iTemp++)

    {

        COneBlock b =m_Shape->GetOneBlock(m_Shape->GetRotate(),iTemp);

 

        int x = m_Shape->m_ptPosition.x + b.iPosX;

        int y = m_Shape->m_ptPosition.y+ b.iPosY;

 

        m_iBoard[y][x].m_iValue = 50;

 

    }

}

 

 

void CBoard::RemoveLine()

{

    int p[4];//

    m_Shape->GetY(p);

 

    for (int iTemp = 0;iTemp<4;iTemp++)

    {    

        int iLineY = p[iTemp];

        if (-1 != iLineY)

        {

            BOOL bGoodOneLine = TRUE;

            for (int iTempBlockX = 0;iTempBlockX<BOARD_X_SIZE+2;iTempBlockX++)

            {

                if(0 == m_iBoard[iLineY][iTempBlockX].m_iValue ){ // 한칸이라도 빈칸이 있으면.

                    bGoodOneLine = FALSE;

                }

            }

 

            if(TRUE == bGoodOneLine){

                RemoveLineDirect(iLineY);

 

                for(int iTempLine = 0;iTempLine<4;iTempLine++)

                {

                    if(-1 !=p[iTempLine] && p[iTempLine]<iLineY)

                    {

 

                        p[iTempLine]++;

                    }

                }

                p[iTemp] = -1;

             }

        }

    }

}

 

void CBoard::NewShape()

{

    int iShape = rand()%m_arrayShape.GetSize();

    m_Shape = m_arrayShape.GetAt(iShape);

 

 

    m_Shape->m_ptPosition = CPoint(4,0);

    m_Shape->SetOffsetDisplay(m_ptOffsetDisplay);

}

 

void CBoard::Refresh(BOOL bShape)

{

    int tempY;

 

    for(tempY = 0;tempY<BOARD_Y_SIZE+1;tempY++){

        for(int tempX=0; tempX<BOARD_X_SIZE+2; tempX++)

        {

            DrawOneBlock((m_ptOffsetDisplay.y+tempY),m_ptOffsetDisplay.x+tempX,ONE_BLOCK_SIZE,m_pDC,RGB(0xc0,0xc0,0xc0),RGB(0xc0,0xc0,0xc0));

 

        }

    }

 

    DrawBoard(bShape);

}

 

void CBoard::RemoveLineDirect(int _line)

{

    while(_line >1)

    {

        LOGOUT("_line:%d",_line);

         for(int j=1;j<BOARD_X_SIZE+1;j++){

             m_iBoard[_line][j] =m_iBoard[_line-1][j] ;

            m_iBoard[_line-1][j].m_iValue = 0;

 

         }

        _line-- ;

    }

    Refresh(FALSE);

}

 

 

BOOL CBoard::IsGameEnd()

{

    for(int tempY = 0;tempY<2 ;tempY++){

        for(int tempX=3; tempX<7; tempX++)

        {

            if(0 != m_iBoard[tempY][tempX].m_iValue){

                return TRUE;

            }

        }

    }

 

    return FALSE;

}

 

 

+ Recent posts