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

📄 gamebo~1.cpp

📁 经典的一款俄罗斯方块-源程序.java.~
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////
// This file is part of the completely free tetris clone "CGTetris".
//
// This is free software.
// You may redistribute it by any means providing it is not sold for profit
// without the authors written consent.
//
// No warrantee of any kind, expressed or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
/////////////////////////////////////////////////////////////////////////////


// GameBoard.cpp : implementation file
//

#include "stdafx.h"
#include "Tetris.h"
#include "GameBoard.h"
#include "Piece.h"
#include "MemDC.h"
#include "VolumeCtrl.h"

#include <stdlib.h>
#include <time.h>

using namespace std;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


static CGameBoard * gpGameBoard;

CGameBoard * TetrisGetGameBoard() { return gpGameBoard; }


static	UINT	guBoomArray[] = {
					IDI_Boom_1,
					IDI_Boom_2,
					IDI_Boom_3,
					IDI_Boom_4,
					IDI_Boom_5,
					IDI_Boom_6,
					IDI_Boom_7,
					IDI_Boom_8,
					IDI_Boom_9,
					IDI_Boom_10,
				};

#define ENDVEC( vector )	(vector-1+sizeof(vector)/sizeof(vector[0]))

/////////////////////////////////////////////////////////////////////////////
// CGameBoard

BOOL		CGameBoard :: m_bRegistered = Register();

IMPLEMENT_DYNAMIC(CGameBoard, CWnd);

CGameBoard::CGameBoard()
{
	m_pCurPiece = m_pNextPiece = 0;
	m_usLevel = 0;
	m_clrCurPiece = RGB(0,0,0);
	m_bShowGrid = TRUE;
	m_nSquareWidth = 14;
	m_nSquareHeight = 14;
	m_clrBackground = RGB(255, 255, 255);
	m_bExFigures = FALSE;
	m_pMusic = 0;
	m_uTimer = 0;
	m_dwVolume = 100;	// 100% music volume by default

	gpGameBoard = this;
}

CGameBoard::~CGameBoard()
{
	if(m_pCurPiece)
		delete m_pCurPiece;
	if(m_pNextPiece)
		delete m_pNextPiece;

	if( m_pMusic )
		delete m_pMusic;

	gpGameBoard = 0;
}

BOOL CGameBoard :: Register()
{
	WNDCLASS wc;
	wc.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = GameBoardWndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = 0;
	wc.hIcon = 0;
	wc.hCursor = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszMenuName = 0;
	wc.lpszClassName = TEXT("TetrisGameBoard");
	VERIFY(RegisterClass(&wc));
	return TRUE;
}

BEGIN_MESSAGE_MAP(CGameBoard, CWnd)
	//{{AFX_MSG_MAP(CGameBoard)
	ON_WM_PAINT()
	ON_WM_TIMER()
	ON_WM_NCDESTROY()
	ON_WM_CREATE()
	ON_WM_ERASEBKGND()
	ON_WM_KEYDOWN()
	ON_WM_KEYUP()
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_MIDI_VOLUMECHANGED, OnVolumeChanged)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CGameBoard message handlers

void CGameBoard::ShowGrid(BOOL bShow)
{
	m_bShowGrid = bShow;
}

void CGameBoard :: Paint()
{
	Invalidate();
	//UpdateWindow();
	OnPaint();	// force an immediately paint
}

void CGameBoard :: OnPaint()
{
	CPaintDC pdc(this); // device context for painting

	CMemDC dc(&pdc);

	COLORREF clrTopLeft = ::GetSysColor(COLOR_BTNHILIGHT);
	COLORREF clrBottomRight = ::GetSysColor(COLOR_BTNSHADOW);

	CRect rect;
	GetClientRect(rect);
	
	dc.FillSolidRect(0, 0, rect.Width(), rect.Height(), m_clrBackground);

	register const UINT uWidth = Width(rect);
	register const UINT uHeight = Height(rect);

	// paint the board itself
	for( register UINT i=0; i<uHeight; ++i )
		for( register UINT j=0; j<uWidth; ++j ) {
			if( m_Board[i][j] != m_clrBackground ) {
				dc.FillSolidRect(j*m_nSquareWidth, i*m_nSquareHeight, m_nSquareWidth, m_nSquareHeight, m_Board[i][j]);
				dc.Draw3dRect(j*m_nSquareWidth, i*m_nSquareHeight, m_nSquareWidth, m_nSquareHeight, clrTopLeft, clrBottomRight);
			}
		}

	// now paint the current piece ...
	if( m_pCurPiece != 0 ) {
		register const int nLines = m_pCurPiece->GetLines();
		register const int nCols  = m_pCurPiece->GetColumns();

		for( register int l = nLines-1 ; l >= 0 ; --l )
			for( register int c = 0 ; c < nCols ; ++c ) {
				int nL = m_nCurLine - ((nLines-1) & l);
				int nC = m_nCurCol + c;
				if( nL >= 0 && nL < Height() &&
					nC >= 0 && nC < Width() )
					if( m_pCurPiece->IsSquare(l, c) ) {
						dc.FillSolidRect(nC*m_nSquareWidth, nL*m_nSquareHeight, m_nSquareWidth, m_nSquareHeight, m_clrCurPiece);
						dc.Draw3dRect(nC*m_nSquareWidth, nL*m_nSquareHeight, m_nSquareWidth, m_nSquareHeight, clrTopLeft, clrBottomRight);
					}
			}
	}

	// draw the grid
	if( m_bShowGrid ) {
		// draw vertical lines
		for( register h = m_nSquareWidth; h < rect.Width(); h += m_nSquareWidth ) {
			dc.MoveTo(h, 0);
			dc.LineTo(h, rect.bottom);
		}

		// draw horizontal lines
		for( register v = m_nSquareHeight; v < rect.Height(); v += m_nSquareHeight ) {
			dc.MoveTo(0, v);
			dc.LineTo(rect.right, v);
		}
	}
}

void CGameBoard::SetDimension(int nWidth, int nHeight)
{
	m_nSquareWidth = nWidth;
	m_nSquareHeight = nHeight;
}

void CGameBoard::GetDimension(int & nWidth, int & nHeight)
{
	nWidth = m_nSquareWidth;
	nHeight = m_nSquareHeight;
}

int CGameBoard::Width(LPCRECT pRect) const
{
	CRect rect(pRect ? pRect : CRect(0,0,0,0));
	if( ! pRect )
		GetClientRect(rect);

	return rect.Width() / m_nSquareWidth;
}

int CGameBoard::Height(LPCRECT pRect) const
{
	CRect rect(pRect ? pRect : CRect(0,0,0,0));
	if( ! pRect )
		GetClientRect(rect);

	return rect.Height() / m_nSquareHeight;
}

void CGameBoard::InitBoard()
{
	CRect rect;
	GetClientRect(rect);
	register const int nHeight = Height(rect);
	register const int nWidth = Width(rect);
	m_Board.resize(nHeight, vector<COLORREF>());
	for( register int i=0; i<nHeight; ++i ) {
		m_Board[i].resize(nWidth, m_clrBackground);
		for( register int j=0; j<nWidth; ++j )
			m_Board[i][j] = m_clrBackground;
	}

	m_ulCompleteLines = 0;
	m_usLevel = 0;
	m_ulPieces = 0;
	m_uPoints = 0;

	if( m_uTimer )
		KillTimer(m_uTimer);
	m_uTimer = 0;

	if( m_pCurPiece )
		delete m_pCurPiece;
	m_pCurPiece = 0;
	if( m_pNextPiece )
		delete m_pNextPiece;
	m_pNextPiece = SelectPiece();

	NotifyParent();

	Paint();
}

void CGameBoard::MoveLeft() {
	ASSERT(m_pCurPiece);	// make sure we're inside a game

	if( CanPlace(m_nCurLine, m_nCurCol-1) ) {
		--m_nCurCol;
		m_SndKey.Play();
	}
}

void CGameBoard::MoveRight() {
	ASSERT(m_pCurPiece);	// make sure we're inside a game

	if( CanPlace(m_nCurLine, m_nCurCol+1) ) {
		++m_nCurCol;
		m_SndKey.Play();
	}
}

void CGameBoard::Rotate() {
	ASSERT(m_pCurPiece);	// make sure we're inside a game

	m_pCurPiece->Rotate();
	if( ! CanPlace(m_nCurLine, m_nCurCol) )
		m_pCurPiece->BackRotate();
	else
		m_SndKey.Play();
}

void CGameBoard::BackRotate() {
	ASSERT(m_pCurPiece);	// make sure we're inside a game

	m_pCurPiece->BackRotate();
	if( ! CanPlace(m_nCurLine, m_nCurCol) )
		m_pCurPiece->Rotate();
	else
		m_SndKey.Play();
}

void CGameBoard::StartFall() {
	if( m_uTimer ) {
		m_SndKey.Play();
		ResetTimer(TRUE);	// increase speed to maximum
	}
}

void CGameBoard::StopFall() {
	if( m_uTimer )
		ResetTimer();	// restore speed
}

void CGameBoard::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if( m_pCurPiece ) {
		switch(nChar) {
			case VK_LEFT:
			case VK_NUMPAD4:
				MoveLeft();
				break;

			case VK_RIGHT:
			case VK_NUMPAD6:
				MoveRight();
				break;

			case VK_UP:
			case VK_NUMPAD8:
			case VK_NUMPAD5:
				Rotate();
				break;

			case VK_DOWN:
			case VK_NUMPAD2:
				BackRotate();
				break;

			case VK_SPACE:
			case VK_NUMPAD0:
				if( !(nFlags & (1<<14)) ) {
					// the key was not down before
					StartFall();
				}
				break;
			case VK_ADD:
			case VK_SUBTRACT:
			case TCHAR('+'):
			case TCHAR('-'):
				if( m_pMusic ) {
					CVolumeCtrl dlg(m_pMusic);
					dlg.DoModal();
					m_dwVolume = dlg.GetVolume();
				}
				break;
		}
	}
	Paint();
	CWnd::OnChar(nChar, nRepCnt, nFlags);
}


void CGameBoard::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if(nChar == VK_SPACE || nChar == VK_NUMPAD0) {
		if( (nFlags & (1<<14)) ) {
			// the key was down before
			StopFall();
		}
	} else
		CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
}


bool CGameBoard::CanPlace(int nLine, int nCol)
{
	ASSERT( m_pCurPiece != 0 );

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

⌨️ 快捷键说明

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