利用VC制作单机版五子棋游戏

 

利用VC制作单机版五子棋游戏

计算机语言类 2009-11-25 22:08:12 阅读134 评论2  字号: 订阅

1, 制作用户登录框

比如有两个用户,张三和李四

定义两个全局变量

CString nameblack;//保存黑子玩家的名字

CString namewhite;//保存白子玩家的名字

GetDlgItemText(IDC_EDIT1,nameblack);

GetDlgItemText(IDC_EDIT2,namewhite);

为了让这个登录框先运行

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

return -1后面加一个

Clogin login;    //Clogin为对话框的类名

login.DoModal();

这时,就会先运行这个对话框的东西

2, 在CMainFrame::PreCreateWindow(CREATESTRUCT& cs)函数中设置单文档的高度和宽度,还有起点

cs.x=100;

cs.y=0;

cs.cx=850;//界面的宽度

cs.cy=700;//界面的高度

cs.hMenu=0;

3, 设置界面的标题

Doc类中设置

BOOL CGobangDoc::OnNewDocument()

加一句

SetTitle("张靖");

4, 导入背景图片

bitmap资源里导入资源图片。

给背景图片取好ID

譬如说ID号是IDB_Chessboard

然后在view类中定义成员变量

CBitmap m_chessboard;

CDC Chessboard;

然后在view类中的OnDraw函数中

m_chessboard.LoadBitmap(IDB_Chessboard);

Chessboard.CreateCompatibleDC(pDC);

Chessboard.SelectObject(m_chessboard);

pDC->BitBlt(0,0,850,600,&Chessboard,0,0,SRCCOPY);(8个参数)

这样就把背景图片画出来了

5,用同样的方法把开始按钮,退出按钮,悔棋按钮,重新开始按钮,黑子,白子。并用

pDC->BitBlt()这个函数把这些bitmap图片放到适当的位置

贴图的时候注意,把先贴最大的图片,然后再贴最小的图片,不然顺序乱的话,就会大图把小图给盖住,从而影响到游戏的效果。

还有一点要注意,在贴完图后一定别忘了ReleaseDC(pDC);很重要,不然会内存泄露。

6, 在界面上显示鼠标的纵横坐标。

 在view类里添加鼠标移动的消息响应

void CGobangView::OnMouseMove(UINT nFlags, CPoint point) 

{

// TODO: Add your message handler code here and/or call default

 

CView::OnMouseMove(nFlags, point);

int x=point.x;

int y=point.y;

CString st;

st.Format(("%d  ,%d  "),x,y);

CDC *pDC=GetDC();

pDC->TextOut(200,0,st);

ReleaseDC(pDC);

SetCursor(LoadCursor(NULL,IDC_CROSS));//加载一个十字形状的鼠标光标。

CView::OnMouseMove(nFlags,point);

}

7, 添加一个PrintState(CDC *pDC)的函数,来在界面的顶部显示白子,黑子,还有到谁走棋等界面显示。

定义一个全局变量type1type1=1时,黑子走棋,type1=0时,白子走棋,当type1=2时,游戏还没有开始。三种状态,三种不同的写法,但是都是大同小异。

void CGobangView::PrintState(CDC *pDC)//把这个函数要写在PrintAll()这个重绘函数里面。

{

CString st;

if(type1==1)

{

st="                                                        ";

pDC->TextOut(280,10,st);

//这个函数的功能是在距左边框280,距上边框10的地方放上st里面的内容。

st=nameblack+"黑子走棋";

//UpdateData(true);

//PrintPart(8,-1,0,pDC);

UpdateData(false);

}

else if (type1==0)

{

st="                                                     ";

pDC->TextOut(280,10,st);

st=namewhite+"白子走棋";

//UpdateData(true);

//PrintPart(8,-1,1,pDC);

UpdateData(false);

}

else

if(type1==2)

{

st.Format("游戏还没有开始");

}

pDC->TextOut(280,10,st);

pDC->TextOut(130,25,"黑子:");

pDC->TextOut(440,25,"白子");

pDC->TextOut(190,25,nameblack);

pDC->TextOut(480,25,namewhite);

st.ReleaseBuffer();//当调用st.GetBuffer()是才会用到ReleaseBuffer()这个方法

}

8, 添加void CGobangView::PrintAll(CDC *pDC)函数

void CGobangView::PrintAll(CDC *pDC)

{

int x;

int y;

pDC->BitBlt(0,0,800,600,&Chessboard,0,0,SRCCOPY);//画背景

pDC->BitBlt(590,145,119,64,&Begin,0,0,SRCCOPY);//画开始按钮

pDC->BitBlt(590,275,115,63,&End,0,0,SRCCOPY);//贴结束按钮

pDC->BitBlt(530,400,300,100,&Score,0,0,SRCCOPY);//贴悔棋按钮

pDC->BitBlt(80,530,300,100,&restart,0,0,SRCCOPY);//贴重新开始按钮

PrintState(pDC);

for ( x=0;x<15;x++)//绘制整个棋盘的棋子

for ( y=0;y<15;y++)

{

if (chess[x][y]==1)

redraw(x,y,0,pDC);//负责画白子

else if (chess[x][y]==2)

redraw(x,y,1,pDC);//负责画黑子

}

}

9, 添加redraw(x,y,1,pDC);//根据传进去的坐标和棋子类型判断画白子还是画黑子

void CGobangView::redraw(int x,int y,int type,CDC *pDC)

 {

if(type==0)

{

pDC->BitBlt(73+30*x-14,86+30*y-14,27,28,&Mask,0,0,MERGEPAINT);

pDC->BitBlt(73+30*x-14,86+30*y-14,27,28,&Blackchess,0,0,SRCAND);

}

else if (type==1)

{

pDC->BitBlt(73+30*x-14,86+30*y-14,27,28,&Mask,0,0,MERGEPAINT);

pDC->BitBlt(73+30*x-14,86+30*y-14,27,28,&Whitechess,0,0,SRCAND);

}

10, 添加一个鼠标点击下去时贴棋子的函数

void CGobangView::PrintPart(int x, int y, int type, CDC *pDC)

{

if (chess[x][y]==0)

{

if(type==0)

{

{

pDC->BitBlt(73+30*x-14,86+30*y-14,27,28,&Mask,0,0,MERGEPAINT);//画棋子的背景

pDC->BitBlt(73+30*x-14,86+30*y-14,27,28,&Blackchess,0,0,SRCAND);//画真正的棋子

}

chess[x][y]=1;

type1=1;

else if (type==1)

{  

{

pDC->BitBlt(73+30*x-14,86+30*y-14,27,28,&Mask,0,0,MERGEPAINT);

pDC->BitBlt(73+30*x-14,86+30*y-14,27,28,&Whitechess,0,0,SRCAND);

}

chess[x][y]=2;

type1=0;

}

}

//AfxBeginThread(&thread1,0);

// AfxBeginThread(&thread,0);

PlaySound(MAKEINTRESOURCE(IDR_luozishengyi),AfxGetResourceHandle(), SND_ASYNC |SND_RESOURCE);

}

11, 添加鼠标左键单击的消息响应函数(这一步是关键)

void CGobangView::OnLButtonDown(UINT nFlags, CPoint point)

{

CDC *pDC=GetDC();

int x=point.x;

int y=point.y;

if (x>=582&&x<=720&&y>=140&&y<=212)

{

MessageBox("游戏准备开始");

PlaySound(MAKEINTRESOURCE(IDR_bgsound),AfxGetResourceHandle(), SND_ASYNC |SND_RESOURCE|SND_LOOP);

paste=1;

}

if(x>=584&&x<=709&&y>=268&&y<=346)

{

if(MessageBox("你确实要退出游戏吗!","标题", MB_OKCANCEL )==IDOK)

exit(0);

}

if (x>=92&&x<=248&&y>=537&&y<=583)

{

if(MessageBox("你确要重新开始吗!","标题", MB_OKCANCEL )==IDOK)

{

for(int i=0;i<15;i++)

       for(int j=0;j<15;j++)

{

   chess[i][j]=0;

}

   paste=1;

   win_state=0;

         PrintAll(pDC);

}

}

if (x>=530&&x<788&&y>=400&&y<=500&&win_state==0)

{

MessageBox("悔棋");

{

       chess[temp_mx][temp_my]=0;

   paste=1;

   if(type1==0)

   {

   type1=1;

   UpdateData(false);

   }

   else

if(type1==1)

   {

   type1=0;

   UpdateData(false);

   }

   UpdateData(false);

}

PrintAll(pDC);

}

//下面是具体的贴棋子以及判断胜负的算法

if(paste==1)

{

int mx=(point.x-61)/30;

int my=(point.y-68)/30;

temp_mx=mx;

temp_my=my;

if(mx>=0&&mx<15&&my>=0&&my<15)

{

PrintState(pDC);

if(type1==0)//白棋子的判断

{

PrintPart(mx,my,0,pDC);

//。。。。是判断输赢的算法

从当前的位置开始判断判断八个方向

如果有一个方向满足了五个,则游戏结束

如果胜利,则

{

nameblack="黑方获胜";

pDC->TextOut(190,25,nameblack);

win_state=1;//游戏结束了

PlaySound(MAKEINTRESOURCE(IDR_BLACK_WIN),AfxGetResourceHandle(), SND_ASYNC |SND_RESOURCE);//奏响胜利的凯歌

MessageBox("黑方获胜");

paste=0;//不能贴子了

UpdateData(false);

}

}

如果是黑子,道理和白子相同

}

12, 要注意的知识点

在使用BitBlt时,有两个属性

一个MERGEPAINT//先反色,后OR

另一个是SRCAND//进行and操作

任何颜色同白色进行OR运算结果都是白色,进行AND运算结果都是该颜色本身.

任何颜色同黑色进行OR运算结果都是该颜色本身,进行AND运算,结果都是黑色

13, 小知识点

都是在App类中的InitInstance函数中添加的

让窗口居中

AfxGetMainWnd()->CenterWindow();//直接让窗口居中

让窗口最大化

m_nCmdShow = SW_SHOWMAXIMIZED;

让窗口最小话

m_nCmdShow = SW_SHOWMINIMIZED;

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值