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

📄 tericsview.cpp

📁 俄罗斯方块游戏
💻 CPP
字号:
// TericsView.cpp : implementation of the CTericsView class
//

#include "stdafx.h"
#include "Terics.h"
#include "iostream.h"
#include "TericsDoc.h"
#include "TericsView.h"
#include <mmsystem.h>
#include "TSocket.h"
#pragma comment(lib,"WINMM.LIB")

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

/////////////////////////////////////////////////////////////////////////////
// CTericsView

IMPLEMENT_DYNCREATE(CTericsView, CView)

BEGIN_MESSAGE_MAP(CTericsView, CView)
	//{{AFX_MSG_MAP(CTericsView)
	ON_WM_TIMER()
	ON_COMMAND(ID_NEW, OnNew)
	ON_COMMAND(ID_LEVEL1, OnLevel1)
	ON_COMMAND(ID_LEVEL2, OnLevel2)
	ON_COMMAND(ID_LEVEL3, OnLevel3)
	ON_WM_KEYDOWN()
	ON_COMMAND(ID_STOP, OnStop)
	ON_UPDATE_COMMAND_UI(ID_LEVEL1, OnUpdateLevel1)
	ON_UPDATE_COMMAND_UI(ID_LEVEL2, OnUpdateLevel2)
	ON_UPDATE_COMMAND_UI(ID_LEVEL3, OnUpdateLevel3)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTericsView construction/destruction

CTericsView::CTericsView()
{
	// TODO: add construction code here
	
}

CTericsView::~CTericsView()
{
}

BOOL CTericsView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	srand((unsigned)time(NULL)); 
	for(int i=0;i<12;i++)
		for(int j=0;j<20;j++)
			canvas[i][j]=0;
	m_level=5;
	PreStyle=0;
	bitmap[0].LoadBitmap(IDB_RED);
	bitmap[1].LoadBitmap(IDB_BLUE);
	bitmap[2].LoadBitmap(IDB_BLUE2);
	bitmap[3].LoadBitmap(IDB_PURPLE);
	bitmap[4].LoadBitmap(IDB_GREEN);
	bitmap[5].LoadBitmap(IDB_GREEN2);
	bitmap[6].LoadBitmap(IDB_YELLOW);
	bitmap[7].LoadBitmap(IDB_GRAY);
	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CTericsView drawing

void CTericsView::OnDraw(CDC* pDC)
{
	CTericsDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	
	CPen penNew(PS_SOLID,1,RGB(0,0,0)),*ppenOld;
	ppenOld=pDC->SelectObject(&penNew);
	pDC->MoveTo(39,39);
	pDC->LineTo(40+12*16,39);
	pDC->LineTo(40+16*12,40+16*20);
	pDC->LineTo(39,40+16*20);
	pDC->LineTo(39,39);

	int i,j;
	CDC dcMemory;
	dcMemory.CreateCompatibleDC(pDC);

	for(i=0;i<12;i++)
		for(j=0;j<20;j++)
		{
			if(canvas[i][j])
			{

					dcMemory.SelectObject(&bitmap[canvas[i][j]-1]);
					pDC->BitBlt(i*16+40,j*16+40,16,16,&dcMemory,0,0,SRCCOPY);

			}
			else
			{
				CRect rcBlock;
				rcBlock.SetRect(i*16+40,j*16+40,i*16+40+16,j*16+40+16);
				pDC->FillSolidRect(&rcBlock,RGB(255,255,255));
			}
			
		}
	dcMemory.DeleteDC();
	
	DrawPreBlock();

	

}

/////////////////////////////////////////////////////////////////////////////
// CTericsView diagnostics

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

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

CTericsDoc* CTericsView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTericsDoc)));
	return (CTericsDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTericsView message handlers

void CTericsView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(!down())
	{
		remove();
		NewBlock();
	}

}

void CTericsView::OnNew() 
{
	// TODO: Add your command handler code here
	for(int i=0;i<12;i++)
		for(int j=0;j<20;j++)
			canvas[i][j]=0;
		score=0;
	KillTimer(1);
	SetTimer(1,m_level*200,0);
	PreBlock();
	NewBlock();
	DrawAll();
	PlaySound(MAKEINTRESOURCE(IDR_READYGO),AfxGetApp()->m_hInstance,SND_RESOURCE|SND_ASYNC);
}


void CTericsView::OnLevel1() 
{
	// TODO: Add your command handler code here

	m_level=5;

}

void CTericsView::OnLevel2() 
{
	// TODO: Add your command handler code here

	m_level=3;
}

void CTericsView::OnLevel3() 
{
	// TODO: Add your command handler code here

	m_level=1;
}


void CTericsView::PreBlock()
{
	int i;
	i=rand()%7;
	PreStyle=i+1;
	switch(i)
	{
	case 0:
		PrePosi[0].x=5;
		PrePosi[1].x=5;
		PrePosi[2].x=5;
     	PrePosi[3].x=5;
		PrePosi[0].y=1;
		PrePosi[1].y=0;
		PrePosi[2].y=2;
     	PrePosi[3].y=3;
		break;
	case 1:
		PrePosi[0].x=5;
		PrePosi[1].x=5;
		PrePosi[2].x=6;
     	PrePosi[3].x=5;
		PrePosi[0].y=1;
		PrePosi[1].y=0;
		PrePosi[2].y=0;
     	PrePosi[3].y=2;
		break;
	case 2:
		PrePosi[0].x=6;
		PrePosi[1].x=5;
		PrePosi[2].x=6;
     	PrePosi[3].x=6;
		PrePosi[0].y=1;
		PrePosi[1].y=0;
		PrePosi[2].y=0;
     	PrePosi[3].y=2;
		break;
	case 3:
		PrePosi[0].x=5;
		PrePosi[1].x=5;
		PrePosi[2].x=6;
     	PrePosi[3].x=5;
		PrePosi[0].y=1;
		PrePosi[1].y=0;
		PrePosi[2].y=1;
     	PrePosi[3].y=2;
		break;
	case 4:
		PrePosi[0].x=5;
		PrePosi[1].x=5;
		PrePosi[2].x=6;
     	PrePosi[3].x=6;
		PrePosi[0].y=1;
		PrePosi[1].y=0;
		PrePosi[2].y=1;
     	PrePosi[3].y=2;
		break;
	case 5:
		PrePosi[0].x=5;
		PrePosi[1].x=6;
		PrePosi[2].x=6;
     	PrePosi[3].x=5;
		PrePosi[0].y=1;
		PrePosi[1].y=0;
		PrePosi[2].y=1;
     	PrePosi[3].y=2;
		break;
	case 6:
		PrePosi[0].x=5;
		PrePosi[1].x=5;
		PrePosi[2].x=6;
     	PrePosi[3].x=6;
		PrePosi[0].y=1;
		PrePosi[1].y=0;
		PrePosi[2].y=0;
     	PrePosi[3].y=1;
		break;
	}
	DrawPreBlock();
}

void CTericsView::NewBlock()
{

	for(int i=0;i<4;i++)
		posi[i]=PrePosi[i];
	style=PreStyle;
	PreBlock();
	if(IsOver())
	{

		KillTimer(1);
		for(i=0;i<4;i++)
			canvas[posi[i].x][posi[i].y]=style;
		
		DrawAll();
		PlaySound(MAKEINTRESOURCE(IDR_LOST),AfxGetApp()->m_hInstance,SND_RESOURCE|SND_ASYNC);
		MessageBox("游戏结束!","俄罗斯",MB_OK);
	}
	for(i=0;i<4;i++)
		canvas[posi[i].x][posi[i].y]=style;
	DrawCurrent(false);	

}



bool CTericsView::IsOver()
{
	int i;
	for(i=0;i<4;i++)
	{
		if(canvas[posi[i].x][posi[i].y]!=0)
			return true;
	}
	return false;
}



void CTericsView::remove()
{
	bool flag,flag2;
	
	flag2=false;
	for(int i=0;i<20;i++)
	{

			flag=true;
			for(int j=0;j<12;j++)
				if(canvas[j][i]==0)
				{
					flag=false;
					break;
				}
			if(flag==true)
			{
				flag2=true;
				for(int k=i;k>0;k--)
					for(int l=0;l<12;l++)
						canvas[l][k]=canvas[l][k-1];
					score+=100;
					
			}
		
	}

		


	DrawAll();
	if(flag2)
		PlaySound(MAKEINTRESOURCE(IDR_FADELAYER),AfxGetApp()->m_hInstance,SND_RESOURCE|SND_ASYNC);

}

bool CTericsView::down()
{
	int i,j;
	for(i=0;i<4;i++)//下一位置
	{
		canvas[posi[i].x][posi[i].y]=0;
		posi[i].y++;
	}
	for(i=0;i<4;i++)// 可以down??
	{
		if(posi[i].y>=20||canvas[posi[i].x][posi[i].y]!=0)
		{
			for(j=0;j<4;j++)
			{
				posi[j].y--;
				canvas[posi[j].x][posi[j].y]=style;
			}
			return false;
		}
	}


	for(i=0;i<4;i++)
	{
		canvas[posi[i].x][posi[i].y]=style;
		DrawOne(posi[i].x,posi[i].y-1,true);
	}
	DrawCurrent(false);


	return true;

}






void CTericsView::rotate()
{
	int i,j;
	position NewPosi[4];
	if(style!=7)
		for(i=0;i<4;i++)
			canvas[posi[i].x][posi[i].y]=0;//移除原方块
	switch(style)//计算下一位置
	{
	case 1:
		if(posi[1].y==posi[0].y)
		{
			NewPosi[0].x=posi[0].x;
			NewPosi[1].x=posi[0].x;
			NewPosi[2].x=posi[0].x;
			NewPosi[3].x=posi[0].x;
			NewPosi[0].y=posi[0].y;
			NewPosi[1].y=posi[0].y+1;
			NewPosi[2].y=posi[0].y-1;
			NewPosi[3].y=posi[0].y-2;
		}
		else
		{
			NewPosi[0].x=posi[0].x;
			NewPosi[1].x=posi[0].x-1;
			NewPosi[2].x=posi[0].x+1;
			NewPosi[3].x=posi[0].x+2;
			NewPosi[0].y=posi[0].y;
			NewPosi[1].y=posi[0].y;
			NewPosi[2].y=posi[0].y;
			NewPosi[3].y=posi[0].y;
		}
		for(i=1;i<4;i++)//判断可否移动,不行则恢复方块
			if(NewPosi[i].x<0||NewPosi[i].x>=12||NewPosi[i].y<0||NewPosi[i].y>=20||canvas[NewPosi[i].x][NewPosi[i].y]!=0)
			{
				for(j=0;j<4;j++)
					canvas[posi[i].x][posi[i].y]=style;
				return;
			}
		break;
	case 2:
	case 3:
	case 4:
	case 5:
	case 6://计算下一位置
		NewPosi[0].y=posi[0].y;
		NewPosi[0].x=posi[0].x;
		for(i=1;i<4;i++)
		{
			NewPosi[i].x=posi[0].x+posi[0].y-posi[i].y;
			NewPosi[i].y=posi[0].y+posi[i].x-posi[0].x;
		}
		for(i=1;i<4;i++)//判断可否移动,不行则恢复方块
			if(NewPosi[i].x<0||NewPosi[i].x>=12||NewPosi[i].y<0||NewPosi[i].y>=20||canvas[NewPosi[i].x][NewPosi[i].y]!=0)
			{
				for(j=0;j<4;j++)
					canvas[posi[i].x][posi[i].y]=style;
				return;
			}
		break;
	case 7:
		return;
	}
	for(i=0;i<4;i++)
	{
		DrawOne(posi[i].x,posi[i].y,true);
		posi[i]=NewPosi[i];
		canvas[posi[i].x][posi[i].y]=style;
	}
	DrawCurrent(false);
	PlaySound(MAKEINTRESOURCE(IDR_ROTATE),AfxGetApp()->m_hInstance,SND_RESOURCE|SND_ASYNC);

}

void CTericsView::left()
{
	int i,j;
	for(i=0;i<4;i++)//左一位置
	{
		canvas[posi[i].x][posi[i].y]=0;
		posi[i].x--;
	}
	for(i=0;i<4;i++)// 可以left??
	{
		if(posi[i].x>=12||posi[i].x<0)
		{
			for(j=0;j<4;j++)
			{
				posi[j].x++;
				canvas[posi[j].x][posi[j].y]=style;
			}
			return;
		}
		if(canvas[posi[i].x][posi[i].y]!=0)
		{
			for(j=0;j<4;j++)
			{
				posi[j].x++;
				canvas[posi[j].x][posi[j].y]=style;
			}
			return;
		}
	}


	for(i=0;i<4;i++)
	{
		canvas[posi[i].x][posi[i].y]=style;
		DrawOne(posi[i].x+1,posi[i].y,true);
	}
	DrawCurrent(false);
	
}

void CTericsView::right()
{
	int i,j;
	for(i=0;i<4;i++)//右一位置
	{
		canvas[posi[i].x][posi[i].y]=0;
		posi[i].x++;
	}
	for(i=0;i<4;i++)// 可以right??
	{
		if(posi[i].x>=12||posi[i].x<0)
		{
			for(j=0;j<4;j++)
			{
				posi[j].x--;
				canvas[posi[j].x][posi[j].y]=style;
			}
			return;
		}
		if(canvas[posi[i].x][posi[i].y]!=0)
		{
			for(j=0;j<4;j++)
			{
				posi[j].x--;
				canvas[posi[j].x][posi[j].y]=style;
			}
			return;
		}
	}


	for(i=0;i<4;i++)
	{
		canvas[posi[i].x][posi[i].y]=style;
		DrawOne(posi[i].x-1,posi[i].y,true);
	}
	DrawCurrent(false);

}


void CTericsView::FlashDown()
{
	while(down())
	{}
	PlaySound(MAKEINTRESOURCE(IDR_FLASHDOWN),AfxGetApp()->m_hInstance,SND_RESOURCE|SND_ASYNC);
	remove();
	NewBlock();

}



void CTericsView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	switch(nChar)
	{
	case VK_UP:
		rotate();
		break;
	case VK_LEFT:
		left();
		break;
	case VK_RIGHT:
		right();
		break;
	case VK_DOWN:
		down();
		break;
	case VK_SPACE:
		FlashDown();
		break;
	}



}

void CTericsView::OnStop() 
{
	// TODO: Add your command handler code here
	KillTimer(1);
}

void CTericsView::DrawOne(int x,int y,bool erase)
{
	CDC *pDC;
	pDC=GetDC();
	CDC  memDC;
	CRect  rcBlock;
	if(erase)//擦除
	{
		rcBlock.SetRect(x*16+40,y*16+40,x*16+40+16,y*16+40+16);
		pDC->FillSolidRect(&rcBlock,RGB(255,255,255));
	}
	else
	{
		memDC.CreateCompatibleDC(pDC);
		memDC.SelectObject(bitmap[style-1]);
		pDC->BitBlt(x*16+40,y*16+40,16,16,&memDC,0,0,SRCCOPY);
		memDC.DeleteDC();
	}
	pDC->DeleteDC();

}

void CTericsView::DrawCurrent(bool erase)
{
	int i;

	for(i=0;i<4;i++)
		DrawOne(posi[i].x,posi[i].y,erase);

}

void CTericsView::DrawAll()
{
	int i,j;
	CDC *pDC;
	pDC=GetDC();
	CString sStr;
	sStr.Format("%d",score);
	pDC->TextOut(10,10,sStr);
	CDC dcMemory;
	dcMemory.CreateCompatibleDC(pDC);
	for(i=0;i<12;i++)
	for(j=0;j<20;j++)
	{
		if(canvas[i][j])
		{

				dcMemory.SelectObject(&bitmap[canvas[i][j]-1]);
				pDC->BitBlt(i*16+40,j*16+40,16,16,&dcMemory,0,0,SRCCOPY);

		}
		else
		{
			CRect rcBlock;
			rcBlock.SetRect(i*16+40,j*16+40,i*16+40+16,j*16+40+16);
			pDC->FillSolidRect(&rcBlock,RGB(255,255,255));
		}
			
	}
	dcMemory.DeleteDC();


}


void CTericsView::DrawPreBlock()
{
	if(PreStyle)
	{
		CDC *pDC;
		pDC=GetDC();
		CDC  memDC;
		CRect  rcBlock;
		rcBlock.SetRect(250,40,2*16+250,4*16+40);
		pDC->FillSolidRect(&rcBlock,RGB(255,255,255));


		memDC.CreateCompatibleDC(pDC);
		memDC.SelectObject(bitmap[PreStyle-1]);
		for(int i=0;i<4;i++)
		{
			pDC->BitBlt((PrePosi[i].x-5)*16+250,PrePosi[i].y*16+40,16,16,&memDC,0,0,SRCCOPY);
		}
		memDC.DeleteDC();
		pDC->DeleteDC();
	}
}

void CTericsView::OnUpdateLevel1(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_level==5 ? 1:0);
}

void CTericsView::OnUpdateLevel2(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_level==3 ? 1:0);
}

void CTericsView::OnUpdateLevel3(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_level==1 ? 1:0);
}

⌨️ 快捷键说明

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