畢業(yè)設(shè)計(jì)(論文)-單擊對(duì)戰(zhàn)游戲的設(shè)計(jì)與實(shí)現(xiàn)_第1頁
畢業(yè)設(shè)計(jì)(論文)-單擊對(duì)戰(zhàn)游戲的設(shè)計(jì)與實(shí)現(xiàn)_第2頁
畢業(yè)設(shè)計(jì)(論文)-單擊對(duì)戰(zhàn)游戲的設(shè)計(jì)與實(shí)現(xiàn)_第3頁
畢業(yè)設(shè)計(jì)(論文)-單擊對(duì)戰(zhàn)游戲的設(shè)計(jì)與實(shí)現(xiàn)_第4頁
畢業(yè)設(shè)計(jì)(論文)-單擊對(duì)戰(zhàn)游戲的設(shè)計(jì)與實(shí)現(xiàn)_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費(fèi)閱讀

付費(fèi)下載

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

目錄 摘要 . 1 關(guān)鍵字 . 1 1 前言 . 1 1.1 程序開發(fā)背景 . 1 1.2 程序開發(fā)目標(biāo) . 1 1.3 編碼設(shè)計(jì)標(biāo)準(zhǔn)與規(guī)范 . 2 1.4 程序開發(fā)的實(shí)際意義 . 2 1.5 對(duì) “單擊對(duì)戰(zhàn) ”的解釋 . 3 2 相關(guān)軟件及技術(shù)介紹 . 3 2.1 開發(fā)平臺(tái)與工具選擇 . 3 2.1.1 .NET 簡(jiǎn)介 . 3 2.1.2 Microsoft Visual Studio 2008 簡(jiǎn)介 . 3 2.2 相關(guān)技術(shù)簡(jiǎn)介 . 3 2.2.1 使用 UDP 協(xié)議的套接字技術(shù) . 3 2.2.2 使用 TCP 協(xié)議的套接字技術(shù) . 3 2.2.3 Socket 方法和相關(guān)類介紹 . 4 2.2.4 多線程的使用 . 4 2.2.5 事件的使用 . 4 2.2.6 反射調(diào)用一個(gè)類的私有成員 . 4 3 可行性分析與需求分析 . 4 3.1 可行性分析 . 4 3.2 需求分析 . 5 3.2.1 功能需求 . 5 4 單擊對(duì)戰(zhàn)游戲設(shè)計(jì) . 5 4.1 系統(tǒng)設(shè)計(jì)思想 . 5 4.2 系統(tǒng)總體設(shè)計(jì) . 5 5 主要功能詳細(xì)設(shè)計(jì) . 6 5.1 在線用戶列表的獲得 . 6 5.1.1 設(shè)計(jì)思路 . 6 5.1.2 實(shí)現(xiàn)過程 . 6 5.2 進(jìn)入對(duì)戰(zhàn)窗體的友好用戶體驗(yàn) . 9 5.2.1 設(shè)計(jì)思路 . 9 5.2.2 關(guān)鍵代碼 . 9 5.3 五子棋對(duì)戰(zhàn)窗體功能 . 12 5.3.1 設(shè)計(jì)思路 . 12 5.3.2 關(guān)鍵代碼 . 12 6 系統(tǒng)測(cè)試 . 15 6.1 測(cè)試分析報(bào)告 . 15 6.2.1 測(cè)試方式簡(jiǎn)介 . 15 6.2 改進(jìn)意見 . 15 7 結(jié)束語 . 15 致謝 . 15 參考文獻(xiàn) . 15 1 單擊對(duì)戰(zhàn)游戲的設(shè)計(jì)與實(shí)現(xiàn) 計(jì)算機(jī)科學(xué)與技術(shù)專業(yè)學(xué)生 指 導(dǎo)教師 摘要 : 系統(tǒng) 是基于 .NET 平臺(tái) 開發(fā)的 一個(gè) P2P 結(jié)構(gòu) 的單擊對(duì)戰(zhàn) 五子棋 游戲。 基于 P2P、套接字、事件、設(shè)計(jì)模式、多線程、反射等 技術(shù) , 使用 c#語言和 UDP 協(xié)議的套接字進(jìn)行廣播 ,不但 可以 實(shí)現(xiàn) 在 局域網(wǎng)內(nèi)獲得所有在線用戶 IP 列表、狀態(tài) 的功能 , 而且通過 使用 TCP 協(xié)議的 套接字 可以 實(shí)現(xiàn) 多個(gè) 用戶之間 的 連接 、 游戲、聊天、 并 閃動(dòng) 對(duì)方 屏幕 的功能 。 以計(jì)算機(jī)技術(shù)和網(wǎng)絡(luò)技術(shù)為核心的現(xiàn)代網(wǎng)絡(luò)技術(shù)已在現(xiàn)實(shí)生活和生產(chǎn)中得以廣泛的使用,休閑類網(wǎng)絡(luò)游戲集趣味性、娛樂性、互動(dòng)性和益智性于一體,已經(jīng)成為多數(shù)人群的休閑方式。 關(guān)鍵字 : P2P; UDP 廣播; TCP 協(xié)議;設(shè)計(jì)模式; 事件 1 前 言 1.1 程序開發(fā)背景 隨著計(jì)算機(jī)信息技術(shù)的發(fā)展,網(wǎng)絡(luò)游戲已成為我們生活中的重要組成部分,但由于廣域網(wǎng)游戲占用的資源較多、易受到病毒等缺點(diǎn),所以局域網(wǎng) 游戲被游戲愛好者廣泛使用。無論是對(duì)于初步探索網(wǎng)絡(luò)編程的編程愛好者還是有志于在物聯(lián)網(wǎng)方面發(fā)展的程序員,編寫簡(jiǎn)單的局域網(wǎng)游戲都是一個(gè)很好開始。 網(wǎng)絡(luò)游戲在市面上已經(jīng)出現(xiàn)多年,許多游戲?qū)?zhàn)平臺(tái)也已相繼出現(xiàn),例如我們熟知的浩方、 QQ 對(duì)戰(zhàn)平臺(tái)和街機(jī)游戲的 ArcadeLive 平臺(tái)等等,雖說它們有很大的不同,但有一點(diǎn)是可以肯定的:不管是這些游戲還是對(duì)戰(zhàn)平臺(tái),剛開始都是需要在局域網(wǎng)內(nèi)調(diào)試的。然而,出于盈利的目的,開發(fā)商一般不會(huì)將對(duì)戰(zhàn)平臺(tái)的局域網(wǎng)內(nèi)的版本流于市面,更不會(huì)公開自己的原代碼。當(dāng)然通過一些人士的分析和透露,我們知道 浩方是通過把 tcp/ip 協(xié)議轉(zhuǎn)換為 ipx 協(xié)議。虛擬局域網(wǎng),為大家提供了一個(gè)作戰(zhàn)平臺(tái),但游戲開始后,玩家之間就是 p2p 的關(guān)系了,游戲速度和平臺(tái)無關(guān)。但具體的實(shí)現(xiàn)肯定是很困難的,里面至少涉及 hook, P2P, VPN,修改數(shù)據(jù)包, java 或 C+的網(wǎng)絡(luò)編程,進(jìn)程通信,數(shù)據(jù)庫的操作等等。當(dāng)然一些大型游戲里面內(nèi)置了網(wǎng)絡(luò)連接模塊,在局域網(wǎng)內(nèi)是不需要再通過平臺(tái)完成數(shù)據(jù)通信的。但對(duì)于一些單機(jī)游戲,要想完成局域網(wǎng)內(nèi)的對(duì)戰(zhàn),對(duì)戰(zhàn)平臺(tái)就不可或缺了。這方面 ArcadeLive 是比較有代表性的,它的聯(lián)網(wǎng)功能可能是靠 kaillera來實(shí)現(xiàn)的 ,要想實(shí)現(xiàn)聯(lián)網(wǎng)玩游戲 ,你必須有一個(gè) kaillera 的客戶端和一個(gè)服務(wù)器端的程序 ,客戶端現(xiàn)在大多在模擬器中自帶 ,而服務(wù)器端則是一個(gè)單獨(dú)的程序??傊W(wǎng)絡(luò)聯(lián)機(jī)模塊的技術(shù)發(fā)展還是很成熟的,但由于開發(fā)商的保密,很多技術(shù)難題還是要自己解決的。 1.2 程序開發(fā)目標(biāo) 擬開發(fā)基于 p2p 具有運(yùn)用時(shí)自動(dòng)加載在線用戶 IP 列表、雙擊某個(gè) IP 或頭像自動(dòng)進(jìn)入五子棋游戲,并且用戶體驗(yàn)很好的程序。 該程序無需服務(wù)器端,也就是說每個(gè)程序?qū)嵗仁欠?wù)端也是客戶端,也就是常被我們提及的 p2p。運(yùn)行程序時(shí)通過廣播特定的信息使所有在線 的用戶獲得自己的 IP 然后添加到自己的用戶列表上,收到此特定信息的用戶回復(fù)另一信息,然后就可以實(shí)現(xiàn)所有的人獲得在線用戶 IP 的功能。游戲是逐漸被世人拋棄的起源于中國古代的傳統(tǒng)黑白棋種之一的五子棋,雖然它看似無聊,但對(duì)于練習(xí)編程技術(shù)還是很有意義的。本程序中的五子棋使用 TCP 協(xié)議的套接字進(jìn)行通訊,廣 2 泛應(yīng)用了事件機(jī)制,接收到我們自定義的信息后就會(huì)根據(jù)以至的信息頭作出相關(guān)的反映。眾所周之,網(wǎng)絡(luò)游戲會(huì)因?yàn)榉N種原因出現(xiàn)延遲,使用戶持續(xù)等待甚至出現(xiàn)卡死的情況,本程序盡最大的努力提高用戶體驗(yàn)的舒適性,即盡量不發(fā)生卡的情況。 1.3 編碼設(shè)計(jì)標(biāo)準(zhǔn)與規(guī)范 為了在編碼過程中,能夠快速地、有效地閱讀,我們有必要為對(duì)象約定一個(gè)規(guī)范的編碼命名約定。 ( 1) . 對(duì)象命名約定 下面為在編碼過程中會(huì)用到的對(duì)象統(tǒng)一的命名,如下表 1 所示 : 對(duì)象名 命名約定(前綴碼 ) Form Frm TextBox txt PictureBox pic Panle pnl Lable lbl TextBox txt TreeView tv 表 1 對(duì)象統(tǒng)一的命名 ( 2) . 結(jié)構(gòu)化編碼約定 編碼風(fēng)格參照下例進(jìn)行: bool startListen = false; public bool CanAgin, CanAgins, CanDown, IFirst; private Socket socketListerner; private Thread mainThread; public ClientRole clientConnectionRole = new ClientRole(); 在程序中,對(duì)一些比較難懂,或是屬性不熟悉的地方加上必要的文字說明,其次,程序要有層次,使得讀程序時(shí)更易讀懂。 1.4 程序開發(fā)的實(shí)際意義 對(duì)于數(shù)據(jù)的通 信,我們比較熟悉的有 Tcp/Ip 協(xié)議、 UDP 協(xié)議等等。以 UDP協(xié)議為例, UDP 從應(yīng)用程序接過報(bào)文后,附上目的端口號(hào)、源端口號(hào)和其他兩個(gè)小字段后就直接將結(jié)果段遞交給網(wǎng)絡(luò)層。網(wǎng)絡(luò)層將該段封裝到數(shù)據(jù)報(bào)中后,盡力而為地將數(shù)據(jù)包傳遞給接收端主機(jī)。如果數(shù)據(jù)報(bào)到達(dá)接收端主機(jī), UPD 將根據(jù) IP 地址和兩個(gè)端口號(hào)將段中的數(shù)據(jù)交給相應(yīng)的進(jìn)程。本程序中的用戶列表的維護(hù)就是利用使用 UDP 協(xié)議的 Socket 發(fā)送廣播進(jìn)行獲得。然而鑒于 UDP 協(xié)議的無連接特點(diǎn),丟失數(shù)據(jù)包的可能性也很大的,所以當(dāng)進(jìn)入游戲窗體后,真正負(fù)責(zé)通訊的采用了 TCP 協(xié)議 的套接字進(jìn)行通訊,也就是說, UDP 協(xié)議那個(gè)套接字只負(fù)責(zé)維護(hù)列表。本程序中的游戲是人氣很旺的網(wǎng)絡(luò)五子棋,選擇它的原因很簡(jiǎn)單:簡(jiǎn)單直接,不會(huì)上癮,算法簡(jiǎn)單,易于實(shí)現(xiàn)。 本程序的可擴(kuò)展性強(qiáng),程序員可以根據(jù)自己的要求將基于 TCP 的 Socket 也提到一個(gè)類中,然后通過存放到一個(gè)以遠(yuǎn)程端點(diǎn)為 Key 相應(yīng)連接套接字為 Value的 Dictionary 中,以實(shí)現(xiàn)和多人對(duì)戰(zhàn)的要求。當(dāng)然也可以利用反射將游戲程序編譯成一個(gè)類,然后放到一個(gè)特定文件夾下,當(dāng)主窗體運(yùn)行時(shí),自動(dòng)加載。除此之 3 外,對(duì)于網(wǎng)絡(luò)編程的初學(xué)者也是很有幫助的。 1.5 對(duì)“單擊對(duì)戰(zhàn)”的 解釋 本程序采用 p2p 的架構(gòu),即集服務(wù)端和客戶端的功能于一體,整個(gè)設(shè)計(jì)采用事件驅(qū)動(dòng),所以非常方便實(shí)現(xiàn)。之所以叫做“單機(jī)對(duì)戰(zhàn)游戲的設(shè)計(jì)與實(shí)現(xiàn)”,主要是內(nèi)嵌的游戲是五子棋游戲,它在用戶體驗(yàn)上的感覺基本就是單擊鼠標(biāo),沒有太多別的負(fù)責(zé)的操作,很是適合小朋友或是老年人玩。 2 相關(guān)軟件及技術(shù)介紹 2.1 開發(fā)平臺(tái)與工具選擇 2.1.1 .NET簡(jiǎn)介 .NET 的編程模型將開發(fā)語言和運(yùn)行時(shí)平臺(tái)分離,實(shí)現(xiàn)了獨(dú)立與語言的組件技術(shù),通過不同的運(yùn)行平臺(tái), .NET 應(yīng)用可以被擴(kuò)展到 PC、 PDA、手機(jī)和嵌入式設(shè)備 上。 .NET 運(yùn)行平臺(tái)稱為 .NET Framework,是 .NET 平臺(tái)的基礎(chǔ)框架,它創(chuàng)造了一個(gè)完全可操控的安全的和特性豐富的應(yīng)用執(zhí)行環(huán)境,這不但使得應(yīng)用程序的開發(fā)與發(fā)布更加簡(jiǎn)單,并且實(shí)現(xiàn)了眾多語言的無縫連接。 2.1.2 Microsoft Visual Studio 2008 簡(jiǎn)介 為了開發(fā) .NET 的應(yīng)用,微軟推出了強(qiáng)大的 .NET 開發(fā)工具 Visual Studio .NET(以下簡(jiǎn)稱 VS)作為微軟 .NET 戰(zhàn)略的重要組成部分。 VS 包含 C#、 Visual Basic .NET、 Visual c+.NET 等 多個(gè)開發(fā)語言,同時(shí)還為第三方語言工具商提供了接口,只要支持 CLS( Common Language Specification)的語言都可以集成到 VS 環(huán)境中。 VS 充分發(fā)揮了 CLR 的潛力,為開發(fā)者提供了一個(gè)統(tǒng)一的集成開發(fā)環(huán)境和調(diào)試器。由于采用統(tǒng)一的類型定義和共享類庫,各語言不僅在運(yùn)行時(shí),而且在設(shè)計(jì)就可以實(shí)現(xiàn)對(duì)象級(jí) 交互。 VS 不僅提供了 Web Services 開發(fā)工具,而且提供從Web Services 開發(fā)到發(fā)布、注冊(cè)、整合的全過程支持。為創(chuàng)建和部署 Web Services, .Net 平臺(tái)采用了一系列的互聯(lián)網(wǎng)協(xié)議 ,如 XML、 SOAP、 WSDL、 UDDL等用于 Web Services 的部署、請(qǐng)求和響應(yīng)。 軟件人員最關(guān)心的還是開發(fā)效率的提高, VS 人性化的界面和眾多工具將成倍提高開發(fā)效率。無論針對(duì)傳統(tǒng)的 Windows 桌面開發(fā), Web Services,開發(fā)人員都不必在為每種不用的應(yīng)用重寫全部代碼,不必為不同的客戶設(shè)備定制不同的界面。 2.2 相關(guān)技術(shù)簡(jiǎn)介 2.2.1 使用 UDP協(xié)議的套接字技術(shù) 數(shù)據(jù)報(bào)式 Socket( DATAGRAM)是一種無連接的 Socket,對(duì)應(yīng)于無連接的 UDP 服務(wù)應(yīng)用 .不安全 (丟失 ,順序混亂 ,在接收端要分析重排及要求重發(fā) ),但效率高。 使用 UDP 協(xié)議的套接字可以用來向許多系統(tǒng)支持的網(wǎng)絡(luò)發(fā)送廣播數(shù)據(jù)包。要實(shí)現(xiàn)這種功能,網(wǎng)絡(luò)本身必須支持廣播功能,因?yàn)橄到y(tǒng)軟件并不提供對(duì)廣播功能的任何模擬。廣播信息將會(huì)給網(wǎng)絡(luò)造成極重的負(fù)擔(dān),因?yàn)樗鼈円缶W(wǎng)絡(luò)上的每臺(tái)主機(jī)都為它們服務(wù),所以發(fā)送廣播數(shù)據(jù)包的能力被限制于那些用顯式標(biāo)記了允許廣播的套接字中。廣播通常是為了如下兩個(gè)原因而使用的: 1. 一個(gè)應(yīng)用程序希望在本地網(wǎng)絡(luò)中找到一個(gè)資源,而應(yīng)用程序?qū)υ撡Y源的地址又沒有任何先驗(yàn)的知識(shí)。 2. 一些重要的功能,例如路由要求把它們的信 息發(fā)送給所有可以找到的本網(wǎng)段的主機(jī)。被廣播信息的目的地址取決于這一信息將在何種網(wǎng)絡(luò)上廣播。本程序中利用基于 UDP 協(xié)議的套接字向廣播地址 55 發(fā)送廣播的方式以獲得用戶列表。 2.2.2 使用 TCP協(xié)議的套接字技術(shù) 本程序中的游戲部分使用的是的 TCP 協(xié)議 4 的套接字進(jìn)行通訊。眾所周之流式 Socket( STREAM)是一種面向連接的 Socket,針對(duì)于面向連接的 TCP 服務(wù)應(yīng)用,雖然效率低但由于其安全特性被廣泛使用。某一個(gè)棋子的位置很可能關(guān)系到游戲的勝敗,所以使用 TCP 協(xié)議的套接字就可以避 免丟包等問題 。 2.2.3 Socket方法和相關(guān)類介紹 -方法 - Socket (): 創(chuàng)建一個(gè) Socket Bind(): 綁定一個(gè)本地的 IP 和端口號(hào) (IPEndPoint) Listen(): 讓 Socket 偵聽傳入的連接嘗試,并指定偵聽隊(duì)列容量 Connect(): 初始化與另一個(gè) Socket 的連接 Accept(): 接收連接并返回一個(gè)新的 socket Send(): 輸出數(shù)據(jù)到 Socket Receive(): 從 Socket 中讀取數(shù)據(jù) Close(): 關(guān)閉 Socket (銷毀連接 ) -相關(guān)類 - IPAddress 類:包含了一個(gè) IP 地址 IPEndPoint 類:包含了一對(duì) IP 地址和端口號(hào) 2.2.4 多線程的使用 應(yīng)用多線程技術(shù)最大的誤區(qū)在于沒有分清適合的情況就盲目地使用多線程。除非運(yùn)行一個(gè)多處理器計(jì)算機(jī),否則在 CPU 密集的任務(wù)中使用兩個(gè)線程不能節(jié)省多少時(shí)間,理解這一點(diǎn)很重要。在單處理器計(jì)算機(jī)上,讓兩個(gè)線程同時(shí)進(jìn) 行 100萬次運(yùn)算所花的時(shí)間與讓一個(gè)線程進(jìn)行 200萬次運(yùn)算是相同的,甚至使用兩個(gè)線程所用的的時(shí)間更長,因?yàn)橐幚砹硪粋€(gè)線程操作系統(tǒng)必須用一定的事件切換線程,即分配時(shí)間片。使用線程帶來的負(fù)面因素是必須額外考慮線程的并發(fā)、同步等線程安全問題,從而使得程序更加復(fù)雜而難以維護(hù)。然而,有些場(chǎng)合則使用多線程技術(shù)非常合適,網(wǎng)絡(luò)應(yīng)用開發(fā)就是其經(jīng)常出現(xiàn)的場(chǎng)合之一。當(dāng)一個(gè)線程等待從網(wǎng)絡(luò)中獲取數(shù)據(jù),同時(shí)其他線程可以繼續(xù)處理其他的任務(wù), 此時(shí)可以節(jié)省很多時(shí)間。本程序中主要就是在針對(duì) Accept和 Receive 這兩個(gè)會(huì)阻塞的方法使用多線 程。 2.2.5 事件的使用 由于不知道什么時(shí)候會(huì)有人發(fā)送信息給自己,所以程序中應(yīng)用事件來處理對(duì)方的消息,即監(jiān)聽對(duì)方發(fā)送的消息,如果接受到的消息和自己要處理的一致,則執(zhí)行注冊(cè)在其上的方法。例如, A 上線的時(shí)候,就會(huì)向廣播地址發(fā)送 “Logon”消息,已經(jīng)在線上的 B、 C 收到此消息后就行執(zhí)行自定義的OnGetList 事件,然后此事件調(diào)用注冊(cè)在自己身上的 GetListMethod 方法,從而實(shí)現(xiàn)將 A 的 IP 地址加到自己的用戶列表上的功能。 2.2.6 反射調(diào)用一個(gè)類的私有成員 當(dāng)用戶進(jìn)入對(duì)戰(zhàn)窗體后,主窗體的用 戶列表不可用,即一次只能和一個(gè)用戶進(jìn)行游戲,(這只是我個(gè)人規(guī)定)。當(dāng)用戶退出對(duì)戰(zhàn)窗體后,必須要求主窗體的用戶列表重新可用,但我們注意到,窗體類的TreeView 類型字段默認(rèn)是 private,也就是其它類不可訪問的,當(dāng)然我們可以將其改成 internal 或更加訪問級(jí)別使外界可以訪問。但我們有更專業(yè)的手段:利用反射技術(shù)。 .NET 的一個(gè)反編譯工具 Reflector 就是利用發(fā)射實(shí)現(xiàn)的。 3 可行性分析與需求分析 3.1 可行性分析 在很早以前五子棋軟件就已經(jīng)被開發(fā)出來了,當(dāng)時(shí)的五子棋軟件僅提供了 5 “ 人機(jī)模式 ” 與 “ 雙人模 式 ” 。 “ 人機(jī)模式 ” 是指,人與計(jì)算機(jī)進(jìn)行對(duì)弈,計(jì)算機(jī)按照事先編寫好的算法程序來進(jìn)行下棋; “ 雙人模式 ” 是指,兩個(gè)人通過交替使用同一臺(tái)計(jì)算機(jī)來進(jìn)行下棋。無論是選擇哪一種模式,所有的操作都必須在同一臺(tái)計(jì)算機(jī)上來往完成,棋局無法在異地計(jì)算機(jī)之間來進(jìn)行,故而也叫單機(jī)版五子棋軟件。 3.2 需求分析 軟件的需求分析是軟件生存期中重要的一步,也是決定性的一步。只有通過需求分析才能把軟件功能和性能的總體概念描述為具體的軟件需求規(guī)格說明,從而奠定軟件開發(fā)的基礎(chǔ)。在此階段,了解用戶要求本軟件必須滿足的所有功能和限制,以及用戶對(duì)軟 件功能和性能的要求,弄清用戶想要軟件 “做什么 ”,準(zhǔn)確地表達(dá)用戶的要求。 3.2.1 功能需求 ( 1) . 運(yùn)行游戲自動(dòng)獲得所 有 在線用戶列表并且自己的 IP 加到所有其他在上用戶玩家列表上的功能 。 ( 2) . 顯示請(qǐng)求對(duì)戰(zhàn)提示框 。 ( 3) . 進(jìn)入對(duì)戰(zhàn)窗體,其他用戶無法再與其游戲 。 ( 4) . 顯示玩家退出提示框 。 ( 5) . 能通過網(wǎng)絡(luò)進(jìn)行下棋 。 ( 6) . 符合五子棋的基本規(guī)則 。 ( 7) . 提供玩家之間的聊天功能 。 ( 8) . 提供玩家之間閃屏功能 。 ( 9) . 一個(gè)用戶退出程序,所有在線用戶列表中自動(dòng)清除退出用戶對(duì)應(yīng)的IP。 ( 10) . 用戶界面需求界面友好、親切 。 ( 11) . 界面簡(jiǎn)潔、不花哨 。 ( 12) . 操作界面直觀、不繁瑣 。 ( 13) . 用戶體驗(yàn)良好 。 4 單擊對(duì)戰(zhàn)游戲設(shè)計(jì) 現(xiàn)有的網(wǎng)絡(luò)編程模式主要分成兩類:一種是基于 C/S(Client/Server客戶機(jī) /服務(wù)器 )模式,另一種是 B/S (Browser/Server,瀏覽器 /服務(wù)器 )模式; C/S 程序具有好的交互性,功能強(qiáng)大, 但是客戶端必須安裝客戶端軟件,服務(wù)器端也要運(yùn)行,限制了其應(yīng)用; B/S 模式下要求客戶端具有瀏覽器,但瀏覽器在安全方面有一些限制,交互性與功能有一些限制。由于這兩種模式的種種弊端,單擊對(duì)戰(zhàn)游戲采用了 p2p網(wǎng)絡(luò)技術(shù)來設(shè)計(jì)與實(shí)現(xiàn) ,網(wǎng)絡(luò)內(nèi)部使用 UDP和 TCP協(xié)議的 Socket 通過傳輸 層提供的服務(wù)進(jìn)行通訊。 4.1 系統(tǒng)設(shè)計(jì)思想 主窗體運(yùn)行時(shí)開啟是一個(gè)基于 UDP協(xié)議的套接字用戶獲得所在網(wǎng)段所用玩家的 IP地址,雙擊一個(gè) IP進(jìn)入對(duì)戰(zhàn)窗體。同時(shí)對(duì)方收到請(qǐng)求對(duì)戰(zhàn)的提示框。 對(duì)戰(zhàn)窗體通過一個(gè) socket 監(jiān)聽其他用戶的連接的連接,一旦有人連接連接,為該用戶建立連接并啟動(dòng)一個(gè)特定的客戶 socket,利用該連接不斷從客戶讀取數(shù)據(jù),雙方的交互。 4.2 系統(tǒng)總體設(shè)計(jì) 系統(tǒng)流程圖 : 6 圖 1 系統(tǒng)流程圖 5 主要功能詳細(xì)設(shè)計(jì) 5.1 在線用戶列表 的獲得 5.1.1 設(shè)計(jì)思路 用戶列表即在線用戶的 IP地址。由于本程序使用的端口號(hào)為1817,所以一般情況下只需要知道本網(wǎng)段內(nèi)所有運(yùn)行了本程序的主機(jī)的 IP就能實(shí)現(xiàn)要求。選擇廣播是最簡(jiǎn)單且效率最高的手段,接下來考慮的就是應(yīng)當(dāng)使用什么協(xié)議的 Socket進(jìn)行廣播。因?yàn)橹皇谦@得列表是需要連接且要求效率較高, UDP顯然在這里最適合。 5.1.2 實(shí)現(xiàn)過程 界面設(shè)計(jì) ( 1) . 新建一個(gè)空解決方案,命名為 ”GobangDemo”,在解決方案上右擊添加一個(gè) “新建項(xiàng)目 ”,在出現(xiàn)的對(duì)話框上選擇 “Windows 窗體應(yīng)用程序 ”命名為“Gobang1”。 ( 2) . 將默認(rèn)生成的窗體刪除,添加一個(gè) “Windows 窗體 ”并命名為 FrmMain,將此窗體的 FormBorderStyle屬性設(shè)為 none。 ( 3) . 拖入一個(gè) Panel控件,命名為 pnlWrap,將它的 Dock屬性設(shè)為 Full。然后依運(yùn)行程序 通過 UDP廣播在線用戶列表 雙擊 某個(gè)用戶列表中IP,進(jìn)入對(duì)戰(zhàn)窗體 運(yùn)行程序 通過 UDP廣播在線用戶列表 是否同意對(duì)戰(zhàn) 請(qǐng)求 開始按鈕可用 ,點(diǎn)擊開始 進(jìn)入對(duì)戰(zhàn)窗體,點(diǎn)擊開始按鈕 點(diǎn)擊棋盤 是否贏了 添加相應(yīng)的棋子到相應(yīng)的位置 顯示對(duì)方贏了對(duì)話框,重新開始按鈕可用 顯示自己贏了對(duì)話框,重新開始按鈕可用 聊天與發(fā)送閃屏 聊天與發(fā)送閃屏 7 次再拖入三個(gè) Panle,分別命名為 pnlTop、 pnlMain、 pnlBelow,然后分別設(shè)置它們對(duì)應(yīng)的 BackgroundImage的值。 ( 4) . 拖入一個(gè) PictureBox控件,命名為 picClose,然后設(shè)置 Image屬性以顯示它默認(rèn)的圖片。拖入一個(gè) ImageList控件,使用默認(rèn)名字 imageList1,在其 Images屬性中添加一個(gè)頭像圖片。拖入一個(gè) ContextMenuStrip控件,使用默認(rèn)命名contextMenuStrip1,然后添加 “顯示主界面 ”和 “退出 ”兩個(gè)子菜單。拖入一個(gè)NotifyIcon控件,使用默認(rèn)命名 notifyIcon1 ,設(shè)置 Visable 屬性為 true ,ContextMenuStrip屬性為 contextMenuStrip1。 ( 5) . 拖入一個(gè) TreeView控件,命名為 tvPlayer,設(shè)值 ImageList屬性為 imageList1,ImageIndex屬性為 0。 小結(jié):其實(shí)要實(shí)現(xiàn)一個(gè)漂亮的界面并不是什么復(fù)雜的問題,只要一張很好看的圖片就可以,但一個(gè)好的編程習(xí)慣那就是將所有的控件都放到 Panel 中,所以就要將圖片切成三段,然后設(shè)置成對(duì)應(yīng)容器的背景顏色。下面分別介紹各控件的具體作用: notifyIcon1 用于將程序圖標(biāo)顯示系統(tǒng)托盤, picClose 用于最小化到系統(tǒng)托盤, tvPlayer 顯示所有在線用戶 IP, imageList1 里的圖片作為用戶列表中的頭像, contextMenuStrip1 作為 notifyIcon1 的菜單。 關(guān)鍵代碼 ( 1) . GetUserList 類中 發(fā)送 UDP 廣播 的方法 SendToAll public void SendToAll(string state) IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse (255. 255. 255.255) , port); Byte sendBytes = Encoding.ASCII.GetBytes(state); try udpGetList.Send(sendBytes, sendBytes.Length, endPoint); ( 2) . GetUserList 類中處理信息的方法 GetList 中 接收來自局域網(wǎng)的信息: IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, port); while (true) Byte receiveBytes = udpGetList.Receive(ref RemoteIpEndPoint); string returnData = Encoding.ASCII.GetString(receiveBytes); /接下來判斷收到的信息,然后作出相應(yīng)的處理 處理 “Logon”消息: GetListEventArgs getList = new GetListEventArgs(); getList.IP = RemoteIpEndPoint.Address.ToString(); getList.Msg = returnData; OnGetList(this, getList); IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(getList.IP), port); 8 Byte sendBytes = Encoding.ASCII.GetBytes(Reply); udpGetList.Send(sendBytes, sendBytes.Length, endPoint); 處理 “Reply”消息: GetListEventArgs getList = new GetListEventArgs(); getList.IP = RemoteIpEndPoint.Address.ToString(); if (getList.IP != IPAddress.Loopback.ToString() getList.Msg = returnData; OnGetList(this, getList); ( 3) . 使用到的事件 public event EventHandler OnGetList; 其中的 GetListEventArgs 是一個(gè)繼承自 EventArgs 的自定義類: public class GetListEventArgs : EventArgs public string Msg; /獲得發(fā)過來的信息 public string IP; /獲得對(duì)方 IP,用于顯示的主界面的用 戶列表上 ( 4) . 窗體類 FrmMain 的中的 TreeNode node = new TreeNode(); node.Text = e.IP; node.Tag = (object)e.IP; foreach (TreeNode n in tvPlayer.Nodes) if (n.Text = node.Text | n.Text.Contains(node.Text) return; tvPlayer.Nodes.Add(node); 小結(jié):在 p2p 理念下,使用廣播獲得用戶列表是目前為止我發(fā)現(xiàn)的最高效的實(shí)現(xiàn)手段 。 可以看到只需 向 廣播地址發(fā)送 “Logon”信息, 在線的所有用戶都會(huì)接收到此信息,然后執(zhí)行相應(yīng)的代碼,其中最重要的就是將發(fā)送此信息的用戶的 IP加到自己的 tvPlayer 中 。 圖 2 主界面 9 5.2 進(jìn)入對(duì)戰(zhàn)窗體的友好用戶體驗(yàn) 5.2.1 設(shè)計(jì)思路 IP 為 88 的用戶 雙擊想要對(duì)戰(zhàn)用戶的 IP(假設(shè)是80),這次操作共發(fā)送兩類信息: 180 收到 “Fight”消息,所有在線用戶收到 “InRoom”消息 。 180 進(jìn)入對(duì)戰(zhàn)窗體,此時(shí)他的 “開始 ”按鈕不可用 。 于是 180的用戶將看到請(qǐng)求對(duì)戰(zhàn)的窗體 ,并且 180 發(fā)送 “Thinking”廣播; 所用 用戶的用戶列表 上 180 將添加 fighting標(biāo)記, 180 將添加 thinking標(biāo)記,此時(shí)這兩個(gè) 用戶暫時(shí) 都 不能再被別人請(qǐng)求對(duì)戰(zhàn)。 如果 180 點(diǎn)擊對(duì)戰(zhàn)窗體的 “同意 ”則進(jìn)入對(duì)戰(zhàn)窗體,此時(shí) 180 將收到 “80 同意了你的請(qǐng)求 ”的提示框,點(diǎn)擊確定,開始按鈕可用;如果 180 點(diǎn)擊拒絕, 180 將收到 “80 同意了你的請(qǐng)求 ”的提示框 , 180 的用戶列表再次可用(利用反射訪問似有成員)。 對(duì)戰(zhàn)雙方進(jìn)入對(duì)戰(zhàn)窗體后就開始了各自的服務(wù)端角色。 5.2.2關(guān)鍵代碼 ( 1) . 雙擊 80 節(jié)點(diǎn)的操作 if(!tvPlayer.SelectedNode.Text.Contains(fighting) & !tvPlayer.SelectedNode.Text.Contains(thinking) GetWindow(); frmFight.IpTag = tvPlayer.SelectedNode.Tag.ToString(); frmFight.getUserList = this.getUserList; frmFight.frmMain = this; frmFight.SetFrmFightPicStartUnabled(); getUserList.SendToAll(InRoom); getUserList.SendToSelected(tvPlayer.SelectedNode.Tag.ToString(), Fight); tvPlayer.Enabled = false; frmFight.Show(); else MessageBox.Show(哥游戲中,請(qǐng)勿打擾! ); ( 2) . 80 收到 “Fight”后的操作 getUserList.SendToAll(Thinking); FrmCue frmCue = new FrmCue(); tvPlayer.Enabled = false; frmCue.frmMain = this; frmCue.Tag = e.IP; frmCue.lblIP.Text = e.IP; frmCue.getUserList = this.getUserList; frmCue.Show(); ( 3) . 所有在線用戶收到 “InRoom”后的操作 foreach (TreeNode node in tvPlayer.Nodes) if (node.Text.Contains(e.IP) 10 node.Text = e.IP + fighting; ( 4) . 80 點(diǎn)擊提示框的 “同意 ”按鈕 private void lblAgree_Click(object sender, EventArgs e) IPAddress myIp = Dns.GetHostAddresses(Dns.GetHostName(); getUserList.SendToSelected(lblIP.Text.Trim(), Agree); if (frmFight = null | frmFight.IsDisposed) if (myIp0.ToString() = this.Tag.ToString() this.Close(); return; frmFight = FrmFight.GetInstance(); frmFight.Ready(); frmFight.IpTag = this.Tag.ToString(); frmFight.getUserList = this.getUserList; frmFight.frmMain = this.frmMain; /getUserList.SendToAll(); getUserList.SendToAll(InRoom); frmFight.Show(); this.Close(); ( 5) . 80 點(diǎn)擊提示框的 “拒絕 ”按鈕 private void lblIgnore_Click(object sender, EventArgs e) getUserList.SendToSelected(lblIP.Text.Trim(), Refuse); getUserList.SendToAll(Free); SetFrmMainTreeViewEnabedIsTrue(); this.Close(); ( 6) . 利用反射在 frmCue 中訪問 frnMain 中的似有方法 private void SetFrmMainTreeViewEnabedIsTrue() Type typeFrmMain = frmMain.GetType(); MethodInfo methodNiDongDe = typeFrmMain. GetMethod( SetTreeViewEnableIsTrue,BindingFlags.NonPublic | BindingFlags.Instance); methodNiDongDe.Invoke(frmMain, null); 11 ( 7) . 進(jìn)入對(duì)戰(zhàn) 窗體那一刻開始各自服務(wù)端的角色 IPEndPoint ep = new IPEndPoint(IPAddress.Any, mainPort ); socketListerner = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socketListerner.Bind(ep); socketListerner.Listen(12); startListen = true; while (true) Socket socketServer; ClientConnection conn; try socketServer = socketListerner.Accept(); conn = new ClientConnection(socketServer); dicConnections.Add(socketServer.RemoteEndPoint.ToString(), conn); RemoteTag = socketServer.RemoteEndPoint.ToString(); catch break; dicConnectionssocketServer.RemoteEndPoint.ToString().

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論