版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、<p><b> 目錄</b></p><p><b> 1緒論1</b></p><p> 1.1課程設(shè)計意義1</p><p> 1.2課設(shè)目的1</p><p> 1.3課設(shè)要求1</p><p> 2網(wǎng)絡(luò)五子棋介紹2</
2、p><p> 2.1網(wǎng)絡(luò)五子棋介紹2</p><p> 2.2游戲玩法2</p><p> 3系統(tǒng)整體設(shè)計3</p><p> 3.1整體設(shè)計3</p><p> 3.2系統(tǒng)流程圖4</p><p><b> 4原理分析5</b></p
3、><p> 4.1服務(wù)器和客戶端通信機制5</p><p> 4.2多線程機制7</p><p> 5服務(wù)器的設(shè)計與實現(xiàn)8</p><p> 5.1服務(wù)器監(jiān)聽8</p><p> 5.2傳遞信息9</p><p> 6客戶端設(shè)計與實現(xiàn)10</p>&
4、lt;p> 6.1客戶端界面設(shè)計11</p><p> 6.1.1GUI圖形界面設(shè)計12</p><p> 6.1.2注冊監(jiān)聽者13</p><p> 6.2連接服務(wù)器14</p><p> 6.3傳遞信息14</p><p> 6.4棋盤數(shù)據(jù)結(jié)構(gòu)15</p>&
5、lt;p> 6.5判斷輸贏算法16</p><p> 6.6背景音樂17</p><p><b> 7設(shè)計實現(xiàn)18</b></p><p><b> 8總結(jié)20</b></p><p><b> 謝辭21</b></p><
6、p><b> 參考文獻21</b></p><p><b> 緒論</b></p><p><b> 課程設(shè)計意義</b></p><p> 五子棋是起源于中國古代的傳統(tǒng)黑白棋種之一。五子棋不僅能增強思維能力,提高智力,而且富含哲理,有助于修身養(yǎng)性。</p><p&
7、gt; 經(jīng)過一個學期的學習,使我對Java有了一定的了解。但要深入理解Java語言,單靠上課是不夠的。必須通過課程設(shè)計,設(shè)計一個比較大的程序,才能更深一步地理解Java語言。在這次課程中,我選擇了網(wǎng)絡(luò)五子棋作為課題。編寫網(wǎng)絡(luò)五子棋游戲要利用到Socket網(wǎng)絡(luò)編程技術(shù)和多線程。通過這次課程設(shè)計,熟悉Java的GUI圖形界面設(shè)計,網(wǎng)絡(luò)Socket 編程和多線程編程。</p><p><b> 課設(shè)目的&
8、lt;/b></p><p> 通過課程設(shè)計,使學生理論聯(lián)系實際,在程序設(shè)計實踐中進一步了解JAVA程序設(shè)計方法掌握類和對象的基本編程方法,熟悉GUI圖形界面編程技術(shù),初步了解Socket編程方法。</p><p><b> 課設(shè)要求</b></p><p> 通過課程設(shè)計完成一個網(wǎng)絡(luò)五子棋游戲。由服務(wù)器和客戶端組成。在Intern
9、et中不同用戶使用客戶端通過服務(wù)器與其它玩家連接。進行五子棋網(wǎng)絡(luò)對戰(zhàn)或聊天。</p><p> 程序中要實現(xiàn)GUI圖形界面的棋盤、黑子、白子功能,設(shè)計棋局存儲數(shù)據(jù)結(jié)構(gòu), 實現(xiàn)開始、重來、退出等基本功能, 實現(xiàn)輸贏自動判別算法, 實現(xiàn)網(wǎng)絡(luò)對戰(zhàn)功能, 背景音樂播放功能等。</p><p><b> 網(wǎng)絡(luò)五子棋介紹</b></p><p><
10、;b> 網(wǎng)絡(luò)五子棋介紹</b></p><p> 五子棋是起源于中國古代的傳統(tǒng)黑白棋種之一。五子棋不僅能增強思維能力,提高智力,而且富含哲理,有助于修身養(yǎng)性。五子棋既有現(xiàn)代休閑的明顯特征“短、平、快”,又有古典哲學的高深學問“陰陽易理”;它既有簡單易學的特性,為人民群眾所喜聞樂見,又有深奧的技巧和高水平的國際性比賽;它的棋文化源遠流長,具有東方的神秘和西方的直觀;既有“場”的概念,亦有“點”
11、的連接。它是中西文化的交流點,是古今哲理的結(jié)晶。</p><p> 網(wǎng)絡(luò)五子棋是一般五子棋的網(wǎng)絡(luò)版,沒有加入人機對戰(zhàn)功能。本軟件使兩個不同計算機的使用者通過一定的網(wǎng)絡(luò)連接,達到兩人對戰(zhàn)的功能。首先運行服務(wù)器監(jiān)聽客戶端連接請求。運行客戶端與服務(wù)器相連,若連接成功,則進入游戲。選擇房間,一個房間最多兩個人,人滿后,雙方可以開始游戲。</p><p><b> 游戲玩法</b
12、></p><p> 網(wǎng)絡(luò)五子棋規(guī)則:棋盤采用15條橫線×15條堅線組成交叉的每個點都可以放棋。</p><p> 本游戲至少需要二個客戶端才能進行游戲??蛻舳伺c服務(wù)器連接成功后,進入游戲大廳(房間號為0),選擇一個大于0的房間號,如果該房間未滿,即小于兩個人,則可進入。點“游戲開始”,處于等待狀態(tài)。如果對方也點擊了“游戲開始”。雙方就可以在網(wǎng)上進行對戰(zhàn)了。在對戰(zhàn)的同時
13、還可以聊天,可以在同一房間內(nèi)私聊,也可以發(fā)送消息給所有在線的用戶。</p><p> 游戲分黑白兩方,每局由規(guī)定黑方先行。黑方玩家移動鼠標在棋盤中點擊行棋。當黑方行棋完畢,轉(zhuǎn)由白方行棋。同色棋子在棋盤上形成橫、豎、斜形成 “五子相連”則獲勝。如果棄權(quán),則判為輸。</p><p><b> 系統(tǒng)整體設(shè)計</b></p><p><b&g
14、t; 整體設(shè)計</b></p><p> 網(wǎng)絡(luò)五子棋是采用網(wǎng)絡(luò)協(xié)議為TCP/IP的網(wǎng)上對弈游戲,運用“客戶端-服務(wù)器“(c/s)網(wǎng)絡(luò)架構(gòu)模式。實現(xiàn)用戶通過Internt連接在任何地方與不同玩家進行對戰(zhàn)。服務(wù)器可以創(chuàng)建任意多局游戲。</p><p> 通過使用多線程和網(wǎng)絡(luò)套接字SOCKET來實現(xiàn)游戲之間的通訊,它是基于點對點的通訊。開始讓服務(wù)器初始化建立服務(wù)器套接字SOCK
15、ET,基于某個端口PORT,服務(wù)器始終處于監(jiān)聽狀態(tài)??蛻舳耸莿幼鞯陌l(fā)起者,何時發(fā)出申請由客戶端決定??蛻舳讼蚍?wù)器發(fā)出申請,服務(wù)器給予響應(yīng)。打開客戶端套接字SOCKET,連接到服務(wù)器端的地址ADDRESS和端口PORT。連接建立后,創(chuàng)建一個SOCKET實例,并開始一個線程,監(jiān)聽該客戶端請求。服務(wù)器繼續(xù)監(jiān)聽其它用戶的連接。服務(wù)器通過數(shù)據(jù)輸入流從客戶端接收信息,并且通過數(shù)據(jù)輸出流把相應(yīng)的信息發(fā)送給客戶端??蛻舳税l(fā)送請求和響應(yīng)接收到的各種信息
16、。</p><p> 在服務(wù)器和客戶端之間傳遞的消息格式是采用“[消息類別]+內(nèi)容“組成的,服務(wù)器和客戶端在傳遞消息的過程,根據(jù)消息的類別來進行相關(guān)的操作。比如要發(fā)送聊天信息,則在客戶端發(fā)送的過程中,自動加上[MSG]在要發(fā)送的消息前面,服務(wù)器接收到客戶端發(fā)來的消息,用startsWith()的方法來讀取消息頭部,如果等于”[MSG]“,進行一步判定是為群聊還是私聊,分別調(diào)用不同的方法向客戶端發(fā)送聊天內(nèi)容。&l
17、t;/p><p><b> 圖3-1</b></p><p><b> 系統(tǒng)流程圖</b></p><p> 服務(wù)器流程圖:圖1-2</p><p><b> 圖3-2</b></p><p> 客戶端流程圖:圖3-3</p><
18、;p><b> 圖3-3</b></p><p><b> 原理分析</b></p><p> 服務(wù)器和客戶端通信機制</p><p> Socket是面向客戶/服務(wù)器模型設(shè)計的,網(wǎng)絡(luò)上的兩個程序通過一個雙向的通訊連接實現(xiàn)數(shù)據(jù)的交換,這個雙向鏈路的一端稱為一個Socket。 Socket通常用來實現(xiàn)客戶方和服
19、務(wù)方的連接??蛻舫绦蚩梢韵騍ocket寫請求,服務(wù)器將處理此請求,然后通過Socket將結(jié)果返回給用戶 。</p><p> 在java中使用套接字相當簡單,Java API為處理套接字的通信提供了一個類java.net.Socket。使得編寫網(wǎng)絡(luò)應(yīng)用程序相對容易。JAVA支持流套接字(stream socket)和數(shù)據(jù)報套接字(datagram socket)。流套接字使用TCP(Transmission C
20、ontrol Protocol,傳輸控制協(xié)議)進行數(shù)據(jù)傳輸,而數(shù)據(jù)報套接字使用UDP(User Datagram Protocol,用戶數(shù)據(jù)報協(xié)議)。</p><p><b> 圖4-1</b></p><p> 在Java中Socket可以理解為客戶端或者服務(wù)器端的一個特殊的對象,這個對象有兩個關(guān)鍵的方法,一個是getInputStream方法,另一個是getO
21、utputStream方法。getInputStream方法可以得到一個輸入流,客戶端的Socket對象上的getInputStream方法得到的輸入流其實就是從服務(wù)器端發(fā)回的數(shù)據(jù)流。GetOutputStream方法得到一個輸出流,客戶端Socket對象上的getOutputStream方法返回的輸出流就是將要發(fā)送到服務(wù)器端的數(shù)據(jù)流,(其實是一個緩沖區(qū),暫時存儲將要發(fā)送過去的數(shù)據(jù))。</p><p> 客戶端
22、啟動以后,與服務(wù)器連接,服務(wù)器會啟動一個線程來與客戶進行文字交流。</p><p> 要完成這個工作,需要完成三個部分的工作:</p><p> Java中有一個專門用來建立Socket服務(wù)器的類,名叫ServerSocket,可以用服務(wù)器需要使用的端口號作為參數(shù)來創(chuàng)建服務(wù)器對象。</p><p> ServerSocket server=new Server
23、Socket(8888);</p><p> 這條語句創(chuàng)建了一個服務(wù)器對象,這個服務(wù)器使用8888號端口。當一個客戶端程序建立一個Socket連接,所連接的端口號為8888時,服務(wù)器對象server便響應(yīng)這個連接,并且server.accept()方法會創(chuàng)建一個Socket對象。服務(wù)器端便可以利用這個Socket對象與客戶進行通訊。Socket socket=server.accept();</p>
24、;<p> 進而得到輸入流和輸出流,并進行封裝。</p><p> reader=newBufferedReader(newInputStreamReader (socket.getInputStream()));</p><p> writer = new PrintWriter(socket.getOutputStream(), true);</p>
25、<p> 隨后,就可以使用reader.readLine()方法得到客戶端的輸入,也可以使用writer.println()方法向客戶端發(fā)送數(shù)據(jù)。從而可以根據(jù)程序的需要對客戶端的不同請求進行回應(yīng)。</p><p> 在所有通訊結(jié)束以后應(yīng)該關(guān)閉這兩個數(shù)據(jù)流,關(guān)閉的順序是先關(guān)閉輸出流,再關(guān)閉輸入流,即使用 </p><p> reader.close(); </p>
26、<p> writer.close();</p><p> 相比服務(wù)器端,客戶端要簡單一些,客戶端只需用服務(wù)器所在機器的ip以及服務(wù)器的端口作為參數(shù)創(chuàng)建一個Socket對象。得到這個對象后,就可以用"建立服務(wù)器"部分介紹的方法實現(xiàn)數(shù)據(jù)的輸入和輸出。</p><p> socket=new Socket("127.0.0.1", 8
27、888);</p><p> reader=newBufferedReader(new InputStreamReader(socket.getInputStream()));</p><p> writer=new PrintWriter(socket.getOutputStream(), true);</p><p> 以上的程序代碼建立了一個socket
28、對象,這個對象連接到ip地址為127.0.0.1(本機IP地址,為了驗證方便)的主機、端口為8888的服務(wù)器對象。并且建立了輸入流和輸出流,分別對應(yīng)服務(wù)器的輸出和客戶端的寫入。</p><p><b> 多線程機制</b></p><p> 多線程機制是指單個程序可以運行多個不同的線程,執(zhí)行不同的任務(wù)。因為線程只能在單個進程的作用域內(nèi)活動,所以創(chuàng)建線程比創(chuàng)建進程要
29、廉價得多,同一類線程共享代碼和數(shù)據(jù)空間,每個線程有獨立的運行桟和程序計數(shù)器(PC),線程切換的開銷小。因此多線程編程在現(xiàn)代軟件設(shè)計中在量采用。</p><p> 創(chuàng)建新線程必須編寫一個線程類,用Java編寫多線程代碼有兩種方式</p><p> 直接繼承Java的線程類Thread;</p><p> 實現(xiàn)Runnable接口</p><p
30、> 無論采用哪種方式均需要在程序中編寫Run()方法,線程在運行時要完成的任務(wù)在該方法實現(xiàn)。Thread 類封裝了線程的行為。繼承Thread類須重寫run()方法實現(xiàn)各自的任務(wù)。程序中不要直接調(diào)用線程的run()方法,而是調(diào)用start()方法啟動線程,讓其進入可調(diào)度的狀態(tài),線程獲得調(diào)度時將自動執(zhí)行run()方法。</p><p> 由于Java的單重繼承的限制,有些類必須繼承其它個類時又要實現(xiàn)線程的
31、特性。這時可通過實現(xiàn)Runnable接口的方式來滿足兩方面的要求。Runnable 接口只有一個方法 run(),它就是線程運行時要執(zhí)行的方法,只要將具體代碼寫入其中即可。線程在調(diào)度時將自動調(diào)用Runnable 接口對象的run方法。</p><p> 多線程是Java的一個特點,多線程可以使程序反應(yīng)更快、交互性更強,并能提高執(zhí)行效率。在網(wǎng)絡(luò)五子中如果服務(wù)器是單線程的,則只能與一個客戶端相連,就失去了網(wǎng)絡(luò)對戰(zhàn)的
32、意義了。所以應(yīng)該采用多線程方式。當服務(wù)器與一個客戶端建立連接,就開啟一個線程與之相連,同時監(jiān)聽其它用戶的連接。</p><p><b> 服務(wù)器的設(shè)計與實現(xiàn)</b></p><p> 網(wǎng)絡(luò)五子棋游戲服務(wù)器端主要由以下幾部分組成:圖5-1</p><p><b> 圖5-1</b></p><p&g
33、t; 網(wǎng)絡(luò)五子棋游戲服務(wù)器端主要有三個類: Server類、five_ Thread類(線程類)和BManager類(消息廣播者)。服務(wù)器端主要通過建立流連接來連接客戶端。服務(wù)器建立與一個客戶端連接,就開始一個線程,并同時監(jiān)聽其它客戶端的連接。服務(wù)器接收一客戶端的信息,接收信息后按照此客戶端的要求將信息發(fā)送到相應(yīng)的客戶端,端起到了中介服務(wù)器的作用。為了更清楚地了解客戶端的登陸情況,將服務(wù)器設(shè)計成圖形界面。創(chuàng)建成一個可以顯示游戲信息的框
34、架。在框架中創(chuàng)建一個包含文本區(qū)的滾動窗格,并在文本區(qū)顯示游戲信息。</p><p><b> 圖5-2</b></p><p><b> 服務(wù)器監(jiān)聽</b></p><p> 首先創(chuàng)建一個服務(wù)器對象,并把它附加到8888號端口上,服務(wù)通過這個端口來監(jiān)聽客戶端的連接請求。通過服務(wù)器對象的accept方法來創(chuàng)建一個Soc
35、ket對象并使其與客戶機連接,就開啟一個線程處理客戶之間數(shù)據(jù),同時繼續(xù)監(jiān)聽其它客戶端的連接請求。并將線程添加至BManager對象bMan中。</p><p> ServerSocket server=new ServerSocket(8888);</p><p> Socket socket=server.accept();</p><p> five_Th
36、read thread=new five_Thread(socket);//建立一線程</p><p> thread.start();//啟動線程</p><p> bMan.add(thread);//線程添加至BManager對象</p><p><b> 傳遞信息</b></p><p> 當于客戶端建
37、立連接后,就建立輸入輸出流,由于消息的發(fā)送和接收。</p><p> reader=newBufferedReader(newInputStreamReader (socket.getInputStream()));</p><p> writer = new PrintWriter(socket.getOutputStream(), true);</p><p&g
38、t; five_Thread對象不僅可以獲取套接字、輸入輸出流,而且它還提供了有關(guān)客戶機的消息。例如客戶機的姓名、房間號、游戲開始與否等。這是因為我們需要確定消息的來源及主要在某個房間傳播的消息。并且,消息廣播者也需要參照線程對象的房間號,以便將消息發(fā)送至某個房間中。</p><p> BManager類繼承了Vector類,它的元素為five_ Thread線程對象,這樣可以更容易用BManager 的對象
39、來管理線程對象,如添加、刪除、返回線程對象。BManager可以自由地參照five_Thread對象的房間號和玩家的名字,這樣能向指定的房間發(fā)送消息和用戶名字。需要比較Bmanager各元素的房間號和給定的房間號,若兩者相同,則向此房間發(fā)送消息。</p><p> 服務(wù)器和客戶端之間的交流主要是相同的房間號之間的用戶進行。如發(fā)送聊天消息,棋子信息,贏輸消息的傳送。</p><p> s
40、endToAll(String msg)方法向所有用戶發(fā)送消息,主要是發(fā)送群聊消息。因為消息的發(fā)送主要在相同的房間號中時行,要發(fā)送群聊消息,即所有房間的用戶都能招收到。在輸入聊天信息前加‘a(chǎn)’。表示向所有人發(fā)送。</p><p> SendToRoom(five_Thread thread, String msg)方法用于向指定的房間(roomnum)發(fā)送消息(msg)。房間內(nèi)的兩個用戶都能接收到消息。主要用于
41、發(fā)送發(fā)私聊信息。</p><p> sendTothreadhers(five_Thread thread, String msg)方法用于向與消息發(fā)送者處于同一房間的用戶發(fā)送各種命令。比如發(fā)送在1號房間的一個用戶發(fā)來“[WIN]“,服務(wù)器向1號房間的另一個用戶發(fā)送[[LOSE]。實現(xiàn)原理:使用for循環(huán)檢查元素(線程)的房間號。用getRoomNumber()得到發(fā)送信息的線程的房間號,當房間號相等時,則調(diào)用
42、sendTo(i, msg)方法向第i個房間發(fā)送消息。但并不向thread連接的客戶機發(fā)送消息。</p><p> 服務(wù)器在five_Thread類中重寫run()方法,由于處理在與客戶端連接過程中的數(shù)據(jù)傳輸,處理和控制。消息傳遞格式“[消息類別]+內(nèi)容“。</p><p> “[ROOM]2“表示客戶端請求進入第二號房間。服務(wù)器判斷2號房間是否為滿,如果不為滿,則向客戶端發(fā)送“[RO
43、OM]2”,表示可以進入,并發(fā)送ROOM2中的其它用戶名字。如果人數(shù)已滿,則發(fā)送[FULL]。表示房間已滿,無法進入。</p><p> “[NAME]“表示進入游戲大廳的用戶名字。</p><p> “[START]“表示客戶端要求開始游戲,如果對方也要求游戲,則游戲開始。服務(wù)器發(fā)送[COLOR]WRITE和[COLOR]BLACK表示棋子顏色分別給兩個客戶端。</p>
44、<p> “[DROPGAME]”表示放棄正在進行中的游戲。服務(wù)器發(fā)送“[DROPGAME]“給相同房間中的另一用戶。</p><p><b> 客戶端設(shè)計與實現(xiàn)</b></p><p> 客戶端負責與用戶之間的交互。包括棋盤類OmokBoard類和Client類。OmokBoard類繼承了JPanel類,它主要用于棋盤的繪制和監(jiān)聽鼠標事件,獲得棋子
45、坐標和繪制棋子。它必須擁有輸出流,用以向?qū)κ謧鬟f棋手的下棋信息。主要的方法有:</p><p> putOpponent ()在客戶端顯示對方棋子,保持雙方棋子的一致性。</p><p> check()判斷一方向上同色棋子個數(shù)。</p><p> drawStones()繪制棋子。</p><p> drawBoard()調(diào)用不同的
46、方法,分析實現(xiàn)棋盤、棋子、提示信息的顯示。</p><p> isRunning()標記游戲運行狀態(tài)。</p><p> reset()清空棋盤,在游戲結(jié)果后運行。</p><p> Client類,繼承JFrame類和實現(xiàn)Runnable接口。主要由于界面初始化和注冊事件監(jiān)聽者。主要方法:</p><p> Run()方法覆蓋Run
47、nable接口里的run ()方法,用以對游戲過程中的數(shù)據(jù)傳輸,處理,控制。</p><p> actionPerformed(ActionEvent ae)實現(xiàn)點擊菜單、按鈕、文本框回車事件的具體代碼。</p><p> Connect()與服務(wù)器連接。</p><p> endgame()結(jié)束游戲。</p><p> player
48、sInfo()顯示用戶位置信息,是在游戲大廳中,還是在房間里。</p><p> goToWaitRoom()從房間里退出,進入游戲大廳。</p><p> 網(wǎng)絡(luò)五子棋客戶端主要由以下幾部分組成:圖6-1</p><p><b> 圖6-1</b></p><p><b> 客戶端界面設(shè)計 </b
49、></p><p><b> 圖6-2</b></p><p><b> GUI圖形界面設(shè)計</b></p><p> 五子棋客戶端界面本軟件的的客戶端的界面如圖6-2所示,主要應(yīng)用SWING的組件來實現(xiàn)。界面由菜單、按鈕、文本框、各種對話框、棋盤和黑白棋子等組成。</p><p>
50、客戶端中的按鈕、文本框、標簽等GUI部件都是布置在面板JPanel上的,</p><p> 其中還包括將一塊面板入在另一塊面板中。這樣能實現(xiàn)比較復雜的布局。多個不同的GUI部件放在面板上時,還要設(shè)置它們的布局方式。這里采用了網(wǎng)絡(luò)布局(GridLayout)和方位布局(BorderLayout)。最后將各個面板JPanel添加到窗體JFrame中。</p><p> 菜單包括游戲、音樂、
51、和幫助菜單項。首先創(chuàng)建一個菜單條(MenuBar) jmb,</p><p> 然后創(chuàng)建不同的菜單項(Menu)加入到菜單條中。</p><p> JMenu sound = new JMenu("音樂"); </p><p> jmb.add(sound);</p><p> 最后創(chuàng)建菜單子項(MenuItem)
52、加入菜單項,比如給“音樂”菜單項添加“播放”菜單子項:</p><p> JMenuItem play = new JMenuItem("播放");</p><p> Sound.add(play);</p><p> 棋盤的繪制。五子棋盤(OmokBoard類),五子棋盤繼承了JPanel,它內(nèi)嵌于框架窗口中棋盤的大小采用15*15個方格
53、。每個交叉點處可放置棋子。</p><p> private void drawLine(){</p><p> gbuff.setColor(Color.BLACK);</p><p> for(int i=1; i<=size;i++) {</p><p> gbuff.drawLine(cell, i*cell, cell
54、*size, i*cell);</p><p> gbuff.drawLine(i*cell, cell, i*cell , cell*size);</p><p><b> }</b></p><p><b> }</b></p><p> 當一個用戶放下一個棋子后,同一房間里的兩個用戶的
55、棋盤都要重畫,以顯示自己和對方下的棋子等信息。</p><p> 棋子的繪制。用白色繪制一個圓形的邊框,將填充黑色,這樣就畫好了一個黑色棋。位置要根據(jù)獲得的鼠標點擊的坐標和棋盤的大小來定。</p><p> private void drawBlack(int x, int y)//繪制黑棋</p><p><b> {</b></
56、p><p> Graphics2D gbuff=(Graphics2D)this.gbuff;</p><p> gbuff.setColor(Color.black);</p><p> gbuff.fillOval(x*cell-cell/2, y*cell-cell/2, cell, cell);</p><p> gbuff.se
57、tColor(Color.red);</p><p> gbuff.drawOval(x*cell-cell/2, y*cell-cell/2, cell, cell);//邊框</p><p><b> }</b></p><p><b> 注冊監(jiān)聽者</b></p><p> 圖形用戶界
58、面的每個可能產(chǎn)生事件的組件稱為事件源, 希望事件源上發(fā)生的事件被程序處理, 就要把事件源注冊給能夠處理該事件源上事件的監(jiān)聽者。 </p><p><b> 圖6-3 </b></p><p> 在這里按鈕,菜單,和發(fā)送消息的文本框都是事件源。要想按鈕或菜單發(fā)生事件時,程序能處理,必須注冊監(jiān)聽者。按鈕動作事件ActionEvent的監(jiān)聽者接口為ActionLis
59、tener,給按鈕注冊監(jiān)聽者的方法為addActionListener()。</p><p> sendBox.addActionListener(this);//文本框按回車鍵</p><p> enterButton.addActionListener(this);</p><p> exitButton.addActionListener(this);&
60、lt;/p><p> 在actionPerformed(ActionEvent ae)中編寫上體的事件處理代碼。在發(fā)生事件時事件源將給其注冊的所有監(jiān)聽者對象的發(fā)送消息,實際上就是調(diào)用監(jiān)聽者對象的actionPerformed()方法,從而完成事件的處理。通過getSource()方法:用來獲取事件源對象。處理不同的事件。如處理單擊“音樂播放”菜單和“游戲開始”引起的事件的actionPerfrmed()方法。<
61、;/p><p> public void actionPerformed(ActionEvent ae) //播放音樂</p><p> { if(ae.getSource()==play){</p><p> Object selection[] = {"fi.MID","five.mid"};</p>
62、<p> Object set = JOptionPane.showInputDialog(null,</p><p> "選擇音樂...","播放...", JOptionPane.QUESTION_MESSAGE,null,selection,selecton[0]);</p><p> music
63、=new Sound(set.toString());</p><p> music.play();</p><p><b> }</b></p><p> else if(ae.getSource()==startButton){</p><p> try{ writer.println("[ST
64、ART]");//發(fā)送開始信息</p><p> infoView.setText("等待對方?jīng)Q定.");</p><p> startButton.setEnabled(false);</p><p> }catch(Exception e){}</p><p><b> }</b>
65、;</p><p> 進行五子棋游戲的一個重要的內(nèi)容是獲取鼠標點擊時在棋盤中的坐標,即落下棋子的位置。</p><p> addMouseListener(new MouseAdapter(){</p><p> public void mousePressed(MouseEvent me){</p><p> if(!enable)
66、return;//是否輪到下棋</p><p> int x=(int)Math.round(me.getX()/(double)cell);//得到鼠標坐標 </p><p> int y=(int)Math.round(me.getY()/(double)cell);</p><p> //坐標要求不超過棋盤大小,在坐標上不存在棋子</p>
67、<p> if(x==0 || y==0 || x==size+1 || y==size+1)return;</p><p> if(map[x][y]==BLACK || map[x][y]==WHITE)return;</p><p> writer.println("[STONE]"+x+" "+y);//向服務(wù)器發(fā)送棋子信息&
68、lt;/p><p> } </p><p><b> 連接服務(wù)器</b></p><p> 客戶端連接服務(wù)器,首先用服務(wù)器所在機器的ip以及服務(wù)器的端口作為參數(shù)創(chuàng)建一個Socket對象??蛻舳苏{(diào)用connect()方法進行連接。</p><p> Socket socket=new Socket(&
69、quot;127.0.0.1", 8888);</p><p> 這里以本機地址127.0.0.1為IP地址,是為了方便服務(wù)器和客戶端運行在同一臺機器上做實驗??蛻舳艘婚_始運行,便連接IP127.0.0.1主機的8888號端口如果連接成功,則在TextArea對象msgViewk中顯示成功消息。否則顯示連接錯誤的消息。</p><p><b> 傳遞信息</b
70、></p><p> 客戶端之間的信息傳遞,比如發(fā)送開始游戲,聊天都要通過先經(jīng)過服務(wù)器發(fā)送。服務(wù)器接收到客戶端發(fā)送的各種消息,識別不同消息的類別,采用不同的方法進行處理。</p><p> 當建立與服務(wù)器的連接后,客戶端通過數(shù)據(jù)輸出流發(fā)送相應(yīng)的請求給服務(wù)器,并且通過數(shù)據(jù)輸入流從服務(wù)器端接收信息。客戶端通過開啟一個線程,處理與服務(wù)器之間的數(shù)據(jù)。</p><p&g
71、t; reader=new BufferedReader(new InputStreamReader(socket.getInputStream())); writer=new PrintWriter(socket.getOutputStream(), true);</p><p> new Thread(this).start();//開始一個將調(diào)用這個runnable的run()方法的線程</p&g
72、t;<p> Java運行系統(tǒng)調(diào)用這個方法run()來執(zhí)行線程。在Client類中,繼承了JFrame類,由于Java的單繼承性,Client類就不能再繼承Thread,但可以實現(xiàn)runnable</p><p> 接口,通過覆蓋Runnable接口里的run ()方法,用以對游戲過程中的數(shù)據(jù)傳輸,處理,控制。</p><p> 客戶端與服務(wù)器之間傳遞的信息,都是由“[
73、消息種類]+內(nèi)容“組成的,服務(wù)器接收到來客戶端的消息,分析”[消息種類]“中的內(nèi)容,進行相關(guān)的操作。下面對各種消息的種類作一個介紹。</p><p> [NAME]當用戶在客戶登陸時,發(fā)送給服務(wù)器,用于顯示登陸用戶名字。</p><p> [ROOM]當用戶登陸上時,[ROOM]號為0,記為“游戲大廳”,選擇房間的用戶在“游戲大廳“,房間號為大于0的整數(shù),一個房間最多容納2人,即對戰(zhàn)的
74、雙方。當服務(wù)器端接收到查看[ROOM]房間號人數(shù)是否為滿。不為滿,則發(fā)送”[ROOM]+n”,給客戶端,表示可以進入。否則發(fā)送“[FULL]”。</p><p> [PLAYERS]在客戶端顯示相同房間用戶列表。</p><p> [DISCONNECT]表示對方斷線。</p><p> [COLOR]得到棋子顏色。[COLOR]BLACK表示黑棋。[WIN
75、]表示獲勝。</p><p> [LOSE]表示失敗。</p><p> [EXIT]表示對方離開房間。</p><p> [ENTER]顯示相同房間中登陸的用戶。</p><p> [STONE]表示對方下棋棋子的坐標。</p><p> [MSG]表示聊天的信息,只在相同的房間內(nèi)可見。如果要想讓所有的登陸
76、的用戶都能收到聊天信息,則消息種類為”[MSG]a”</p><p><b> 棋盤數(shù)據(jù)結(jié)構(gòu)</b></p><p> 棋盤設(shè)置成有15*15個方格。定義了一個二維數(shù)組Map[][]用于保存棋子在棋盤中的位置。在程序中用常數(shù)1表BLACK(黑棋),用-1表示W(wǎng)RITE(白棋),用0表示在此位置上無棋子。如在(3,3)位置上有一個黑棋。則Map[3][3]的值為1。
77、</p><p> public static final int BLACK=1, WHITE=-1;//顏色標識值</p><p> private int[][] map;//Map是一個二元數(shù)組,用于保存棋子的位置</p><p><b> 判斷輸贏算法</b></p><p> 輸贏的判斷是網(wǎng)絡(luò)五子棋游
78、戲中一個很重要的部分。當雙方每放下一個棋子的時候,程序都要進行判斷是否已經(jīng)產(chǎn)生了輸贏。如果是,則停止游戲,并發(fā)送結(jié)果給服務(wù)器,服務(wù)器再發(fā)送結(jié)果給對方。橫,豎或者對角線方向上擁有五顆同樣的棋子時,即為勝利。</p><p> 當在棋盤中放入一個棋子時,比如白色。程序要計算它左邊連在一起的白色棋子的個數(shù),然后計算右邊與它相連在一起的白色棋子的個數(shù)。再將兩數(shù)相加,如果為四,與自己加起來剛好為五。則白棋獲勝。用同樣的方
79、法在垂直和對角線方向進行判斷同色棋子個數(shù)。如果獲勝,則客戶端發(fā)送[WIN]給服務(wù)器,否則由對方下棋,并重復進行相同的運算。</p><p> count()方法用來查找并計算連在一起的棋子的個數(shù)。P為基準坐標,dx、dy分別為表示橫向于豎向的變量。col代表棋子顏色。弱dx為-1,dy為0,則計算左邊連續(xù)棋子的個數(shù);若dx為1,dy為1,則計算左下到右上連續(xù)棋子的個數(shù)。dx與dy只取-1、0、1三個值之一。下面
80、是count()方法的代碼。</p><p> private int count(Point p, int dx, int dy, int col)</p><p><b> {</b></p><p><b> int i=0;</b></p><p> for(; map[p.x+(i
81、+1)*dx][p.y+(i+1)*dy]==col ;i++);</p><p><b> return i;</b></p><p><b> }</b></p><p> 用check()方法調(diào)用count()方法,分別在橫、豎和對角線方向上計算相連同色棋子的個數(shù)。</p><p>
82、private boolean check(Point p, int col)</p><p><b> {</b></p><p> if(count(p, 1, 0, col)+count(p, -1, 0, col)==4)//橫向檢查</p><p> return true;</p><p> if(c
83、ount(p, 0, 1, col)+count(p, 0, -1, col)==4)//豎向檢查</p><p> return true;</p><p> if(count(p, -1, -1, col)+count(p, 1, 1, col)==4)//對角線方向檢查</p><p> return true;</p><p>
84、 if(count(p, 1, -1, col)+count(p, -1, 1, col)==4)//對角線方向檢查</p><p> return true;</p><p> return false;</p><p><b> }</b></p><p><b> 背景音樂</b>&
85、lt;/p><p><b> 圖6-4</b></p><p> 通過下拉框,選擇要播放的音樂,點擊確定開始播放。停止播放,在菜單欄中單擊停止播放。如圖6-4所示。</p><p> 播放背景音樂通過Sound類實現(xiàn)。首先要獲得播放文件的URL地址具體過程如下:</p><p> urlLoader=(URLClas
86、sLoader)this.getClass().getClassLoader();</p><p> url=urlLoader.findResource("audio/"+soundfile);//當前目錄audio下</p><p> 再據(jù)url地址獲得一個用于播放的音頻的AudioClip對象</p><p> AudioClip
87、soundData=ap.newAudioClip(url);</p><p> 通過soundData的play()和stop()方法就可以實現(xiàn)音樂的播放和停止。</p><p><b> 設(shè)計實現(xiàn)</b></p><p><b> 首先運行服務(wù)器</b></p><p><b>
88、 圖7-1</b></p><p> 運行兩個客戶端,以便進行對戰(zhàn)??蛻舳说倪B接的IP為127.0.0.1。兩個用戶分別命名為feng和tang。進行游戲大廳后,輸入房間號1,進入1號房間。點擊“開始游戲”進行游戲。</p><p><b> 圖7-2</b></p><p><b> 圖7-3</b>
89、</p><p> 當游戲一方贏時,顯示提示信息。圖7-4所示。</p><p><b> 圖7-4</b></p><p> 同色棋子成“五子相連”為勝,下面黑棋勝。圖7-5所示</p><p><b> 圖7-5</b></p><p> 當游戲進行時,一方棄權(quán)
90、,則按輸處理。另一方獲勝。如圖:圖7-6</p><p><b> 圖7-6</b></p><p><b> 總結(jié)</b></p><p> Java作為一種分布式和可移植的計算機語言,在網(wǎng)絡(luò)軟件開發(fā)上有著特別的優(yōu)點。它開發(fā)方便、快捷,安全性高,對以往復雜的功能,尤其是網(wǎng)絡(luò)通信等方面,實現(xiàn)起來簡潔明了,在網(wǎng)絡(luò)編程領(lǐng)
91、域有著巨大的發(fā)展?jié)摿Α_@次Java課程設(shè)計完成了一個網(wǎng)絡(luò)五子棋的設(shè)計和開發(fā)。包括服務(wù)器和客戶端。不同的用戶使用客戶端,利用服務(wù)器相連。實現(xiàn)了用戶在Internet上任何地方與別人進行五子對戰(zhàn)。網(wǎng)絡(luò)五子棋的實現(xiàn)用到了網(wǎng)絡(luò)套接字和多線程的相關(guān)知識。服務(wù)器創(chuàng)建服務(wù)器Socket,并處于監(jiān)聽狀態(tài)。客戶端向服務(wù)器發(fā)出申請,服務(wù)器接受后,利用輸入輸出流進行通信。并開始一個線程,處理與這個相連的客戶端在游戲過程的數(shù)據(jù)傳輸、控制等。進行五子棋的一個主要
92、算法就是判斷輸贏。這里采用計算落下棋子的橫、豎及對角線方向的同色棋子的個數(shù)來實現(xiàn)。當個數(shù)為5時為勝。服務(wù)器與客戶端在通信過程中,雙方如何知道發(fā)送信息的意義呢?這里發(fā)送的信息采用“[消息類別]+內(nèi)容“的格式。服務(wù)器和客戶端通過分析“消息類別”來采取不同的方法處理發(fā)送的數(shù)據(jù)。</p><p> 通過這次課程設(shè)計,加深了我對Java網(wǎng)絡(luò)編程和多線程編程方面的了解。網(wǎng)絡(luò)五子棋基本實現(xiàn)了網(wǎng)絡(luò)對戰(zhàn)的功能,但只能通過網(wǎng)絡(luò),沒
93、有實現(xiàn)人機對戰(zhàn)的功能。也沒有添加“禁手”規(guī)則。這時是已后要改進的地方。</p><p><b> 謝辭</b></p><p> 二周的課程設(shè)計很快就過去了,首先要感謝xx老師的細心的指導。對我能準時完成任務(wù)有很大的幫助。王xx嚴謹?shù)闹笇B(tài)度與深厚的理論知識都讓我受益非淺,從他身上我學到了很多的東西,無論是理論還是實踐都使我的知識有很大的提高.借此我特提出感謝。還
94、要感謝同學在課程設(shè)計期間對我的幫助,最后要感謝互聯(lián)網(wǎng),有很多問題,通過搜索很快就得到解決的方法。</p><p><b> 參考文獻</b></p><p> 丁振凡 . Java語言實用教程[M]. 北京郵電大學出版社. 2006.9</p><p> 宛延闿 . 實用Java語言程序設(shè)計教程習題解答與上機實踐[M]. 機械工業(yè)出版社.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- java課程設(shè)計--五子棋
- 五子棋java課程設(shè)計
- 五子棋java課程設(shè)計
- java課程設(shè)計--五子棋游戲
- java課程設(shè)計--對戰(zhàn)五子棋
- java課程設(shè)計-五子棋游戲
- java課程設(shè)計報告-五子棋
- java課程設(shè)計--人機對弈五子棋
- 五子棋java語言課程設(shè)計報告
- java課程設(shè)計報告---java 五子棋游戲設(shè)計
- 五子棋課程設(shè)計
- java課程設(shè)計五子棋(附源代碼)
- java_五子棋小游戲課程設(shè)計
- 五子棋-課程設(shè)計報告
- java課程設(shè)計報告---單機版五子棋
- 面向?qū)ο蟪绦蛟O(shè)計---五子棋-java課程設(shè)計
- 五子棋c++課程設(shè)計
- 五子棋c++課程設(shè)計
- 五子棋小游戲課程設(shè)計
- 《java程序設(shè)計》課程設(shè)計-五子棋小游戲
評論
0/150
提交評論