보드(게임판) 구성
앞에서 만든 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; } |
'스터디 > MFC 테트리스' 카테고리의 다른 글
[01]윈도우 프로그램 껍데기 만들기 (0) | 2011.01.05 |
---|---|
VC6.0 테트리스 만들기 – 벽돌(Shape) 모양 (0) | 2010.12.31 |
VC6.0 테트리스 만들기 – 벽돌(Shape)만들기 (0) | 2010.12.29 |
VC6.0 테트리스 만들기 - OneBlock 구조 (0) | 2010.12.28 |
VC6.0 테트리스 만들기 - 구조 (0) | 2010.12.28 |