棋类对战小游戏(VS2012 MFC基于对话框)

1需求分析

二打一棋用户需要的功能如下:

1)移动棋子:玩家通过鼠标点击能够实现棋子的移动,同时保证每次只能移动一格,且只能移动到未被占领的格子上。

2)吃掉棋子:同一条线上的己方两个棋子可以吃掉对方的一个棋子,让对方棋子消失。

3)棋子闪烁:点击己方棋子,棋子闪烁,同时保证己方回合内点击对方棋子,对方棋子不闪烁。

4)重新开始:游戏重新开始。

5)黑棋先行:黑棋优先移动。

6)红棋先行:红棋优先移动。

7)退出游戏:退出二打一棋。

2设计思路

2.1总体思路

根据游戏需求,需要利用MFC环境定义一个对话框类,提供程序的初始界面,其中包括重新开始按钮、黑棋先行按钮、红棋先行按钮、退出游戏按钮钮。同时游戏用户对棋盘的相关操作还要通过TVSODlg类来实现。

2.2面向对象技术的应用

项目中主要的类:TVSODlg

TVSODlg类:实现棋盘画面绘制,对棋子进行操作等相关作用。

继承:系统中的对话框基类CDialogEx

成员变量和成员函数如下:

void Hoxiaoyuan(inti,int j) :绘制/红色小圆

void Hexiaoyuan(inti,int j) :绘制黑色小圆

void dayuan(int i,int j):绘制大圆

void youxiao(CPoint q) :确定点击的有效位置

void beijing(CDC* pDC) :绘制棋盘背景

void qizhi() :初始棋子放置

void tiaojian(int i,intj) :棋子消失(胜负)条件判断

int pointvalue[7][6] :点初始值为0,红棋标记为1,黑棋标记为2

CPoint q :保存点信息

int p,n,c,d p=1,黑棋移动,p=2,红棋移动;n=0点未被选定,n=1,点已选定,cd标记选定的点

int pblack,pred :保存红棋和黑棋个数,初始个数均为6

int k :判断棋子是否需要初始化     int i,j

CBitmap beijingtu :插入背景图

afx_msg void OnLButtonDown(UINTnFlags, CPoint point) :鼠标左键点击

afx_msg voidOnTimer(UINT_PTR nIDEvent) :计时器函数

afx_msg void OnBnClickedButton1():重新开始

afx_msg voidOnBnClickedButton2() :黑棋先行

afx_msg voidOnBnClickedButton3() :红棋先行

afx_msg voidOnBnClickedButton4() :退出游戏

3操作步骤

新建基于对话框的MFC应用程序项目TVSO

3.1二打一棋对话框设计

从控件列表中选择按钮控件放于对话框上,修改按钮控件的属性,设计结果如下。

棋类对战小游戏(VS2012 MFC基于对话框)_第1张图片

3.2棋盘绘制

通过调用绘图相关函数画出如下所示棋盘界面:相关函数代码在beijing(pDC)中实现。

棋类对战小游戏(VS2012 MFC基于对话框)_第2张图片

3.3棋子初始化绘制

⑴用二维数组将图中相关点的信息保存POINT pointt[7][6]

⑵通过调用绘图相关函数画出下图所示棋子界面,并对相关点做标记:相关代码在void CTVSODlg ::qizhi()

棋类对战小游戏(VS2012 MFC基于对话框)_第3张图片

3.4鼠标左击

⑴为TVSODlg类添加消息处理函数OnLButtonDown

棋类对战小游戏(VS2012 MFC基于对话框)_第4张图片

OnLButtonDown函数中,需调用以下函数:

youxiao(CPoint q):确定点击的有效位置

dayuan(c,d):绘制大圆

Hexiaoyuan(i,j);:绘制黑色小圆

Hoxiaoyuan(i,j):绘制红色小圆

tiaojian(i,j):胜负条件判断

hongheiqi():右上角红黑棋显示

⑶棋子移动的原理:即是绘制新圆覆盖掉原来的圆,同时修改相关标记。

 

3.5棋子闪烁

⑴为TVSODlg类添加消息处理函数OnTimer

棋类对战小游戏(VS2012 MFC基于对话框)_第5张图片

⑵在绘制棋子函数中添加SetTimer函数。

3.6添加背景图

⑴将.bmp图片文件放置在项目res文件夹下。

⑵在资源视图中导入.bmp格式图片文件。

棋类对战小游戏(VS2012 MFC基于对话框)_第6张图片

⑶为其添加相关函数代码,该函数代码在void CTVSODlg::OnPaint()函数中。

3.7在对话框中显示相关内容。

如果要显示背景、棋子、背景图等,则需要在void CTVSODlg::OnPaint()函数中调用。

4运行效果

棋类对战小游戏(VS2012 MFC基于对话框)_第7张图片

5源码

5.1对话框内容显示

该函数添加在void CTVSODlg::OnPaint()函数的else之中。

CPaintDC dc(this);    

CDC DC;                            //定义并创建一个内存设备环境

DC.CreateCompatibleDC(&dc);//创建兼容性DC 

DC.SelectObject(&beijingtu);//调用函数显示图片

dc.StretchBlt(0,0,800,800,&DC,0,0,800,800,SRCCOPY);

      

CDC *pDC=GetDC();

beijing(pDC);

ReleaseDC(pDC);

qizhi();

             

for(i=0;i<7;i++)//重新绘制

{

       for(j=0;j<6;j++)

       {

              if(pointvalue[i][j]==1)Hoxiaoyuan(i,j);

              elseif(pointvalue[i][j]==2) Hexiaoyuan(i,j);

       }

}

5.2左击鼠标响应相关函数

voidCTVSODlg::OnLButtonDown(UINT nFlags, CPoint point)

{

       i=-1;j=-1;

       q=point;

       youxiao(q);

       if(p==1)//黑棋移动

       {

              if(pointvalue[i][j]==2)

              { c=i;d=j;n=1;}//n=1时,表示选定该点   获取ij的值

              else if(pointvalue[i][j]==0&&n==1)

              {

                     if(abs(i-c)==1&&j==d||abs(j-d)==1&&i==c)//判断能够移动,则执行

                     {

                            pointvalue[c][d]=0;

                            pointvalue[i][j]=2;

                            dayuan(c,d);

                            Hexiaoyuan(i,j); //黑棋时

                            tiaojian(i,j);

                            p=2;n=0;c=-1;d=-1; hongheiqi();

                     }

              }

       }

       else if(p==2)

       {

              if(pointvalue[i][j]==1){c=i;d=j;n=1;}

              else if(pointvalue[i][j]==0&&n==1)

              {

                     if(abs(i-c)==1&&j==d||abs(j-d)==1&&i==c)//判断能够移动,则执行

                     {

                            pointvalue[c][d]=0;

                            pointvalue[i][j]=1;//红棋的值

                            dayuan(c,d);

                            Hoxiaoyuan(i,j);

                            tiaojian(i,j);

                            p=1;n=0;c=-1;d=-1; hongheiqi();

                     }

              }

       }

       CDialogEx::OnLButtonDown(nFlags, point);

}

 

 

5.3绘制圆相关函数

voidCTVSODlg::Hoxiaoyuan(int i,int j)  //绘制红色小圆

{

       CDC *pDC=GetDC();

       CPen redbian(PS_SOLID,3,RGB(255,0,0));

       pDC->SelectObject(redbian);

       CBrush red(RGB(255,0,0));

       pDC->SelectObject(red);

       pDC->Ellipse(pointt[i][j].x-10,pointt[i][j].y-10,pointt[i][j].x+10,pointt[i][j].y+10);

       ReleaseDC(pDC);

}

voidCTVSODlg::Hexiaoyuan(int i,int j)//绘制黑色小圆

{

       CDC *pDC=GetDC();

       CPen redbian(PS_SOLID,3,RGB(0,0,0));

       pDC->SelectObject(redbian);

       CBrush black(RGB(0,0,0));

       pDC->SelectObject(black);

       pDC->Ellipse(pointt[i][j].x-10,pointt[i][j].y-10,pointt[i][j].x+10,pointt[i][j].y+10);

       ReleaseDC(pDC);

}

voidCTVSODlg::dayuan(int i,int j)  //绘制大圆

{

       CDC *pDC=GetDC();

       CPen whitebian(PS_SOLID,1,RGB(255,255,255));

       pDC->SelectObject(whitebian);

       pDC->Ellipse(pointt[i][j].x-20,pointt[i][j].y-20,pointt[i][j].x+20,pointt[i][j].y+20);

       ReleaseDC(pDC);

}

5.4右上角红黑棋显示

voidCTVSODlg::hongheiqi()//右上角红黑棋显示

{

       CDC *pDC=GetDC();

       if(p==1)

       {

              CPen redbian(PS_DASH,3,RGB(0,0,0));

              pDC->SelectObject(redbian);

              CBrush black(RGB(0,0,0));

              pDC->SelectObject(black);

              pDC->Ellipse(350-10,30-10,350+10,30+10);

       }

       else if(p==2)

       {

              CPen redbian(PS_DASH,3,RGB(255,0,0));

              pDC->SelectObject(redbian);

              CBrush red(RGB(255,0,0));

              pDC->SelectObject(red);

              pDC->Ellipse(350-10,30-10,350+10,30+10);

       }

       ReleaseDC(pDC);

}

5.5有效点判断函数

voidCTVSODlg::youxiao(CPoint q)

{

       for(i=1;i<=5;i++)

       {

              for(j=1;j<=4;j++)

              {

if(q.x>=pointt[i][j].x-20&&q.x<=pointt[i][j].x+20&&q.y>=pointt[i][j].y-20&&q.y<=pointt[i][j].y+20)

{m=1;break;}//设置点有效位置

              }

              if(m==1){m=0;break;}

       }

}

5.6棋盘背景绘制函数

voidCTVSODlg::beijing(CDC* pDC)  //背景绘制

{

       for(j=100;j<=500;j=j+100)

       {pDC->MoveTo(100,j); pDC->LineTo(400,j);}

       for(i=100;i<=400;i=i+100)

       {pDC->MoveTo(i,100); pDC->LineTo(i,500);}  

for(i=1;i<6;i++)

       {

for(j=1;j<5;j++)

                     dayuan(i,j);//绘制背景圆

       }

}

 

 

5.7初始棋子绘制函数

void CTVSODlg::qizhi()//初始棋子绘制

{

       SetTimer(1,1000,NULL);

       if(k==0)

       {

              for(i=0;i<7;i++)    //点初始值为0,红棋标记为1,黑棋标记为2

              {for(j=0;j<6;j++)  pointvalue[i][j]=0;}

              //初始化棋盘(红棋)

              for(j=1;j<=4;j++){Hoxiaoyuan(1,j);pointvalue[1][j]=1;}

              Hoxiaoyuan(2,1); pointvalue[2][1]=1;

              Hoxiaoyuan(2,4); pointvalue[2][4]=1;

              //初始化棋盘(黑棋)

for(j=1;j<=4;j++){Hexiaoyuan(5,j);pointvalue[5][j]=2;}

              Hexiaoyuan(4,1); pointvalue[4][1]=2;

              Hexiaoyuan(4,4); pointvalue[4][4]=2;

              k=1;

       }

}

5.8棋子消失及胜负判断函数

voidCTVSODlg::tiaojian(int i,int j)//棋子消失(胜负)条件判断

{

       if(pointvalue[i][j]==2) //黑棋时

       {

              if(pointvalue[i-1][j]==2)//

              {

                     if(pointvalue[i+1][j]==1&&pointvalue[i+2][j]!=1)

                     {

                            pointvalue[i+1][j]=0;

                            dayuan(i+1,j);

                            pred--;

                     }

                     if(pointvalue[i-2][j]==1&&pointvalue[i-3][j]!=1)

                     {

                            pointvalue[i-2][j]=0;

                            dayuan(i-2,j);

                            pred--;

                     }

              }

              if(pointvalue[i+1][j]==2)//

              {

                     if(pointvalue[i-1][j]==1&&pointvalue[i-2][j]!=1)

                     {

                            pointvalue[i-1][j]=0;

                            dayuan(i-1,j);

                            pred--;

                     }

                     if(pointvalue[i+2][j]==1&&pointvalue[i+3][j]!=1)

                     {

                            pointvalue[i+2][j]=0;

                            dayuan(i+2,j);

                            pred--;

                     }

              }

              if(pointvalue[i][j-1]==2)//

              {

                     if(pointvalue[i][j+1]==1&&pointvalue[i][j+2]!=1)

                     {

                            pointvalue[i][j+1]=0;

                            dayuan(i,j+1);

                            pred--;

                     }

                     if(pointvalue[i][j-2]==1&&pointvalue[i][j-3]!=1)

                     {

                            pointvalue[i][j-2]=0;

                            dayuan(i,j-2);

                            pred--;

                     }

              }

              if(pointvalue[i][j+1]==2)//

              {

                     if(pointvalue[i][j-1]==1&&pointvalue[i][j-2]!=1)

                     {

                            pointvalue[i][j-1]=0;

                            dayuan(i,j-1);

                            pred--;

                     }

                     if(pointvalue[i][j+2]==1&&pointvalue[i][j+3]!=1)

                     {

                            pointvalue[i][j+2]=0;

                            dayuan(i,j+2);

                            pred--;

                     }

              }

              if(pred==0) AfxMessageBox("黑旗获胜");

       }

       else if(pointvalue[i][j]==1)//红棋时

       {

              if(pointvalue[i-1][j]==1)//

              {

                     if(pointvalue[i+1][j]==2&&pointvalue[i+2][j]!=2)

                     {

                            pointvalue[i+1][j]=0;

                            dayuan(i+1,j);

                            pblack--;

                     }

                     if(pointvalue[i-2][j]==2&&pointvalue[i-3][j]!=2)

                     {

                            pointvalue[i-2][j]=0;

                            dayuan(i-2,j);

                            pblack--;

                     }

              }

              if(pointvalue[i+1][j]==1)//

              {

                     if(pointvalue[i-1][j]==2&&pointvalue[i-2][j]!=2)

                     {

                            pointvalue[i-1][j]=0;

                            dayuan(i-1,j);

                            pblack--;

                     }

                     if(pointvalue[i+2][j]==2&&pointvalue[i+3][j]!=2)

                     {

                            pointvalue[i+2][j]=0;

                            dayuan(i+2,j);

                            pblack--;

                     }

              }

              if(pointvalue[i][j-1]==1)//

              {

                     if(pointvalue[i][j+1]==2&&pointvalue[i][j+2]!=2)

                     {

                            pointvalue[i][j+1]=0;

                            dayuan(i,j+1);

                            pblack--;

                     }

                     if(pointvalue[i][j-2]==2&&pointvalue[i][j-3]!=2)

                     {

                            pointvalue[i][j-2]=0;

                            dayuan(i,j-2);

                            pblack--;

                     }

              }

              if(pointvalue[i][j+1]==1)//

              {

                     if(pointvalue[i][j-1]==2&&pointvalue[i][j-2]!=2)

                     {

                            pointvalue[i][j-1]=0;

                            dayuan(i,j-1);

                            pblack--;

                     }

                     if(pointvalue[i][j+2]==2&&pointvalue[i][j+3]!=2)

                     {

                            pointvalue[i][j+2]=0;

                            dayuan(i,j+2);

                            pblack--;

                     }

              }

              if(pblack==0) AfxMessageBox("红旗获胜");

       }

}

5.9计时器函数

voidCTVSODlg::OnTimer(UINT_PTR nIDEvent)

{

       if(pointvalue[i][j]==2&&p==1)

       {

              dayuan(i,j);

              Hexiaoyuan(i,j);

       }

       else if(pointvalue[i][j]==1&&p==2)

       {

              dayuan(i,j);

              Hoxiaoyuan(i,j);

       }

       CDialogEx::OnTimer(nIDEvent);

}

5.10重新开始按钮

voidCTVSODlg::OnBnClickedButton1()

{

       p=1;n=0;

       pblack=6;pred=6;

       k=0;

       OnPaint();

}

5.11黑棋先行按钮

voidCTVSODlg::OnBnClickedButton2()

{

       OnBnClickedButton1();

}

5.12红棋先行按钮

voidCTVSODlg::OnBnClickedButton3()

{

       OnBnClickedButton1();

       p=2;

}

5.13退出游戏按钮

voidCTVSODlg::OnBnClickedButton4()

{

       CTVSODlg::OnCancel();

}



你可能感兴趣的:(编程历程,C/C++)