📄 fangkuaidlg.cpp
字号:
// fangkuaiDlg.cpp : implementation file
//
#include "stdafx.h"
#include "fangkuai.h"
#include "fangkuaiDlg.h"
UINT nChar;
int n=0;//记录分数,即消的行数
int Number[2];//随机的数据用于获取方块
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CFangkuaiDlg dialog
CFangkuaiDlg::CFangkuaiDlg(CWnd* pParent /*=NULL*/)
: CDialog(CFangkuaiDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CFangkuaiDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CFangkuaiDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFangkuaiDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFangkuaiDlg, CDialog)
//{{AFX_MSG_MAP(CFangkuaiDlg)
ON_BN_CLICKED(IDC_GameOver, OnGameOver)
ON_BN_CLICKED(IDC_GameStart, OnGameStart)
ON_BN_CLICKED(IDC_UP, OnUp)
ON_BN_CLICKED(IDC_DOWN, OnDown)
ON_BN_CLICKED(IDC_LEFT, OnLeft)
ON_BN_CLICKED(IDC_RIGHT, OnRight)
ON_BN_CLICKED(IDC_PAUSE, OnPause)
ON_WM_TIMER()
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_STATIC_NUM, OnStaticNum)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFangkuaiDlg message handlers
BOOL CFangkuaiDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// TODO: Add extra initialization here
CRect rt;
GetClientRect(&rt);
WIDTHOFBRICKS=((rt.right-rt.left)-LEFTMARGIN)/10;
HEIGHTOFBRICKS=((rt.bottom-rt.top)-TOPMARGIN-::GetSystemMetrics(SM_CYCAPTION))/20;
WIDTHOFBRICKS=HEIGHTOFBRICKS=min(WIDTHOFBRICKS,HEIGHTOFBRICKS);
// TRACE(L"HEIGHTOFBRICKS:%d\n",HEIGHTOFBRICKS);
BrickAtBottom=FALSE;
EraseALine=FALSE;
Level=0;
TimerInterval=5000/20;
GameState=STOP;
InitBricks();
RefreshAll();
return TRUE; // return TRUE unless you set the focus to a control
}
void CFangkuaiDlg::OnKey(UINT nChar)
{
{
switch(nChar)
{
case VK_NUMPAD1://左方向
if(!(IsOutOfRect(1)==2))
{
RefreshBricks();
for(int a=0;a<4;a++)//a为循环用变量
CurrentBrick[a].y--;//Y表示的是横向坐标,左起为0,向左移动Y减小
}
break;
case VK_NUMPAD3://右方向
if(!(IsOutOfRect(2)==1))
{
RefreshBricks();
for(int a=0;a<4;a++)
CurrentBrick[a].y++;//右移动Y增加
}
break;
case VK_NUMPAD7://下落
OnTimer(1);
break;
case VK_NUMPAD9://旋转
RefreshBricks();
RotateBrick();
break;
}
myDraw();
}
}
void CFangkuaiDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
switch(nIDEvent)
{
case 1:
if(GameState==RUNNING)
{
if(Isbottom())//如果未到底
{
RefreshBricks();//刷新
for(int i=0;i<4;i++)
CurrentBrick[i].x++;//方块下降X增加
}
else //如果到底了
{
IsGameOver();
CanEraseALine();//消去一行
DrawNextBrick();//绘制下一个方块以提示
GenerateABrick();//生成新的方块
Number[0]=Number[1];
CreateNumber();//获取随机的数据
}
myDraw();
}
break;
}
CDialog::OnTimer(nIDEvent);
}
void CFangkuaiDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
dc.FillSolidRect(180,50,100,60,RGB(0,0,255));
EraseALine=TRUE;
myDraw();
// Do not call CDialog::OnPaint() for painting messages
}
//////////////以下为自定义函数////////////////////////
void CFangkuaiDlg::InitBricks()
{
for(int i=0;i<20;i++)
for(int j=0;j<10;j++)
MatrixOfBricks[i][j]=0;
RefreshAll();
}
// 刷新方块区域,已看懂
void CFangkuaiDlg::RefreshBricks(void)
{
int i;
for(i=0;i<4;i++)
{
MatrixOfBricks[CurrentBrick[i].x][CurrentBrick[i].y]=0;//消去原先的方块
LastPositionOfBrick[i].x=CurrentBrick[i].x;//记录原先位置
LastPositionOfBrick[i].y=CurrentBrick[i].y;
}
}
//旋转,已看懂
void CFangkuaiDlg::RotateBrick()
{
int i,j;//循环变量
int IndexOfCenter=0;//旋转轴的方块序号
Brick CenterBrick;//用于存放中间方块的位置
Brick TempBrick[4];//用于存放当前方块的位置,一旦旋转后出界,则用此恢复
CenterBrick.y=0;
CenterBrick.x=0;
if(CurrentBrick[4].x==0) return;
for(i=0;i<4;i++)
{
TempBrick[i].x=CurrentBrick[i].x;
TempBrick[i].y=CurrentBrick[i].y;
}
if((CurrentBrick[0].x==CurrentBrick[1].x==CurrentBrick[2].x==CurrentBrick[3].x)
||(CurrentBrick[0].y==CurrentBrick[1].y==CurrentBrick[2].y==CurrentBrick[3].y))
{//如果是长棒,则以第二块为轴心,否则以第一块为轴心
CenterBrick.x=CurrentBrick[2].x;
CenterBrick.y=CurrentBrick[2].y;
IndexOfCenter=2;
}
else
{
CenterBrick.x=CurrentBrick[1].x;
CenterBrick.y=CurrentBrick[1].y;
IndexOfCenter=1;
}
for(i=0;i<4;i++)
{
if(i!=IndexOfCenter)
{//逆时针旋转
CurrentBrick[i].x=TempBrick[i].y-CenterBrick.y+CenterBrick.x;
CurrentBrick[i].y=CenterBrick.x-TempBrick[i].x+CenterBrick.y;
if((MatrixOfBricks[CurrentBrick[i].x][CurrentBrick[i].y]==2)||//如果碰底
(CurrentBrick[i].y>9)||//如果右出界
(CurrentBrick[i].y<0)||//如果左出界
(CurrentBrick[i].x>19)||//如果下出界
(CurrentBrick[i].x<0))//如果上出界
{//如果已出界,则不能旋转,用备份方块还原
for(j=0;j<4;j++)
{
CurrentBrick[j].x=TempBrick[j].x;
CurrentBrick[j].y=TempBrick[j].y;
}
break;
}
}
}
}
//是否出界,已看懂
int CFangkuaiDlg::IsOutOfRect(int w)
{
if(w==2)//右移
{
for(int a=0;a<4;a++)
{
if((CurrentBrick[a].y>=9)//如果即将右移出界或碰到已有方块
||(MatrixOfBricks[CurrentBrick[a].x][CurrentBrick[a].y+1]==2))
{
return 1;//表示已到右边界
}
}
}
if(w==1)//左移
{
for(int a=0;a<4;a++)
if((CurrentBrick[a].y<=0)//如果即将左移出界或碰到已有方块
||(MatrixOfBricks[CurrentBrick[a].x][CurrentBrick[a].y-1]==2))
return 2;//表示已到左边界
}
return 3;//未到边界
}
//判断是否到底,已看懂
int CFangkuaiDlg::Isbottom()
{
BrickAtBottom=TRUE;
for(int a=0;a<4;a++)
{
if(CurrentBrick[a].x==19)//如果当前方块已经到了最底端,X是纵向的坐标
{
for(int c=0;c<4;c++)
MatrixOfBricks[CurrentBrick[c].x][CurrentBrick[c].y]=2;//2表示不再自由下落
return 0;//到底了
}
if(MatrixOfBricks[CurrentBrick[a].x+1][CurrentBrick[a].y]==2)//如果当前方块碰到了别的方块
{
for(int c=0;c<4;c++)
MatrixOfBricks[CurrentBrick[c].x][CurrentBrick[c].y]=2;//2表示不再自由下落
return 0;//到底了
}
}
BrickAtBottom=FALSE;
return 1;
}
//消行,判断是否游戏结束,已看懂
void CFangkuaiDlg::CanEraseALine()
{
int flagover=0;
//int i=1; //用于对等级进行判断
TCHAR m_strValue[200];
for(int a=19;a>=0;a--)
{
flagover=0;
/////////////////////////////////
/////判断是否有一行可消去////////
/////////////////////////////////
for(int b=0;b<10;b++)
{
if(MatrixOfBricks[a][b]==2)
{
flagover++;
}
}
//////如果可消去////////////////
if(flagover==10)
{
EraseALine=TRUE;
for(int t=a;t>0;t--)//方块下移
{
for(b=0;b<10;b++)
{
MatrixOfBricks[t][b]=MatrixOfBricks[t-1][b];//标识移位
MatrixOfBricks[t-1][b]=0;//本位置置空
}
}
n++;//如果可以消一行,则n值增加1
a=a+1;//重新判断这一行
}
}
switch (n)
{
case 5:
Level=1;
break;
case 10:
Level=2;
break;
case 15:
Level=3;
break;
case 20:
Level=4;
break;
case 25:
Level=5;
break;
case 30:
Level=6;
break;
case 35:
Level=7;
break;
case 40:
Level=8;
break;
case 45:
Level=9;
break;
} //对等级进行计数判断
TimerInterval=5000/20-Level*25;//重新设定时间间隔以适合不同等级
SetTimer(1,TimerInterval,NULL); //重新定义记时器
_itow(n*100,m_strValue,10 );
SetDlgItemText(IDC_STATIC_NUM,m_strValue);//显示分数
_itow(CFangkuaiDlg::Level,m_strValue,10 );
SetDlgItemText(IDC_LEVEL,m_strValue);//显示等级数
//////////////////////////////
/////////判断结束/////////////
//////////////////////////////
}
void CFangkuaiDlg::IsGameOver()
{
int a;
for(a=0;a<9;a++)
{
if(MatrixOfBricks[0][a]==2)//如果任一列到顶
{
GameState=STOP;
KillTimer(1);//停计时器
MessageBox(_T("Game Over!"));
InitBricks();
myDraw();
return;
}
}
}
//初始化,已看懂
void CFangkuaiDlg::CreateNumber()
{
Number[1]=rand()%7;
}
void CFangkuaiDlg::GenerateABrick()
{
switch (Number[0])
{
case 1://-----//
CurrentBrick[0].x=0;
CurrentBrick[0].y=4;
CurrentBrick[1].x=0;
CurrentBrick[1].y=5;
CurrentBrick[2].x=0;
CurrentBrick[2].y=3;
CurrentBrick[3].x=0;
CurrentBrick[3].y=2;
CurrentBrick[4].x=1;
break;
case 2:
CurrentBrick[0].x=0;
CurrentBrick[0].y=4;
CurrentBrick[1].x=0;
CurrentBrick[1].y=5;
CurrentBrick[2].x=1;
CurrentBrick[2].y=5;
CurrentBrick[3].x=1;
CurrentBrick[3].y=6;
CurrentBrick[4].x=2;
break;
case 3:
CurrentBrick[0].x=1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -