需要的技术和方法:
Socket通信、获取鼠标点击事件、DC画线画圆
1、大体思路:
为了实现两两互连在线下棋,运用Socket通信实现信息的发送和接受
通过单文档继承基类CView类,在OnPaint函数中画出棋盘和棋子,新建一个棋盘类ChessBoard,已保存已下的坐标和判断输赢,刷新界面以重绘的方式实现下一步显示一步棋子的方式。
2、运用的方法:
-
截获WM_LBUTTONUP:用于获取鼠标左击事件,实现下棋;
ON_MESSAGE(WM_LBUTTONUP,DownChess)LRESULT DownChes(WPARAM wParam,LPARAM lParam) { if(bCanDown)//bCanDown控制是否轮到自己 { CPoint pt; GetCursorPos(&pt);//获取当前鼠标点击坐标,非当前程序界面坐标 ScreenToClient(&pt);//转换为当前界面的坐标 if(!UpdateChessBoard(iChessType,pt)) return TRUE;//用于下棋,包含是否能下,是否胜利等判断; int iRow,iCol; board.GetCurSite(iRow,iCol);//获取这步棋在棋盘的坐标 CString strSite = ""; strSite.Format(_T("%d,%d"),iRow,iCol); pSocket.Send(strSite,(strSite.GetLength())*sizeof(TCHAR));//将下的坐标发送给对方 } }
-
刷新界面
简单方法:ShowWindow()//通过关闭打开刷新
-
画线:
在Onpaint函数中实现界面绘制:
void CChilrdView::Onpaint()
{
CPaintDC dc(this);
int iLineSize = 16;//棋盘大小
CPen bP,*jbP;
bP.CreatePen(PS_DASH,2,RGB(233,233,233));//新建画笔
jbp = dc.SelectObject(&bP);
CRect clientRc;
GetCilentRect(clientRc);
int iWidth = clientRc.Width();
int iHeight = clientRc.Height();
int iStartW = 20;
int iStartH = 20;
double dWDis = (iWidth-2*iStartW)/iLineSize;
double dHDis = (iHeight-2*iStartH)/iLineSize;
//画棋盘
for(int i = 0;i<iLineSize;i++)
{
dc.MoveTo(iStartW,iStartH+i*dHDis);
dc.LineTo((iLineSize-1)*dWDis+iStartW,iStartH+i*dHDis);
}
for(int i = 0;i<iLineSize;i++)
{
dc.MoveTo(iStartW+i*dWDis,iStartH);
dc.LineTo(iStartW+i*dWDis,(iLineSize-1)*dHDis+iStartH);
}
dc.SelectObject(jbp);
if(bCanDrawChess) DrawAllChess(dc);//自定义函数,用于画棋子,其中棋子布局用int类型的二维数组保存
}
画圆函数:
void DrawAllChess(CPaintDC &dc)
{
for(int i =0 ;i<chessBoardSize;i++){
for(int j = 0;j<chessBoardSize;j++)
{
if(Chess[i][j] == NoChess) continue;
CBrush* brush = NULL;
if(Chess[i][j] == BlackChess) brush = new CBrush(RGB(255,255,255));刷子,用于填充圆
else brush = new Brush(RGB(0,0,0));
CBrush *oldBrush = dc.SelectObject(brush);
dc.Ellipse(iCurStartX-this->ChessR,iCurStartY-this->ChessR,iCurStartX+this->ChessR,iCurStartY+this->ChessR);//画圆方法函数
dc.SelectObject(oldBrush);
delete brush;
brush = NULL;
}
}
}