网络游戏实例vc++网络五子棋Word文档下载推荐.docx

上传人:b****6 文档编号:18269092 上传时间:2022-12-14 格式:DOCX 页数:27 大小:121.54KB
下载 相关 举报
网络游戏实例vc++网络五子棋Word文档下载推荐.docx_第1页
第1页 / 共27页
网络游戏实例vc++网络五子棋Word文档下载推荐.docx_第2页
第2页 / 共27页
网络游戏实例vc++网络五子棋Word文档下载推荐.docx_第3页
第3页 / 共27页
网络游戏实例vc++网络五子棋Word文档下载推荐.docx_第4页
第4页 / 共27页
网络游戏实例vc++网络五子棋Word文档下载推荐.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

网络游戏实例vc++网络五子棋Word文档下载推荐.docx

《网络游戏实例vc++网络五子棋Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《网络游戏实例vc++网络五子棋Word文档下载推荐.docx(27页珍藏版)》请在冰豆网上搜索。

网络游戏实例vc++网络五子棋Word文档下载推荐.docx

它负责响应Receive

的消息。

服务器端和客户端都用这个socket发送和接受数据。

_CMessg.h/CMessg.cpp:

发送和接受的数据的定义。

它采用串行化的方式对网络数据进行处理。

五子棋规则部分包括如下文件。

_Match.h/Match.cpp:

Match类中保存着当前的棋盘,它还负责判断是否能够在指定的位置落子,

是否出现输赢局面。

1.4代码详细分析

下面将分析网络五子棋游戏中的网络控制、五子棋规则和视图控制部分的相关代码。

_网络控制部分:

CServerSocket、CClientSocket和CMessg。

第4章网络游戏开发209

CServerSocket类是一个专门用来监听客户端连接的Socket类,它继承于CSocket,响应OnAccept

消息。

CServerSocket类声明如下:

classCServerSocket:

publicCSocket

{

public:

CFiveChessView*m_view;

//主视图的指针,为接受连接函数服务

UINTm_uPort;

//需要监听的端口

BOOLInit(UINTport,CFiveChessView*dlg);

//socket的初始化

virtualvoidOnAccept(intnErrorCode);

//接受连接消息处理函数

};

在ServerSocket.cpp中的核心代码如下,其中成员函数Init负责初始化ServerSocket,而OnAccept

函数负责接收客户端连接。

BOOLCServerSocket:

:

Init(UINTport,CFiveChessView*view)

m_uPort=port;

m_view=view;

//创建socket

if(Create(m_uPort)==FALSE)

AfxMessageBox("

ServerSocketCreateError"

);

returnFALSE;

}

//监听socket

if(Listen()==FALSE)

ServerListenError"

returnTRUE;

voidCServerSocket:

OnAccept(intnErrorCode)//接受客户端连接

CSocket:

OnAccept(nErrorCode);

//调用视图类中的连接处理函数

m_view->

ProcessPendingAccept();

CClientSocket类是一个专门用做会话的类,它负责数据的发送和接收。

它继承自CSocket,负责

响应OnReceive和OnClose消息。

另外,作为CSocket类的继承类,理所当然的采用了串行化的方式

来处理网络数据。

网络数据是由CMessg的对象构成的。

另外,在CClientSocket类中还定义了几个静态函数,它们用来得到本机的名字和本机的IP地址。

CClientSocket类声明如下:

classCClientSocket:

210VisualC++游戏开发技术与实例

CArchive*m_aSessionIn;

//输入数据的串行化

CArchive*m_aSessionOut;

//输出数据的串行化

CSocketFile*m_sfSocketFile;

//Socket关联文件指针

//视图指针

boolm_bInit;

//是否初始化

boolm_bClose;

//连接是否已关闭

voidInit(CFiveChessView*view);

//socket和串行化相关的初始化

BOOLSendMessage(CMessg*msg);

//发送消息的函数

voidCloseSocket();

//关闭socket函数

//几个静态函数,用来得到主机名和主机IP地址

staticintGetLocalHostName(CString&

sHostName);

//获得本地计算机名称

staticintGetIpAddress(constCString&

sHostName,CString&

sIpAddress);

//获得本地IP

sHostName,BYTE&

f0,BYTE&

f1,BYTE&

f2,BYTE

&

f3);

//这个静态函数根据GetLastError()返回的tag找到网络失败的原因

staticCStringErrorReason(inttag);

virtualvoidOnReceive(intnErrorCode);

//数据接受消息的处理函数

virtualvoidOnClose(intnErrorCode);

//socket关闭的消息处理函数

ClientSocket.cpp中的核心代码如下(构造函数负责部分初始化工作):

CClientSocket:

CClientSocket()

m_aSessionIn=NULL;

m_aSessionOut=NULL;

m_sfSocketFile=NULL;

m_bInit=false;

m_bClose=false;

析构函数负责清除内存。

~CClientSocket()

if(m_aSessionIn)

deletem_aSessionIn;

if(m_aSessionOut)

deletem_aSessionOut;

if(m_sfSocketFile)

deletem_sfSocketFile;

OnReceive函数负责接收对方发送过来的数据,并对数据进行相应的处理。

这是一个消息响应

函数:

voidCClientSocket:

OnReceive(intnErrorCode)

OnReceive(nErrorCode);

do

第4章网络游戏开发211

CMessgtemp;

temp.Serialize(*m_aSessionIn);

m_sMsgList+=temp.m_strText;

//加入新的对话内容

//把新的对话内容显示在主视图窗口的一个Edit控件中

m_outputedit.SetWindowText(m_view->

m_sMsgList);

//把Edit窗口中显示的内容滚动到当前的位置

m_iLineCurrentPos=m_view->

m_outputedit.GetLineCount();

m_outputedit.LineScroll(m_view->

m_iLineCurrentPos);

//判断对方发送过来的数据是否是落子的位置

if(m_view->

m_match.CanDown(temp.m_x,temp.m_y,m_view->

m_who%2+1))

//是对方发送的落子信息

m_turn=temp.m_turn;

//该轮到我走棋了

Invalidate(FALSE);

//刷新视图,显示对方的走子位置

//对方是否赢了

m_match.IsWin(m_view->

m_who%2+1,m_view->

m_winpos))

m_bWin=TRUE;

//对方赢了

m_bOver=TRUE;

你输了"

//显示输棋的对话框

m_sMsgList+="

;

while(!

m_aSessionIn->

IsBufferEmpty());

Init函数负责初始化串行化socket:

Init(CFiveChessView*view)

m_sfSocketFile=newCSocketFile(this);

m_aSessionIn=newCArchive(m_sfSocketFile,CArchive:

load);

m_aSessionOut=newCArchive(m_sfSocketFile,CArchive:

store);

this->

SendMessage函数负责串行化数据到对方socket:

BOOLCClientSocket:

SendMessage(CMessg*msg)

if(m_aSessionOut!

=NULL)

msg->

Serialize(*m_aSessionOut);

//输出串行化

m_aSessionOut->

Flush();

//直接发送

212VisualC++游戏开发技术与实例

else

//对方关闭了连接

m_bClose=true;

CloseSocket();

关闭Socket、清除串行化数据的工作由函数CloseSocket完成:

CloseSocket()

Close();

对方关闭了Socket的消息响应处理函数OnClose:

OnClose(intnErrorCode)

OnClose(nErrorCode);

GetLocalHostName函数负责获得本地计算机名称:

intCClientSocket:

GetLocalHostName(CString&

sHostName)

charszHostName[256];

intnRetCode;

nRetCode=gethostname(szHostName,sizeof(szHostName));

if(nRetCode!

=0)

//产生错误

sHostName=_T("

没有取得"

returnGetLastError();

第4章网络游戏开发213

sHostName=szHostName;

return0;

GetIpAddress函数负责获得本地IP地址:

GetIpAddress(constCString&

sIpAddress)

structhostentFAR*lpHostEnt=gethostbyname(sHostName);

if(lpHostEnt==NULL)

sIpAddress=_T("

"

//获取IP

LPSTRlpAddr=lpHostEnt->

h_addr_list[0];

if(lpAddr)

structin_addrinAddr;

memmove(&

inAddr,lpAddr,4);

//转换为标准格式

sIpAddress=inet_ntoa(inAddr);

if(sIpAddress.IsEmpty())

GetIpAddress的一个重载:

f1,BYTE

f2,BYTE&

f3)

f0=f1=f2=f3=0;

f0=inAddr.S_un.S_un_b.s_b1;

f1=inAddr.S_un.S_un_b.s_b2;

f2=inAddr.S_un.S_un_b.s_b3;

f3=inAddr.S_un.S_un_b.s_b4;

214VisualC++游戏开发技术与实例

CMessg类是一个数据类,它继承于CObject。

在这个程序中,让CMessg类发挥串行化数据的作

用。

CMessg类中包括了几个主要的成员变量:

CStringm_strText;

intm_turn;

intm_x;

intm_y;

其中m_strText表示聊天的字符串;

m_turn表示轮到谁走棋;

m_x表示落子的水平方向的位置;

m_y表示落子的竖直方向的位置。

这4个数据构成了网络传输数据的全部信息。

事实上,在发送具体的CMessg数据的时候并不需要用到所有这4个成员变量。

例如,用户只是

聊天的时候,只需要填充m_strText就可以了,m_turn、m_x和m_y会被初始填充为–1,表示没有子

落下。

而当用户落子的时候,m_strText会被初始填充成NULL,m_turn、m_x和m_y会被填充成具体

的落子位置和轮换信息。

CMessg.h中的核心代码如下:

classCMessg:

publicCObject

protected:

DECLARE_DYNCREATE(CMessg)

//聊天的内容

//轮到谁落子

//落子的水平位置

//落子的竖直位置

voidInit();

//初始化

virtualvoidSerialize(CArchive&

ar);

//串行化数据类

CMessg.cpp中的核心代码如下:

IMPLEMENT_DYNCREATE(CMessg,CObject)

voidCMessg:

Init()//初始化

m_strText=_T("

m_x=-1;

m_y=-1;

m_turn=-1;

Serialize(CArchive&

ar)//数据串行化

if(ar.IsStoring())

ar<

<

m_strText;

m_turn;

m_x;

m_y;

第4章网络游戏开发215

ar>

>

_Match类(五子棋规则)

正如前面所说的,每一种游戏都有一定的规则,Match类正是五子棋的规则处理类。

在Match类中保存着一个当前的棋盘,它是一个二维的数组intchessboard[LW][LW]。

如果

chessboard[x][y]为0,则表示(x,y)的位置上没有棋子;

如果chessboard[x][y]为1表示该位置上有黑子;

如果chessboard[x][y]为2,则表示该位置上有白子。

Match类还负责判断是否能在某个位置落子,是否有人赢棋。

Cmatch类声明如下:

#defineLW19//棋盘的水平竖直方向的格数

classMatch

Match();

virtual~Match();

intchessboard[LW][LW];

//0表示没有子落下;

1表示黑子落下;

2表示白子落下

BOOLCanDown(intx,inty,intwho);

//是否能在x,y的位置落子

BOOLIsWin(intwho,intpos[5][2]);

//判断是否赢棋

voidClear();

//清除棋盘内容

Match.cpp中的核心代码如下(在构造函数里初始化棋盘):

Match:

Match()

for(inti=0;

i<

LW;

i++)

for(intj=0;

j<

j++)

chessboard[i][j]=0;

Clear函数负责清除棋盘内容:

voidMatch:

Clear()

CanDown函数负责判断在点(x,y)位置是否能落子:

216VisualC++游戏开发技术与实例

BOOLMatch:

CanDown(intx,inty,intwho)

if(x<

0||x>

=LW||y<

0||y>

=LW)

if(chessboard[x][y]!

chessboard[x][y]=who;

判断玩家是否赢棋,如果赢棋则标注五子连珠的位置。

IsWin(intwho,intpos[5][2])

inti,j;

for(i=0;

for(j=0;

if(chessboard[i][j]==who)

//水平方向

if(j+4<

LW)

if(chessboard[i][j+1]==who&

chessboard[i][j+2]==who&

chessboard[i][j+3]==who&

chess

board[i][j+4]==who)

{//赢棋

//标注赢棋的关键子的位置

for(intk=0;

k<

5;

k++)

pos[k][0]=i;

pos[k][1]=j+k;

//垂直

if(i+4<

if(chessboard[i+1][j]==who&

chessboard[i+2][j]==who&

chessboard[i+3][j]==who&

board[i+4][j]==who)

pos[k][0]=i+k;

pos[k][1]=j;

LW&

j+4<

LW)//东南向

第4章网络游戏开发217

if(chessboard[i+1][j+1]==who&

chessboard[i+2][j+2]==who&

chessboard[i+3][j+3]==who&

chessboard[i+4][j+4]==who)

k++)//标注赢棋的关键子的位置

//东北

if(i-4>

0&

if(chessboard[i-1][j+1]==who&

chessboard[i-2][j+2]==who&

chessboard[i-

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 财会金融考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1