⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gamebo~1.cpp

📁 经典的一款俄罗斯方块-源程序.java.~
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	register const int nLines = m_pCurPiece->GetLines();

	for( register int l = nLines - 1 ; l >= 0 ; l-- ) {
		for( register int c = 0 ; c < nCols ; c++ ) {
			register const int nL = nLine - ((nLines-1) & l) ;
			register const int nC = nCol + c;

			if( m_pCurPiece->IsSquare(l, c) ) {
				if( nL >= Height() || nC < 0 || nC >= Width() )
					return false;
				else if( nL >= 0 && m_Board[nL][nC] != m_clrBackground )
					return false;
			}
		}
	}
	return true;
}


void CGameBoard::CheckBoard()
{
	for( register int l = Height() - 1 ; l > 0 ; --l ) {
		bool bLineComplete = true;
		for( register int c = Width() - 1 ; c >= 0 ; --c ) {
			ASSERT(l>0);
			ASSERT(c>=0);
			if( m_Board[l][c] == m_clrBackground ) {
				bLineComplete = false;
				break;
			}
		}
		if( bLineComplete ) {
			// show animated annihilation of that line
			{
				UINT * low = guBoomArray;
				UINT * high = ENDVEC(guBoomArray);
				CClientDC cdc(this);
				int nWidth = Width();
				m_SndLineComplete.Play();
				while( low <= high ) {
					HICON hIcon = AfxGetApp()->LoadIcon(*low);
					if( ! hIcon )
						break;
					for( register c1 = nWidth - 1; c1 >= 0; --c1 )
						::DrawIconEx(
							cdc.GetSafeHdc(),
							c1 * m_nSquareWidth, l * m_nSquareHeight,
							hIcon,
							m_nSquareWidth, m_nSquareHeight,
							0, 0, DI_NORMAL
						);
					::Sleep(100);
					++low;
				}
			}

			// remove that line from the board
			for( register int l1 = l ; l1 > 0 ; --l1 ) {
				for( register int c1 = Width() - 1 ; c1 >= 0 ; --c1 ) {
					ASSERT( l1 > 0 ) ;
					ASSERT( c1 >= 0 ) ;
					m_Board[l1][c1] = m_Board[l1-1][c1] ;
				}
			}
			++l ;	// try same line again ...
			OnLineComplete();
			m_SndPlace.Play();
			Paint();
		}
	}
}

void CGameBoard :: FixPiece() {
	ASSERT( m_pCurPiece != 0 ) ;

	m_SndPlace.Play();

	register const int nCols = m_pCurPiece->GetColumns() ;
	register const int nLines = m_pCurPiece->GetLines() ;

	for( register int l = nLines - 1 ; l >= 0 ; l-- ) {
		for( register int c = 0 ; c < nCols ; c++ ) {
			if( m_pCurPiece->IsSquare( l, c ) ) {
				int nL = m_nCurLine - ((nLines-1) & l) ;
				int nC = m_nCurCol + c ;
				if( nL >= 0 ) {
					ASSERT( nL < Height() ) ;
					ASSERT( nC >= 0 ) ;
					ASSERT( nC < Width() ) ;
					m_Board[nL][nC] = m_clrCurPiece;
				}
			}
		}
	}
	m_uPoints += UINT(m_pCurPiece->GetPoints()) + m_usLevel + (m_bExFigures ? 10 : 0);
}

void CGameBoard::OnLineComplete()
{
	++m_ulCompleteLines;
	m_uPoints += m_bExFigures ? 20 : 10;
	if( (m_ulCompleteLines % 10) == 0 ) {
		m_SndLevelWarp.Play();
		++m_usLevel;
		m_uPoints += m_bExFigures ? 20 : 10;
		if( m_usLevel >= 2 && m_bShowGrid )
			m_bShowGrid = FALSE;

		ResetTimer();
	}
	NotifyParent();
}

void CGameBoard::StartGame()
{
	InitBoard();
	ResetTimer();
	if( m_pMusic )
		m_pMusic->Play(TRUE);
}

void CGameBoard::StopGame()
{
	KillTimer(m_uTimer);
	if( m_pMusic )
		m_pMusic->Stop();
}

void CGameBoard::ResumeGame()
{
	ResetTimer();
	if( m_pMusic )
		m_pMusic->Continue();
}

void CGameBoard::PauseGame()
{
	KillTimer(m_uTimer);
	if( m_pMusic )
		m_pMusic->Pause();
}

void CGameBoard :: OnNewPiece()
{
	++m_ulPieces;
	NotifyParent();
	ResetTimer();
}

void CGameBoard :: OnGameOver()
{
	StopGame();
	CWnd * pParent = GetParent();
	ASSERT(pParent != 0);

	m_BoardNotifier.hdr.hwndFrom = GetSafeHwnd();
	m_BoardNotifier.hdr.idFrom = UINT(::GetWindowLong(GetSafeHwnd(), GWL_ID));
	m_BoardNotifier.hdr.code = NMB_GAMEOVER;

	m_SndGameOver.Play();

	pParent->SendMessage(WM_NOTIFY, WPARAM(m_BoardNotifier.hdr.idFrom), LPARAM(&m_BoardNotifier.hdr));
}

void CGameBoard::OnTimer(UINT nIDEvent) 
{
	if( m_pNextPiece == 0 ) {
		m_pNextPiece = SelectPiece();
		NotifyParent(FALSE);
	}

	if( m_pCurPiece == 0 ) {
		m_pCurPiece = m_pNextPiece;
		m_pNextPiece = 0;
		
		do {
			m_clrCurPiece = RGB(rand()%255, rand()%255, rand()%255);
		} while( m_clrCurPiece == m_clrBackground );

		m_nCurLine = 1;
		if( m_usLevel >= 4 )
			// random startpoint ...
			m_nCurCol = rand() % (Width()-m_pCurPiece->GetColumns()) ;
		else
			// fixed (centered) startpoint ...
			m_nCurCol = (Width() - m_pCurPiece->GetColumns()) / 2 ;

		if( ! CanPlace( m_nCurLine, m_nCurCol ) ) {
			OnGameOver();
			return ;
		}

		OnNewPiece();
	} else {
		if( ! CanPlace( m_nCurLine+1, m_nCurCol ) ) {
			FixPiece() ;
			delete m_pCurPiece ;
			m_pCurPiece = 0 ;
			CheckBoard() ;
		} else
			m_nCurLine++ ;
	}
	Paint() ;
}

LRESULT CALLBACK GameBoardWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uiMsg)									// Dispatch on message type
	{
	case WM_NCCREATE:								// On WM_NCCREATE we create a C++ object and attach it to the control
		{
			CGameBoard * pCtl = new CGameBoard();	// Create an instance of the class
			ASSERT(pCtl);							// Better not fail!
			BOOL b = pCtl->SubclassWindow(hWnd);	// Attach the window handle to the new object
			ASSERT(b);								// Better not fail!
			return b;								// Return result to continue/abort window creation
			break;
		}
	default:										// All other messages go through default window processor
		return ::DefWindowProc(hWnd, uiMsg, wParam, lParam);
	}
}

void CGameBoard::OnNcDestroy() 
{
	CWnd::OnNcDestroy();

	// Make sure the window was destroyed
	ASSERT(NULL == m_hWnd);

	// Destroy this object since it won't be destroyed otherwise
	delete this;
}

int CGameBoard::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	// Set the styles for the parent control
	ModifyStyleEx(0, WS_EX_CLIENTEDGE | WS_EX_NOPARENTNOTIFY);

	m_SndKey.Create(IDR_SndKey);
	m_SndPlace.Create(IDR_SndPlace);
	m_SndLevelWarp.Create(IDR_SndLevelWarp);
	m_SndGameOver.Create(IDR_SndGameOver);
	m_SndLineComplete.Create(IDR_SndLineComplete);

	return 0;
}

BOOL CGameBoard::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
}

void CGameBoard :: NotifyParent(BOOL bStatistics /* = TRUE */)
{
	CWnd * pParent = GetParent();
	ASSERT(pParent != 0);

	NMHDR & hdr = bStatistics ? m_BoardNotifier.hdr : m_PreviewNotifier.hdr;

	hdr.hwndFrom = GetSafeHwnd();
	hdr.idFrom = UINT(::GetWindowLong(GetSafeHwnd(), GWL_ID));
	hdr.code = bStatistics ? NMB_STATISTICS : NMB_PREVIEW;

	if( bStatistics ) {
		m_BoardNotifier.level	= UINT(m_usLevel);
		m_BoardNotifier.lines	= UINT(m_ulCompleteLines);
		m_BoardNotifier.pieces	= UINT(m_ulPieces);
		m_BoardNotifier.points	= UINT(m_uPoints);
	} else {
		ASSERT(m_pNextPiece != 0);
		m_PreviewNotifier.piece = m_pNextPiece;
	}
	pParent->SendMessage(WM_NOTIFY, WPARAM(hdr.idFrom), bStatistics ? LPARAM(&m_BoardNotifier) : LPARAM(&m_PreviewNotifier));
}

CPiece * CGameBoard::SelectPiece()
{
	CPiece * pPiece = 0;

	switch( rand() % (m_bExFigures ? 11 : 7) ) {
		case 0:
			pPiece = new CLongPiece();
			break;
		case 1:
			pPiece = new CSquarePiece();
			break;
		case 2:
			pPiece = new CRevLShapePiece();
			break;
		case 3:
			pPiece = new CLShapePiece();
			break;
		case 4:
			pPiece = new CTeeShapePiece();
			break;
		case 5:
			pPiece = new CSShapePiece();
			break;
		case 6:
			pPiece = new CRevSShapePiece();
			break;
		case 7:
			pPiece = new CCrossShapePiece();
			break;
		case 8:
			pPiece = new CUShapePiece();
			break;
		case 9:
			pPiece = new CZShapePiece();
			break;
		case 10:
			pPiece = new CRevZShapePiece();
			break;
	}

	ASSERT(pPiece != 0);

	return pPiece;
}

void CGameBoard::ResetTimer(BOOL bSpeed)
{
	if( m_uTimer )
		KillTimer(m_uTimer);
	srand(time(0));
	UINT uElaps = (m_usLevel < 20 && ! bSpeed) ? 500-(m_usLevel*25) : 50;
	m_uTimer = SetTimer(2, uElaps, 0);
}

void CGameBoard::EnableSound(BOOL bEnable) {
	m_SndKey.EnableSound(bEnable);
	m_SndPlace.EnableSound(bEnable);
	m_SndLevelWarp.EnableSound(bEnable);
	m_SndGameOver.EnableSound(bEnable);
	m_SndLineComplete.EnableSound(bEnable);
}

void CGameBoard::EnableMusic(BOOL bEnable) {
	delete m_pMusic;
	m_pMusic = 0;
	if( bEnable )
		m_pMusic = new CMIDI();
}


void CGameBoard::SetMusicType(UINT uResource) {
	if( m_pMusic ) {
		m_pMusic->Create(uResource, this);
		m_pMusic->SetVolume(m_dwVolume);
	}
}

void CGameBoard::OnMouseMove(UINT nFlags, CPoint point) 
{
	::SetCursor(0);
	CWnd::OnMouseMove(nFlags, point);
}

LONG CGameBoard :: OnVolumeChanged(WPARAM wParam, LPARAM lParam) {
	ASSERT(m_pMusic != 0);
	ASSERT(m_pMusic == (CMIDI *)wParam);
	// Volume of music changed during playback.
	// Reset the volume to what we want it to be.
	m_pMusic->SetChannelVolume(LOWORD(lParam), m_dwVolume);
	return 0;
}


void CGameBoard :: SetVolume(DWORD dwPercent) {
	ASSERT(dwPercent <= 100);
	m_dwVolume = dwPercent;
	if( m_pMusic )
		m_pMusic->SetVolume(m_dwVolume);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -