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

📄 testview.cpp

📁 Visual studio 2005 C++ 俄罗斯方块游戏实例 详细的介绍了编码方法~
💻 CPP
字号:
// testView.cpp : CtestView 类的实现
//

#include "stdafx.h"
#include "test.h"

#include "testDoc.h"
#include "testView.h"
#include "Set.h"
#include "file.h"
#include "time.h"
#include <mmsystem.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CtestView

IMPLEMENT_DYNCREATE(CtestView, CView)

BEGIN_MESSAGE_MAP(CtestView, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
	ON_WM_TIMER()
	ON_WM_KEYDOWN()
	ON_COMMAND(ID_Start, &CtestView::OnStart)
	ON_COMMAND(ID_Stop, &CtestView::OnStop)
	ON_COMMAND(ID_Restart, &CtestView::OnRestart)
	ON_COMMAND(ID_Pause, &CtestView::OnPause)
	ON_COMMAND(ID_SET, &CtestView::OnSet)
END_MESSAGE_MAP()

// CtestView 构造/析构

CtestView::CtestView()
{
	ss=900;
	m_nbegin=false;
	int i,j;
	for(i=0;i<22;i++)
		for(j=0;j<35;j++)   // from bottom to top
			map[i][j]=-1;
	first=true;
	end=false;
	start=true;
	score=0;
	gray.CreatePen(PS_SOLID,1,RGB(228,228,228));
}

CtestView::~CtestView()
{
}

BOOL CtestView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CtestView 绘制

void CtestView::OnDraw(CDC* pDC)
{
	CtestDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	CBitmap bmp;
	bmp.LoadBitmap(IDB_BITMAP1);
	BITMAP bs;
	bmp.GetBitmap(&bs);
	CDC dc;
	dc.CreateCompatibleDC(pDC);
	CBitmap *pOldBmp = (CBitmap*)dc.SelectObject(&bmp);

	CPen *old=dc.SelectObject(&gray);
	dc.MoveTo(0,455);
	dc.LineTo(242,455);
	dc.LineTo(242,0);
	dc.Rectangle(260,35,350,125);
	pDC->BitBlt(10, 10, bs.bmWidth, bs.bmHeight, &dc, 0, 0, SRCCOPY);

}

void CtestView::drawone(int i,int j,int colour,CDC *pDC)
{
	// 画一个方块
	// 取方块的 左上角坐标(x1,y1)  还有右下角坐标(x2,y2)
	int x1=i*15;
	int y1=j*15;
	int x2=x1+15;
	int y2=y1+15;
	
	// 画方块
	pDC->SelectObject(&gray);
	pDC->Rectangle(x1,y1,x2,y2);
	clien.SetRect(x1+1,y1+1,x2-1,y2-1);
	if(colour==0) pDC->FillSolidRect(clien,RGB(0,0,255));  // blue
	else if(colour==1) pDC->FillSolidRect(clien,RGB(0,255,0));  //green
	else if(colour==2) pDC->FillSolidRect(clien,RGB(255,0,0));
	else if(colour==3) pDC->FillSolidRect(clien,RGB(255,255,0));
	else if(colour==4) pDC->FillSolidRect(clien,RGB(0,255,255));
	else if(colour==5) pDC->FillSolidRect(clien,RGB(255,0,255));
}

void CtestView::reflash(int mode)
{
	CDC *pDC = GetDC();
	CBitmap bmp;
	bmp.LoadBitmap(IDB_BITMAP1);
	BITMAP bs;
	bmp.GetBitmap(&bs);
	CDC dc;
	dc.CreateCompatibleDC(pDC);
	CBitmap *pOldBmp = (CBitmap*)dc.SelectObject(&bmp);
	int i,j;
	for(i=0;i<30;i++)
		for(j=0;j<=wide;j++)
		{
			if(map[j][i]!=-1)
				drawone(j,29-i,map[j][i],&dc);
		}
	CPen *old=dc.SelectObject(&gray);
	dc.MoveTo(0,455);
	dc.LineTo(242,455);
	dc.LineTo(242,0);
	dc.Rectangle(260,35,350,125);
	shownext(&dc);
	//showscore(&dc);
	if(mode==0)
	{
		for(i=0;i<4;i++)
			drawone(tod[i][0],tod[i][1],colour,&dc);
	}
	showscore(&dc);
	pDC->BitBlt(10, 10, bs.bmWidth, bs.bmHeight, &dc, 0, 0, SRCCOPY);
	ReleaseDC(pDC);
	
}

void CtestView::shownext(CDC *pDC)
{
	int m=shape[nshp][nloop][16];
	int n=shape[nshp][nloop][17];
	// 取方块的 左上角坐标(x1,y1)  还有右下角坐标(x2,y2)
	for(int i=0;i<lentdn;i++)
	{
		int x1=next[i][0]*15+275;
		int y1=next[i][1]*15+50;
		int x2=x1+15;
		int y2=y1+15;

		if(m==2) x1+=15,x2+=15;
		else if(m==1) x1+=30,x2+=30;
		if(n==2) y1+=15,y2+=15;
		else if(n==1) y1+=30,y2+=30;
		// 画方块
		pDC->SelectObject(&gray);
		pDC->Rectangle(x1,y1,x2,y2);
		clien.SetRect(x1+1,y1+1,x2-1,y2-1);
		if(ncolour==0) pDC->FillSolidRect(clien,RGB(0,0,255));  // blue
		else if(ncolour==1) pDC->FillSolidRect(clien,RGB(0,255,0));  //green
		else if(ncolour==2) pDC->FillSolidRect(clien,RGB(255,0,0));
		else if(ncolour==3) pDC->FillSolidRect(clien,RGB(255,255,0));
		else if(ncolour==4) pDC->FillSolidRect(clien,RGB(0,255,255));
		else if(ncolour==5) pDC->FillSolidRect(clien,RGB(255,0,255));
		// 取得坐标
	}
}
void CtestView::showscore(CDC *pDC)
{
	//CDC *pDC=GetDC();
	LPCTSTR   fontFace=_T("方正舒体");//直接指定字体  
    CFont   font;  
    font.CreatePointFont   (180,fontFace); //110是字体的大小  
	pDC->SelectObject(font);
	pDC->SetTextColor(RGB(255,20,222));
	CString s;
	
	pDC->SetBkMode(TRANSPARENT);
	pDC->TextOutW(260,170,L"分数:");
	s.Format(L"     %d",score);
	pDC->SetTextColor(RGB(100,209,202));
	pDC->TextOutW(260,190,s);
	 fontFace=_T("黑体");//直接指定字体
	font.CreatePointFont   (120,fontFace);
	pDC->SetTextColor(RGB(255,20,22));
	pDC->SelectObject(font);
	pDC->TextOutW(255,240,L"小提示:");
	pDC->TextOutW(260,260,L"  W:  变形;");
	pDC->TextOutW(260,280,L"  A:  左移;");
	pDC->TextOutW(260,300,L"  D:  右移;");
	pDC->TextOutW(260,320,L"Space:  加速;");
	//在此添加游戏的说明

	//ReleaseDC(pDC);
}
void CtestView::mydraw()
{
	int maxl;    // the longest length
	int i,j;
	if(m_nbegin){


	if(first)
	{
		lentd=0;
		lentdn=0;
		// 随机生成方快的 形状与 颜色
		if(start)
		{
			shp=rand()%7;
			loop=rand()%4;
			colour=rand()%6;

			nshp=rand()%7;
			nloop=rand()%4;
			ncolour=rand()%6;
		}
		else
		{
			shp=nshp;
			loop=nloop;
			colour=ncolour;
			nshp=rand()%7;
			nloop=rand()%4;
			ncolour=rand()%6;
		}
		for(j=0;j<16;j++)
		{
			if(shape[nshp][nloop][j]==1)
			{
		// 取得刚生成的方块的最初的坐标 (居中原则)
				next[lentdn][0]=j%4;
				next[lentdn][1]=j/4;
				lentdn++;
			}
		}
		start=false;
		for(j=0;j<16;j++)
		{
			if(shape[shp][loop][j]==1)
			{
		// 取得刚生成的方块的最初的坐标 (居中原则)
				tod[lentd][0]=j%4+7;
				tod[lentd][1]=j/4;	
				if(map[tod[lentd][0]][29-tod[lentd][1]-1]!=-1 || map[tod[lentd][0]][29-tod[lentd][1]]!=-1)
				{
					end=true;
					result();
					return ;
				}
				lentd++;
			}
		}
		circle=true;    // circle 
	}
	first=false;
	int min=30;   // the left one
	int top=0;    // the bottom

	reflash(0);
	bool touch=false;       // 判断有没有 碰到下面的变量

	maxl=0;                 // 现有的最高的行,maxl>30 则结束

	for(i=0;i<lentd;i++)
	{
		// 用 min记录 最左边的正方形的位置
		if(min>tod[i][0]) 	min=tod[i][0]; 

		// 用 top记录 最下边的正方形的位置
		if(top<tod[i][1])   top=tod[i][1];
	}
    top=29-top;
	if(top==0) touch=true;
	else
	{
		for(i=0;i<lentd;i++)
		{
			if(map[tod[i][0]][29-tod[i][1]-1]!=-1)
			{
				touch=true;
				break;
			}
		}
	}
	if(touch) 
	{
		maxl=shape[shp][loop][17];
		for(j=min;j<min+shape[shp][loop][16];j++)   // row
		{
			for(i=top;i<top+maxl;i++)     // first row next colume
			{
				int t=(maxl+top-1-i)*4+j-min;
				if(shape[shp][loop][t]==1) 		
				{
					map[j][i]=colour;
				}			
			}
		}
		// 以下的代码用于消行
		int row[4];
		int lend=0;
		for(i=0;i<30;i++)
		{
			for(j=0;j<=wide;j++)
			{
				if(map[j][i]==-1) break;
			}
			if(j==wide+1) 
			{
				row[lend]=i;
				lend++;
			}
		}
		
		if(lend!=0)
		{
	
			if(lend>=2)
				sndPlaySound(L"fadelayer.wav", SND_ASYNC);
			else
				PlaySound(L"useitem.wav",NULL, SND_ASYNC);
			score+=step[lend];
			for(i=0;i<=wide;i++)
			{
				int t=row[0],s=row[0];
				while(t<30)
				{
					t++;
					bool check=true;
					while(check)
					{
						for(j=0;j<lend;j++)
							if(t==row[j]) break; 
						if(j==lend) check=false;
						else t++;
					}
					map[i][s]=map[i][t];
					s++;
				}
				for(;s<30;s++)
					map[i][s]=-1;
			}
			reflash(1);
		}
		first=true;
	}
	else
	{
		for(i=0;i<lentd;i++)
			tod[i][1]++;
	}

	}
	
}

// CtestView 打印

BOOL CtestView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CtestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CtestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清除过程
}


// CtestView 诊断

#ifdef _DEBUG
void CtestView::AssertValid() const
{
	CView::AssertValid();
}

void CtestView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CtestDoc* CtestView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CtestDoc)));
	return (CtestDoc*)m_pDocument;
}
#endif //_DEBUG


// CtestView 消息处理程序

void CtestView::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	srand((unsigned int) time(NULL));
	mydraw();
	CView::OnTimer(nIDEvent);
	
}
void CtestView::result()
{
	
	if(end)
		KillTimer(1);
	PlaySound(L"lost.wav",NULL,NULL);
	mciSendString(L"close sound", NULL, 0, NULL);
	CDC *pDC=GetDC();
	CBitmap bmp;
	bmp.LoadBitmap(IDB_BITMAP1);
	BITMAP bs;
	bmp.GetBitmap(&bs);
	CDC dc;
	dc.CreateCompatibleDC(pDC);
	CBitmap *pOldBmp = (CBitmap*)dc.SelectObject(&bmp);

	CPen *old=dc.SelectObject(&gray);
	dc.MoveTo(0,455);
	dc.LineTo(242,455);
	dc.LineTo(242,0);
	dc.Rectangle(260,35,350,125);

	LPCTSTR   fontFace=_T("方正舒体");//直接指定字体  
    CFont   font;  
    font.CreatePointFont   (280,fontFace); //110是字体的大小  
	dc.SelectObject(font);
	dc.SetTextColor(RGB(255,20,222));
	CString s;
	s.Format(L"SCORE:  %d",score);
	
	dc.SetBkMode(TRANSPARENT);
	dc.TextOutW(30,170,L"GAME OVER!");
	dc.TextOutW(30,200,s);
	pDC->BitBlt(10, 10, bs.bmWidth, bs.bmHeight, &dc, 0, 0, SRCCOPY);
	
}

void CtestView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	int i;
	int left=wide;
    int right=0;
	int top=0;
	int up=29;
	bool nodown=false;
	for(i=0;i<lentd;i++)
	{
		if(left>tod[i][0])  left=tod[i][0];	
		if(right<tod[i][0]) right=tod[i][0];
		if(top<tod[i][1])   top=tod[i][1];
		if(up>tod[i][1])    up=tod[i][1];
	}
	bool cando=true;
	bool havedone=false;
	switch(nChar)
	{
	case 'A':
		if(left>0)
		{
			for(i=0;i<lentd;i++)
			{
				if(map[tod[i][0]-1][29-tod[i][1]]!=-1) 
				{
					cando=false;
					break;
				}
			}
			if(cando==false) break;
			for(i=0;i<lentd;i++)
				tod[i][0]--;
			havedone=true;
		}
		break;
	case 'D':
		if(right<wide)
		{
			for(i=0;i<lentd;i++)
			{
				if(map[tod[i][0]+1][29-tod[i][1]]!=-1) 
				{
					cando=false;
					break;
				}
			}
			if(cando==false) break;
			for(i=0;i<lentd;i++)
				tod[i][0]++;
			havedone=true;
		}
		break;
	case ' ':
		if(top==29) break;
		else
		{
			for(i=0;i<lentd;i++)
			{
				if(map[tod[i][0]][29-tod[i][1]-1]!=-1) 
				{
					nodown=true;
					break;
				}
			}
			if(nodown==false)
			{
				for(i=0;i<lentd;i++)
					tod[i][1]++;
				havedone=true;
			}
			break;
		}
	case 'W':
		cando=false;
		int docopy[4][2];
		for(i=0;i<lentd;i++)
			docopy[i][0]=tod[i][0],docopy[i][1]=tod[i][1];
		loop=(loop+1)%4;
		lentd=0;
		for(i=0;i<16;i++)
		{
			if(shape[shp][loop][i]==1)
			{
				tod[lentd][0]=i%4+left;
				tod[lentd][1]=i/4+up;
				if(shp==4)
				{
					if(loop%2==1) tod[lentd][0]++,tod[lentd][1]--;
					else tod[lentd][0]--,tod[lentd][1]++;
				}
				if(tod[lentd][0]>wide || map[tod[lentd][0]][29-tod[lentd][1]]!=-1)
				{
					cando=true;
					break;
				}
				lentd++;
			}
		}
		if(!cando) havedone=true;
		else 
		{
			havedone=false;
			lentd=4;
			loop=(loop-1)%7;
			for(i=0;i<4;i++)
				tod[i][0]=docopy[i][0],tod[i][1]=docopy[i][1];
		}

		break;

	}
	if(havedone) 
	{
		PlaySound(L"KEY.WAV",NULL, SND_ASYNC);
		reflash(0);
	}
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CtestView::OnInitialUpdate()
{
	CView::OnInitialUpdate();

	// TODO: 在此添加专用代码和/或调用基类
	end=false;
	CFrameWnd *pFrm = GetTopLevelFrame();
	pFrm->MoveWindow(360,0,400,540,true);
}

void CtestView::OnStart()
{
	// TODO: 在此添加命令处理程序代码
	m_nbegin = true;
	if(end)
	{
		MessageBox(L"请先结束游戏");
		return;
	}

	PlaySound(L"ReadyGo.WAV",NULL,NULL);
	wchar_t buf[256];
	wsprintf(buf, L"open \"%s\" alias sound type waveaudio", L"game.wav");
	MCIERROR err = mciSendString(buf, NULL, 0, NULL);
	if (err) {
		if (mciGetErrorString(err, buf, 256)) MessageBox(buf, L"Error");
		return;
	}
	mciSendString(L"play sound", NULL, 0, NULL);
	SetTimer(1,500,NULL);
}

void CtestView::OnStop()
{
	// TODO: 在此添加命令处理程序代码
	// TODO: 在此添加命令处理程序代码
	CDC *pDC = GetDC();
	int i,j;
	for(i=0;i<=wide;i++)
		for(j=0;j<35;j++)   // from bottom to top
			map[i][j]=-1;
	first=true;
	end=false;
	start=true;
	score=0;
	mciSendString(L"close sound", NULL, 0, NULL);
	gray.CreatePen(PS_SOLID,1,RGB(228,228,228));

	CBitmap bmp;
	bmp.LoadBitmap(IDB_BITMAP1);
	BITMAP bs;
	bmp.GetBitmap(&bs);
	CDC dc;
	dc.CreateCompatibleDC(pDC);
	CBitmap *pOldBmp = (CBitmap*)dc.SelectObject(&bmp);

	CPen *old=dc.SelectObject(&gray);
	dc.MoveTo(0,455);
	dc.LineTo(242,455);
	dc.LineTo(242,0);
	dc.Rectangle(260,35,350,125);
	pDC->BitBlt(10, 10, bs.bmWidth, bs.bmHeight, &dc, 0, 0, SRCCOPY);

	m_nbegin = false;
	ReleaseDC(pDC);

}

void CtestView::OnRestart()
{
	// TODO: 在此添加命令处理程序代码
	SetTimer(1,ss,NULL);
}

void CtestView::OnPause()
{
	// TODO: 在此添加命令处理程序代码
	KillTimer(1);
}

CSet dlg;

void CtestView::OnSet()
{
	// TODO: 在此添加命令处理程序代码
	 CheckDlgButton(IDC_BGM,dlg.a);
	 dlg.DoModal();
	ss=dlg.m_nSpeed;
	ss=ss*90;
	KillTimer(1);
	SetTimer(1,(UINT)ss,NULL);
}

⌨️ 快捷键说明

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