logo资料库

VC++MFC单机和网络版五子棋.doc

第1页 / 共32页
第2页 / 共32页
第3页 / 共32页
第4页 / 共32页
第5页 / 共32页
第6页 / 共32页
第7页 / 共32页
第8页 / 共32页
资料共32页,剩余部分请下载后查看
五子棋 五子棋是一种很受人们喜爱的游戏,它的规则简单,但玩法变化多端,富有趣味性, 适合人们消遣。这里我们就来设计一个五子棋游戏。 (一) (一) 人对人游戏 1. 1. 游戏实现 人对人游戏,其实只是对游戏规则的实现,我们只是利用五子棋游戏的规则来编程, 至于真正的游戏实现——计算机的“智能”算法,我们将在后面讲述。 五子棋的规则很简单: 1,判断是否能放下棋子(是否已经有了棋子); 2,判断是哪种颜色下棋;
3,判断是否已经结束(是谁赢?)。 这些规则,我们将用相应的函数来实现。 其它,我们还将介绍其它一些功能的实现。如鼠标的更换,工具栏和状态栏的编辑, 类与类之间的相互调用。 新建工程 3_1,选择单文档,在 Step 4 of 6 中先中 Windows Sockets 复选框。如下图: 图 3-1-1 2. 2. 资源编辑 由于我们这个程序出现的关于资源编辑的内容太多,我们具体介绍如下: 见下图 3-1-2,我们需要添加的有:
图 3-1-2 黑白位图 Bitmap 以表示棋盘上面的棋子: IDB_BLACK IDB_WHITE 黑白鼠标 Cursor 以替换当前鼠标: IDC_CURSOR1 黑棋子 IDC_CURSOR2 白棋子 说明: 由于下棋时我们必须把鼠标热点设置在中间,点击下图(图 3-1-3)最右边按扭, 然后把鼠标移动到图像中你想设置为热点的地方,按下鼠标左键。
图 3-1-3 黑白图标 Icon 以显示在状态栏供以提示: IDI_BLACK IDI_WHITE 说明: 由于我们的图标支持 256 色,按下下图(图 3-1-4)最右边按扭,选择 Device 里面显示的选项。 图 3-1-4 菜单以供操作: 开始: ID_START 保存: ID_SAVE 打开: ID_OPEN 工具栏: 如上图所示。 说明: 工具栏一般都是根据菜单选项而产生的,它的 ID 一般都能从菜单的 ID 中找 到。
3. 3. 变量函数 首先,为了实现状态栏的应用,我们必须更改它的变量: 在 MainFrm.h 文件里面,把 CStatusBar m_wndStatusBar 为 public 接着是在 3_1View.h 文件里面添加变量函数: //两个鼠标 HCURSOR hcursorwhite; HCURSOR hcursorblack; //棋盘数组 int wzq[19][19]; // colorwhite TRUE 时白棋下,否则黑棋下 bool colorwhite; //棋子位图 CBitmap m_bmblack; CBitmap m_bmwhite; //保存文件 void Save(); //检查是否结束 void over(CPoint point); //鼠标操作 afx_msg void OnLButtonUp(UINT nFlags, CPoint point); //鼠标图形更换 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); //菜单的开始 afx_msg void OnStart(); //菜单的保存 afx_msg void OnSave(); //菜单的打开 afx_msg void OnOpen(); 4. 4. 具体实现 棋盘大小设置: 由于我们的游戏的棋盘大小是一定的,不能改变大小的,是应该符合要求的。在如下 函数添加设置窗口大小的语句: BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: Modify the Window class or styles here by modifying // cs.dwExStyle=cs.dwExStyle|WS_EX_TOPMOST; the CREATESTRUCT cs //
cs.style=WS_SYSMENU|WS_OVERLAPPED|WS_MINIMIZEBOX;//; //设置窗口大小:400*340 cs.cx=450; cs.cy=500; return TRUE; } 初始化变量: 在构造函数里添加初始代码: CMy3_1View::CMy3_1View() { // TODO: add construction code here //Load 鼠标图像和棋子位图 hcursorblack=AfxGetApp()->LoadCursor(IDC_CURSOR1); hcursorwhite=AfxGetApp()->LoadCursor(IDC_CURSOR2); m_bmwhite.LoadBitmap(IDB_WHITE); m_bmblack.LoadBitmap(IDB_BLACK); //清理棋盘 //数组值为 0 表示没有棋子 for(int i=0;i<19;i++) for(int j=0;j<19;j++) wzq[i][j]=0; //白棋先下 colorwhite=true; } 画棋盘: 在 OnDraw(CDC* pDC)函数中画棋盘,由于在游戏过程中有可能重画棋盘,而那时棋盘 上面有棋子,所以,我们在这个函数里面必须有画棋子的语句。 我们用数组的做为 1 表示白棋,-1 表示黑棋。 void CMy3_1View::OnDraw(CDC* pDC) { CMy3_1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here //画背景 CBrush mybrush1; mybrush1.CreateSolidBrush(RGB(192,192,192)); CRect myrect1(0,0,1200,800); pDC->FillRect(myrect1,&mybrush1); //画棋盘框线 CPen mypen; CPen*myoldPen; mypen.CreatePen(PS_SOLID,1,RGB(0,0,0)); myoldPen=pDC->SelectObject(&mypen); for(int i=0;i<19;i++) { pDC->MoveTo(40,40+i*20); pDC->LineTo(400,40+i*20); pDC->MoveTo(40+i*20,40); pDC->LineTo(40+i*20,400); }
//重画时显示存在的棋子 CDC Dc; if(Dc.CreateCompatibleDC(pDC)==FALSE) AfxMessageBox("Can't create DC"); for(int n=0;n<19;n++) for(int m=0;m<19;m++) if(wzq[n][m]==1) { //显示白棋 Dc.SelectObject(m_bmwhite); pDC->BitBlt(n*20+32,m*20+32,160,160,&Dc,0,0,SRCCOPY); } else if(wzq[n][m]==-1) { //显示黑棋 Dc.SelectObject(m_bmblack); pDC->BitBlt(n*20+32,m*20+32,160,160,&Dc,0,0,SRCCOPY); } } 设置鼠标: 棋盘画好了,接下来就是下棋了。但鼠标并没有像我们上面说的那样变成白棋,加 函数如下: BOOL CMy3_1View::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: Add your message handler code here and/or call default if(nHitTest==HTCLIENT) { //白棋下,显示白棋鼠标 if(colorwhite) { //调用主框架里面的状态栏 CMainFrame*pFrm=(CMainFrame*)AfxGetApp()->m_pMainWnd; CStatusBar*pStatus=&pFrm->m_wndStatusBar; if(pStatus) { pStatus->GetStatusBarCtrl().SetIcon(0,AfxGetApp()->LoadIcon(IDI_WHITE)); pStatus->SetPaneText(0,"白棋下"); } SetCursor(hcursorwhite); } //显示黑棋鼠标 else { SetCursor(hcursorblack); CMainFrame*pFrm=(CMainFrame*)AfxGetApp()->m_pMainWnd; CStatusBar*pStatus=&pFrm->m_wndStatusBar; if(pStatus) { //显示图像 pStatus->GetStatusBarCtrl().SetIcon(0,AfxGetApp()->LoadIcon(IDI_BLACK)); //显示文字
pStatus->SetPaneText(0,"黑棋下"); } } return 1; } return CView::OnSetCursor(pWnd, nHitTest, message); } 现在运行程序,怎样,鼠标变成白棋了,而且下面的状态栏也能够显示鼠标状态了, 真是一举两得。可是,又该怎样把棋子放在棋盘上呢? 下棋操作: 这 就 涉 及 到 OnLButtonDown(UINT nFlags, CPoint point) 和 OnLButtonUp(UINT nFlags, CPoint point)两个函数了。要用哪一个或用两个?用 Down 函数时是在鼠标按下 时放下棋子,可是,要是我们按下后意识到按错了怎么办;那就改用 Up 函数,表示当 鼠标键松开时放下棋子。OK! 添加函数如下: void CMy3_1View::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CDC *pDC=GetDC(); CDC Dc; if(Dc.CreateCompatibleDC(pDC)==FALSE) AfxMessageBox("Can't create DC"); //是否在棋盘内 if(point.x>30&&point.x<410&&point.y>30&&point.y<410) { int px=(point.x-30)/20; int py=(point.y-30)/20; //是否已经有棋子 if(colorwhite&&wzq[px][py]==0) { Dc.SelectObject(m_bmwhite); pDC->BitBlt(px*20+32,py*20+32,160,160,&Dc,0,0,SRCCOPY); //表示存在白棋 wzq[px][py]=1; //检查是否结束 over(point); //换黑棋下 colorwhite=false; { Dc.SelectObject(m_bmblack); pDC->BitBlt(px*20+32,py*20+32,160,160,&Dc,0,0,SRCCOPY); wzq[px][py]=-1; over(point); colorwhite=true; } } else if(wzq[px][py]==0) } CView::OnLButtonUp(nFlags, point); }
分享到:
收藏