(完整版)java五子棋畢業(yè)課程設(shè)計(jì).doc_第1頁
(完整版)java五子棋畢業(yè)課程設(shè)計(jì).doc_第2頁
(完整版)java五子棋畢業(yè)課程設(shè)計(jì).doc_第3頁
(完整版)java五子棋畢業(yè)課程設(shè)計(jì).doc_第4頁
(完整版)java五子棋畢業(yè)課程設(shè)計(jì).doc_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、目錄1緒論.11.1課程設(shè)計(jì)意義 .11.2課設(shè)目的 .11.3課設(shè)要求 .12網(wǎng)絡(luò)五子棋介紹 .22.1網(wǎng)絡(luò)五子棋介紹 .22.2游戲玩法 .23系統(tǒng)整體設(shè)計(jì) .33.1整體設(shè)計(jì) .33.2系統(tǒng)流程圖 .44原理分析 .54.1服務(wù)器和客戶端通信機(jī)制 .54.2多線程機(jī)制 .75服務(wù)器的設(shè)計(jì)與實(shí)現(xiàn) .85.1服務(wù)器監(jiān)聽 .85.2傳遞信息 .96客戶端設(shè)計(jì)與實(shí)現(xiàn) .106.1客戶端界面設(shè)計(jì) .116.1.1GUI 圖形界面設(shè)計(jì) .126.1.2注冊監(jiān)聽者 .136.2連接服務(wù)器 .146.3傳遞信息 .146.4棋盤數(shù)據(jù)結(jié)構(gòu) .156.5判斷輸贏算法 .166.6背景音樂 .177設(shè)計(jì)實(shí)現(xiàn)

2、.188總結(jié).20謝辭 .21參考文獻(xiàn).211 緒論1.1課程設(shè)計(jì)意義五子棋是起源于中國古代的傳統(tǒng)黑白棋種之一。五子棋不僅能增強(qiáng)思維能力,提高智力,而且富含哲理,有助于修身養(yǎng)性。經(jīng)過一個學(xué)期的學(xué)習(xí),使我對Java 有了一定的了解。但要深入理解Java 語言,單靠上課是不夠的。必須通過課程設(shè)計(jì),設(shè)計(jì)一個比較大的程序,才能更深一步地理解Java 語言。在這次課程中, 我選擇了網(wǎng)絡(luò)五子棋作為課題。編寫網(wǎng)絡(luò)五子棋游戲要利用到Socket網(wǎng)絡(luò)編程技術(shù)和多線程。通過這次課程設(shè)計(jì), 熟悉 Java 的 GUI 圖形界面設(shè)計(jì), 網(wǎng)絡(luò) Socket 編程和多線程編程。1.2課設(shè)目的通過課程設(shè)計(jì),使學(xué)生理論聯(lián)系實(shí)

3、際,在程序設(shè)計(jì)實(shí)踐中進(jìn)一步了解JAVA 程序設(shè)計(jì)方法掌握類和對象的基本編程方法,熟悉GUI 圖形界面編程技術(shù),初步了解Socket編程方法。1.3課設(shè)要求通過課程設(shè)計(jì)完成一個網(wǎng)絡(luò)五子棋游戲。由服務(wù)器和客戶端組成。在Internet 中不同用戶使用客戶端通過服務(wù)器與其它玩家連接。進(jìn)行五子棋網(wǎng)絡(luò)對戰(zhàn)或聊天。程序中要實(shí)現(xiàn) GUI 圖形界面的棋盤、黑子、白子功能 ,設(shè)計(jì)棋局存儲數(shù)據(jù)結(jié)構(gòu) , 實(shí)現(xiàn)開始、重來、退出等基本功能 , 實(shí)現(xiàn)輸贏自動判別算法 , 實(shí)現(xiàn)網(wǎng)絡(luò)對戰(zhàn)功能 , 背景音樂播放功能等。2 網(wǎng)絡(luò)五子棋介紹2.1網(wǎng)絡(luò)五子棋介紹五子棋是起源于中國古代的傳統(tǒng)黑白棋種之一。五子棋不僅能增強(qiáng)思維能力,提高

4、智力,而且富含哲理,有助于修身養(yǎng)性。五子棋既有現(xiàn)代休閑的明顯特征 “短、平、快 ”,又有古典哲學(xué)的高深學(xué)問“陰陽易理 ”;它既有簡單易學(xué)的特性,為人民群眾所喜聞樂見,又有深奧的技巧和高水平的國際性比賽;它的棋文化源遠(yuǎn)流長,具有東方的神秘和西方的直觀;既有“場 ”的概念,亦有 “點(diǎn)”的連接。它是中西文化的交流點(diǎn),是古今哲理的結(jié)晶。網(wǎng)絡(luò)五子棋是一般五子棋的網(wǎng)絡(luò)版,沒有加入人機(jī)對戰(zhàn)功能。本軟件使兩個不同計(jì)算機(jī)的使用者通過一定的網(wǎng)絡(luò)連接,達(dá)到兩人對戰(zhàn)的功能。首先運(yùn)行服務(wù)器監(jiān)聽客戶端連接請求。運(yùn)行客戶端與服務(wù)器相連,若連接成功,則進(jìn)入游戲。選擇房間,一個房間最多兩個人,人滿后,雙方可以開始游戲。2.2游

5、戲玩法網(wǎng)絡(luò)五子棋規(guī)則: 棋盤采用 15 條橫線 15 條堅(jiān)線組成交叉的每個點(diǎn)都可以放棋。本游戲至少需要二個客戶端才能進(jìn)行游戲??蛻舳伺c服務(wù)器連接成功后,進(jìn)入游戲大廳 (房間號為 0),選擇一個大于 0 的房間號,如果該房間未滿,即小于兩個人,則可進(jìn)入。點(diǎn)“游戲開始” ,處于等待狀態(tài)。如果對方也點(diǎn)擊了 “游戲開始”。雙方就可以在網(wǎng)上進(jìn)行對戰(zhàn)了。在對戰(zhàn)的同時還可以聊天,可以在同一房間內(nèi)私聊,也可以發(fā)送消息給所有在線的用戶。游戲分黑白兩方,每局由規(guī)定黑方先行。黑方玩家移動鼠標(biāo)在棋盤中點(diǎn)擊行棋。當(dāng)黑方行棋完畢,轉(zhuǎn)由白方行棋。同色棋子在棋盤上形成橫、豎、斜形成“五子相連”則獲勝。如果棄權(quán),則判為輸。3

6、系統(tǒng)整體設(shè)計(jì)3.1整體設(shè)計(jì)網(wǎng)絡(luò)五子棋是采用網(wǎng)絡(luò)協(xié)議為TCPIP 的網(wǎng)上對弈游戲, 運(yùn)用“客戶端服務(wù)器“ (cs)網(wǎng)絡(luò)架構(gòu)模式。實(shí)現(xiàn)用戶通過Internt 連接在任何地方與不同玩家進(jìn)行對戰(zhàn)。服務(wù)器可以創(chuàng)建任意多局游戲。通過使用多線程和網(wǎng)絡(luò)套接字SOCKET 來實(shí)現(xiàn)游戲之間的通訊,它是基于點(diǎn)對點(diǎn)的通訊。開始讓服務(wù)器初始化建立服務(wù)器套接字SOCKET ,基于某個端口 PORT ,服務(wù)器始終處于監(jiān)聽狀態(tài)。 客戶端是動作的發(fā)起者,何時發(fā)出申請由客戶端決定。 客戶端向服務(wù)器發(fā)出申請, 服務(wù)器給予響應(yīng)。打開客戶端套接字SOCKET ,連接到服務(wù)器端的地址ADDRESS 和端口PORT 。連接建立后,創(chuàng)建一個

7、SOCKET 實(shí)例,并開始一個線程,監(jiān)聽該客戶端請求。服務(wù)器繼續(xù)監(jiān)聽其它用戶的連接。服務(wù)器通過數(shù)據(jù)輸入流從客戶端接收信息,并且通過數(shù)據(jù)輸出流把相應(yīng)的信息發(fā)送給客戶端??蛻舳税l(fā)送請求和響應(yīng)接收到的各種信息。在服務(wù)器和客戶端之間傳遞的消息格式是采用 “ 消息類別 +內(nèi)容“組成的,服務(wù)器和客戶端在傳遞消息的過程,根據(jù)消息的類別來進(jìn)行相關(guān)的操作。比如要發(fā)送聊天信息,則在客戶端發(fā)送的過程中,自動加上MSG在要發(fā)送的消息前面,服務(wù)器接收到客戶端發(fā)來的消息,用 startsWith() 的方法來讀取消息頭部,如果等于” MSG “,進(jìn)行一步判定是為群聊還是私聊,分別調(diào)用不同的方法向客戶端發(fā)送聊天內(nèi)容。圖 3

8、13.2系統(tǒng)流程圖服務(wù)器流程圖:圖1 2圖 32客戶端流程圖:圖3 3圖 334 原理分析4.1服務(wù)器和客戶端通信機(jī)制Socket 是面向客戶服務(wù)器模型設(shè)計(jì)的,網(wǎng)絡(luò)上的兩個程序通過一個雙向的通訊連接實(shí)現(xiàn)數(shù)據(jù)的交換,這個雙向鏈路的一端稱為一個Socket。Socket通常用來實(shí)現(xiàn)客戶方和服務(wù)方的連接。客戶程序可以向Socket寫請求,服務(wù)器將處理此請求,然后通過Socket將結(jié)果返回給用戶。在 java 中使用套接字相當(dāng)簡單, Java API 為處理套接字的通信提供了一個類 .Socket。使得編寫網(wǎng)絡(luò)應(yīng)用程序相對容易。 JAVA 支持流套接字( stream socket)和數(shù)據(jù)報(bào)套接字(

9、datagram socket)。流套接字使用TCP ( Transmission Control Protocol,傳輸控制協(xié)議)進(jìn)行數(shù)據(jù)傳輸,而數(shù)據(jù)報(bào)套接字使用UDP( User Datagram Protocol,用戶數(shù)據(jù)報(bào)協(xié)議) 。服務(wù)器主機(jī)客戶端ServerSocket (port)accept()(1) 等待連接Socket (主機(jī), port)(3)建立 Socket(2) 請求連接(3)建立 Socket連接成功InputStreamInputStreamOutputStreamOutputStream(4)傳送數(shù)據(jù)(5)關(guān)閉連接(5)關(guān)閉連接Socket 通信圖 41在 Ja

10、va 中 Socket可以理解為客戶端或者服務(wù)器端的一個特殊的對象,這個對象有兩個關(guān)鍵的方法,一個是getInputStream 方法,另一個是getOutputStream 方法。 getInputStream 方法可以得到一個輸入流,客戶端的 Socket 對象上的 getInputStream 方法得到的輸入流其實(shí)就是從服務(wù)器端發(fā)回的數(shù)據(jù)流。 GetOutputStream 方法得到一個輸出流, 客戶端 Socket對象上的 getOutputStream 方法返回的輸出流就是將要發(fā)送到服務(wù)器端的數(shù)據(jù)流,(其實(shí)是一個緩沖區(qū),暫時存儲將要發(fā)送過去的數(shù)據(jù))??蛻舳藛右院螅c服務(wù)器連接,服務(wù)

11、器會啟動一個線程來與客戶進(jìn)行文字交流。要完成這個工作,需要完成三個部分的工作:Java 中有一個專門用來建立Socket 服務(wù)器的類,名叫ServerSocket,可以用服務(wù)器需要使用的端口號作為參數(shù)來創(chuàng)建服務(wù)器對象。ServerSocket server=new ServerSocket(8888);這條語句創(chuàng)建了一個服務(wù)器對象,這個服務(wù)器使用8888 號端口。當(dāng)一個客戶端程序建立一個 Socket連接,所連接的端口號為 8888 時,服務(wù)器對象 server 便響應(yīng)這個連接,并且 server.accept()方法會創(chuàng)建一個 Socket對象。服務(wù)器端便可以利用這個Socket對象與客戶進(jìn)

12、行通訊。Socket socket=server.accept();進(jìn)而得到輸入流和輸出流,并進(jìn)行封裝。reader=newBufferedReader(newInputStreamReader(socket.getInputStream();writer = new PrintWriter(socket.getOutputStream(), true);隨后,就可以使用reader.readLine()方法得到客戶端的輸入,也可以使用 writer.println() 方法向客戶端發(fā)送數(shù)據(jù)。從而可以根據(jù)程序的需要對客戶端的不同請求進(jìn)行回應(yīng)。在所有通訊結(jié)束以后應(yīng)該關(guān)閉這兩個數(shù)據(jù)流,關(guān)閉的順序是

13、先關(guān)閉輸出流,再關(guān)閉輸入流,即使用reader.close();writer.close();相比服務(wù)器端,客戶端要簡單一些,客戶端只需用服務(wù)器所在機(jī)器的ip 以及服務(wù)器的端口作為參數(shù)創(chuàng)建一個Socket對象。得到這個對象后, 就可以用 建立服務(wù)器 部分介紹的方法實(shí)現(xiàn)數(shù)據(jù)的輸入和輸出。socket=new Socket(127.0.0.1, 8888);reader=newBufferedReader(newInputStreamReader(socket.getInputStream();writer=new PrintWriter(socket.getOutputStream(), tru

14、e);以上的程序代碼建立了一個socket 對象,這個對象連接到ip 地址為127.0.0.1(本機(jī) IP 地址,為了驗(yàn)證方便)的主機(jī)、端口為8888 的服務(wù)器對象。并且建立了輸入流和輸出流,分別對應(yīng)服務(wù)器的輸出和客戶端的寫入。4.2多線程機(jī)制多線程機(jī)制是指單個程序可以運(yùn)行多個不同的線程,執(zhí)行不同的任務(wù)。因?yàn)榫€程只能在單個進(jìn)程的作用域內(nèi)活動,所以創(chuàng)建線程比創(chuàng)建進(jìn)程要廉價得多,同一類線程共享代碼和數(shù)據(jù)空間,每個線程有獨(dú)立的運(yùn)行桟和程序計(jì)數(shù)器( PC),線程切換的開銷小。因此多線程編程在現(xiàn)代軟件設(shè)計(jì)中在量采用。創(chuàng)建新線程必須編寫一個線程類,用 Java 編寫多線程代碼有兩種方式直接繼承 Java

15、的線程類 Thread ;實(shí)現(xiàn) Runnable 接口無論采用哪種方式均需要在程序中編寫 Run() 方法,線程在運(yùn)行時要完成的任務(wù)在該方法實(shí)現(xiàn)。 Thread 類封裝了線程的行為。 繼承 Thread 類須重寫 run() 方法實(shí)現(xiàn)各自的任務(wù)。 程序中不要直接調(diào)用線程的 run()方法,而是調(diào)用 start()方法啟動線程,讓其進(jìn)入可調(diào)度的狀態(tài),線程獲得調(diào)度時將自動執(zhí)行 run()方法。由于 Java 的單重繼承的限制,有些類必須繼承其它個類時又要實(shí)現(xiàn)線程的特性。這時可通過實(shí)現(xiàn)Runnable 接口的方式來滿足兩方面的要求。Runnable 接口只有一個方法run() ,它就是線程運(yùn)行時要執(zhí)

16、行的方法,只要將具體代碼寫入其中即可。線程在調(diào)度時將自動調(diào)用Runnable 接口對象的 run 方法。多線程是 Java 的一個特點(diǎn),多線程可以使程序反應(yīng)更快、 交互性更強(qiáng),并能提高執(zhí)行效率。在網(wǎng)絡(luò)五子中如果服務(wù)器是單線程的,則只能與一個客戶端相連,就失去了網(wǎng)絡(luò)對戰(zhàn)的意義了。所以應(yīng)該采用多線程方式。當(dāng)服務(wù)器與一個客戶端建立連接,就開啟一個線程與之相連,同時監(jiān)聽其它用戶的連接。5 服務(wù)器的設(shè)計(jì)與實(shí)現(xiàn)網(wǎng)絡(luò)五子棋游戲服務(wù)器端主要由以下幾部分組成:圖51監(jiān)聽連接服務(wù)器端向客戶端發(fā)送信息接收客戶端信息圖 51網(wǎng)絡(luò)五子棋游戲服務(wù)器端主要有三個類:Server 類、five_ Thread 類(線程類)和

17、BManager 類(消息廣播者) 。服務(wù)器端主要通過建立流連接來連接客戶端。服務(wù)器建立與一個客戶端連接,就開始一個線程,并同時監(jiān)聽其它客戶端的連接。服務(wù)器接收一客戶端的信息,接收信息后按照此客戶端的要求將信息發(fā)送到相應(yīng)的客戶端,端起到了中介服務(wù)器的作用。為了更清楚地了解客戶端的登陸情況,將服務(wù)器設(shè)計(jì)成圖形界面。創(chuàng)建成一個可以顯示游戲信息的框架。在框架中創(chuàng)建一個包含文本區(qū)的滾動窗格,并在文本區(qū)顯示游戲信息。圖 525.1服務(wù)器監(jiān)聽首先創(chuàng)建一個服務(wù)器對象, 并把它附加到 8888 號端口上,服務(wù)通過這個端口來監(jiān)聽客戶端的連接請求。 通過服務(wù)器對象的 accept方法來創(chuàng)建一個 Socket對象并

18、使其與客戶機(jī)連接,就開啟一個線程處理客戶之間數(shù)據(jù),同時繼續(xù)監(jiān)聽其它客戶端的連接請求。并將線程添加至 BManager 對象 bMan 中。ServerSocket server=new ServerSocket(8888);Socket socket=server.accept();five_Threadthread=new five_Thread(socket);建立一線程thread.start();啟動線程bMan.add(thread); 線程添加至 BManager 對象5.2傳遞信息當(dāng)于客戶端建立連接后,就建立輸入輸出流,由于消息的發(fā)送和接收。reader=newBufferedR

19、eader(newInputStreamReader(socket.getInputStream();writer = new PrintWriter(socket.getOutputStream(), true);five_Thread 對象不僅可以獲取套接字、輸入輸出流,而且它還提供了有關(guān)客戶機(jī)的消息。例如客戶機(jī)的姓名、房間號、游戲開始與否等。這是因?yàn)槲覀冃枰_定消息的來源及主要在某個房間傳播的消息。并且,消息廣播者也需要參照線程對象的房間號,以便將消息發(fā)送至某個房間中。BManager 類繼承了 Vector 類,它的元素為 five_ Thread 線程對象,這樣可以更容易用BMana

20、ger 的對象來管理線程對象,如添加、刪除、返回線程對象。BManager 可以自由地參照five_Thread 對象的房間號和玩家的名字,這樣能向指定的房間發(fā)送消息和用戶名字。需要比較Bmanager各元素的房間號和給定的房間號,若兩者相同,則向此房間發(fā)送消息。服務(wù)器和客戶端之間的交流主要是相同的房間號之間的用戶進(jìn)行。如發(fā)送聊天消息,棋子信息,贏輸消息的傳送。sendToAll(String msg)方法向所有用戶發(fā)送消息,主要是發(fā)送群聊消息。因?yàn)橄⒌陌l(fā)送主要在相同的房間號中時行,要發(fā)送群聊消息,即所有房間的用戶都能招收到。在輸入聊天信息前加a。表示向所有人發(fā)送。SendToRoom(fi

21、ve_Thread thread, String msg)方法用于向指定的房間(roomnum)發(fā)送消息 (msg)。房間內(nèi)的兩個用戶都能接收到消息。主要用于發(fā)送發(fā)私聊信息。sendTothreadhers(five_Thread thread, String msg)方法用于向與消息發(fā)送者處于同一房間的用戶發(fā)送各種命令。比如發(fā)送在 1 號房間的一個用戶發(fā)來“ WIN “,服務(wù)器向 1 號房間的另一個用戶發(fā)送 LOSE 。實(shí)現(xiàn)原理:使用 for 循環(huán)檢查元素(線程)的房間號。用 getRoomNumber()得到發(fā)送信息的線程的房間號, 當(dāng)房間號相等時, 則調(diào)用 sendTo(i, msg)方

22、法向第 i 個房間發(fā)送消息。但并不向 thread 連接的客戶機(jī)發(fā)送消息。服務(wù)器在 five_Thread 類中重寫 run()方法,由于處理在與客戶端連接過程中的數(shù)據(jù)傳輸,處理和控制。消息傳遞格式“消息類別 +內(nèi)容“?!?ROOM2 “表示客戶端請求進(jìn)入第二號房間。 服務(wù)器判斷 2 號房間是否為滿,如果不為滿,則向客戶端發(fā)送“ ROOM2 ”,表示可以進(jìn)入,并發(fā)送 ROOM2 中的其它用戶名字。如果人數(shù)已滿,則發(fā)送 FULL 。表示房間已滿,無法進(jìn)入。“ NAME “表示進(jìn)入游戲大廳的用戶名字?!?START “表示客戶端要求開始游戲,如果對方也要求游戲,則游戲開始。服務(wù)器發(fā)送 COLORW

23、RITE 和COLORBLACK 表示棋子顏色分別給兩個客戶端。“ DROPGAME ”表示放棄正在進(jìn)行中的游戲。服務(wù)器發(fā)送 “ DROPGAME “給相同房間中的另一用戶。6 客戶端設(shè)計(jì)與實(shí)現(xiàn)客戶端負(fù)責(zé)與用戶之間的交互。包括棋盤類OmokBoard 類和 Client類。 OmokBoard 類繼承了 JPanel 類,它主要用于棋盤的繪制和監(jiān)聽鼠標(biāo)事件,獲得棋子坐標(biāo)和繪制棋子。它必須擁有輸出流,用以向?qū)κ謧鬟f棋手的下棋信息。主要的方法有:putOpponent ()在客戶端顯示對方棋子,保持雙方棋子的一致性。check()判斷一方向上同色棋子個數(shù)。drawStones()繪制棋子。draw

24、Board() 調(diào)用不同的方法,分析實(shí)現(xiàn)棋盤、棋子、提示信息的顯示。isRunning()標(biāo)記游戲運(yùn)行狀態(tài)。reset()清空棋盤,在游戲結(jié)果后運(yùn)行。Client 類,繼承 JFrame 類和實(shí)現(xiàn) Runnable 接口。主要由于界面初始化和注冊事件監(jiān)聽者。主要方法:Run()方法覆蓋 Runnable 接口里的 run ()方法,用以對游戲過程中的數(shù)據(jù)傳輸,處理,控制。actionPerformed(ActionEvent ae)實(shí)現(xiàn)點(diǎn)擊菜單、 按鈕、文本框回車事件的具體代碼。Connect()與服務(wù)器連接。endgame()結(jié)束游戲。playersInfo()顯示用戶位置信息,是在游戲大廳

25、中,還是在房間里。goToWaitRoom()從房間里退出,進(jìn)入游戲大廳。網(wǎng)絡(luò)五子棋客戶端主要由以下幾部分組成:圖61連接運(yùn)程服務(wù)器發(fā)送信息接收消息客戶端實(shí)時更新棋盤截取鼠標(biāo)動作判斷輸贏音樂播放圖 616.1客戶端界面設(shè)計(jì)圖 626.1.1GUI 圖形界面設(shè)計(jì)五子棋客戶端界面本軟件的的客戶端的界面如圖6-2 所示,主要應(yīng)用SWING的組件來實(shí)現(xiàn)。界面由菜單、按鈕、文本框、各種對話框、棋盤和黑白棋子等組成。客戶端中的按鈕、文本框、 標(biāo)簽等 GUI 部件都是布置在面板JPanel 上的,其中還包括將一塊面板入在另一塊面板中。這樣能實(shí)現(xiàn)比較復(fù)雜的布局。多個不同的 GUI 部件放在面板上時, 還要設(shè)置

26、它們的布局方式。 這里采用了網(wǎng)絡(luò)布局 (GridLayout) 和方位布局 (BorderLayout)。最后將各個面板JPanel 添加到窗體 JFrame 中。菜單包括游戲、音樂、和幫助菜單項(xiàng)。首先創(chuàng)建一個菜單條(MenuBar)jmb,然后創(chuàng)建不同的菜單項(xiàng) (Menu) 加入到菜單條中。JMenu sound = new JMenu(音樂 );jmb.add(sound);最后創(chuàng)建菜單子項(xiàng) (MenuItem) 加入菜單項(xiàng),比如給“音樂”菜單項(xiàng)添加“播放”菜單子項(xiàng):JMenuItem play = new JMenuItem( 播放 );Sound.add(play);棋盤的繪制。五子棋

27、盤(OmokBoard 類),五子棋盤繼承了JPanel,它內(nèi)嵌于框架窗口中棋盤的大小采用15*15 個方格。每個交叉點(diǎn)處可放置棋子。private void drawLine()gbuff.setColor(Color.BLACK);for(int i=1; i=size;i+) gbuff.drawLine(cell, i*cell, cell*size, i*cell);gbuff.drawLine(i*cell, cell, i*cell , cell*size);當(dāng)一個用戶放下一個棋子后,同一房間里的兩個用戶的棋盤都要重畫,以顯示自己和對方下的棋子等信息。棋子的繪制。用白色繪制一個圓

28、形的邊框,將填充黑色,這樣就畫好了一個黑色棋。位置要根據(jù)獲得的鼠標(biāo)點(diǎn)擊的坐標(biāo)和棋盤的大小來定。private void drawBlack(int x, int y)繪制黑棋Graphics2D gbuff=(Graphics2D)this.gbuff; gbuff.setColor(Color.black); gbuff.fillOval(x*cell-cell2, y*cell-cell2, cell, cell); gbuff.setColor(Color.red);gbuff.drawOval(x*cell-cell2, y*cell-cell2, cell, cell);邊框6.1.

29、2注冊監(jiān)聽者圖形用戶界面的每個可能產(chǎn)生事件的組件稱為事件源, 希望事件源上發(fā)生的事件被程序處理, 就要把事件源注冊給能夠處理該事件源上事件的監(jiān)聽者。事件源注冊 :btn.addActionListerner(監(jiān)聽者對象)觸發(fā)事件ActionEvent 事件監(jiān)聽者實(shí)現(xiàn)接口public void actionPerformed(ActionEvent e)圖 63在這里按鈕,菜單,和發(fā)送消息的文本框都是事件源。要想按鈕或菜單發(fā)生事件時, 程序能處理,必須注冊監(jiān)聽者。 按鈕動作事件 ActionEvent 的 監(jiān) 聽 者 接 口 為 ActionListener , 給 按 鈕 注 冊 監(jiān) 聽 者

30、的 方 法 為addActionListener()。sendBox.addActionListener(this);文本框按回車鍵enterButton.addActionListener(this);exitButton.addActionListener(this);在 actionPerformed(ActionEvent ae)中編寫上體的事件處理代碼。在發(fā)生事件時事件源將給其注冊的所有監(jiān)聽者對象的發(fā)送消息,實(shí)際上就是調(diào)用監(jiān)聽者對象的 actionPerformed()方法,從而完成事件的處理。通過getSource()方法:用來獲取事件源對象。 處理不同的事件。 如處理單擊 “音樂

31、播放”菜單和“游戲開始”引起的事件的actionPerfrmed()方法。public void actionPerformed(ActionEvent ae)播放音樂 if(ae.getSource()=play)Object selection = fi.MID,five.mid;Object set = JOptionPane.showInputDialog(null, 選擇音樂 ., 播放 .,JOptionPane.QUESTION_MESSAGE,null,selection,selecton0);music=new Sound(set.toString();music.play(

32、);else if(ae.getSource()=startButton)trywriter.println(START); 發(fā)送開始信息infoView.setText(等待對方?jīng)Q定 .);startButton.setEnabled(false);catch(Exception e)進(jìn)行五子棋游戲的一個重要的內(nèi)容是獲取鼠標(biāo)點(diǎn)擊時在棋盤中的坐標(biāo),即落下棋子的位置。addMouseListener(new MouseAdapter()public void mousePressed(MouseEvent me)if(!enable)return;是否輪到下棋int x=(int)Math.ro

33、und(me.getX()(double)cell);得到鼠標(biāo)坐標(biāo)int y=(int)Math.round(me.getY()(double)cell);坐標(biāo)要求不超過棋盤大小,在坐標(biāo)上不存在棋子if(x=0 | y=0 | x=size+1 | y=size+1)return;if(mapxy=BLACK | mapxy=WHITE)return;writer.println(STONE+x+ +y);向服務(wù)器發(fā)送棋子信息6.2連接服務(wù)器客戶端連接服務(wù)器, 首先用服務(wù)器所在機(jī)器的ip 以及服務(wù)器的端口作為參數(shù)創(chuàng)建一個Socket對象??蛻舳苏{(diào)用connect()方法進(jìn)行連接。Sockets

34、ocket=new Socket(127.0.0.1, 8888);這里以本機(jī)地址127.0.0.1 為 IP 地址,是為了方便服務(wù)器和客戶端運(yùn)行在同一臺機(jī)器上做實(shí)驗(yàn)。 客戶端一開始運(yùn)行, 便連接 IP127.0.0.1 主機(jī)的 8888號端口如果連接成功, 則在 TextArea 對象 msgViewk 中顯示成功消息。 否則顯示連接錯誤的消息。6.3傳遞信息客戶端之間的信息傳遞,比如發(fā)送開始游戲,聊天都要通過先經(jīng)過服務(wù)器發(fā)送。服務(wù)器接收到客戶端發(fā)送的各種消息,識別不同消息的類別,采用不同的方法進(jìn)行處理。當(dāng)建立與服務(wù)器的連接后,客戶端通過數(shù)據(jù)輸出流發(fā)送相應(yīng)的請求給服務(wù)器,并且通過數(shù)據(jù)輸入流從

35、服務(wù)器端接收信息??蛻舳送ㄟ^開啟一個線程,處理與服務(wù)器之間的數(shù)據(jù)。reader=newBufferedReader(newInputStreamReader(socket.getInputStream();writer=newPrintWriter(socket.getOutputStream(), true);new Thread(this).start();開始一個將調(diào)用這個runnable的 run() 方法的線程Java 運(yùn)行系統(tǒng)調(diào)用這個方法 run() 來執(zhí)行線程。在 Client 類中,繼承了 JFrame 類,由于 Java 的單繼承性, Client 類就不能再繼承 Threa

36、d,但可以實(shí)現(xiàn) runnable接口,通過覆蓋 Runnable 接口里的 run () 方法,用以對游戲過程中的數(shù)據(jù)傳輸,處理,控制。客戶端與服務(wù)器之間傳遞的信息, 都是由 “ 消息種類 +內(nèi)容“組成的,服務(wù)器接收到來客戶端的消息,分析” 消息種類 “中的內(nèi)容,進(jìn)行相關(guān)的操作。下面對各種消息的種類作一個介紹。NAME 當(dāng)用戶在客戶登陸時,發(fā)送給服務(wù)器,用于顯示登陸用戶名字。 ROOM 當(dāng)用戶登陸上時, ROOM 號為 0,記為“游戲大廳” ,選擇房間的用戶在“游戲大廳“, 房間號為大于 0 的整數(shù),一個房間最多容納 2 人,即對戰(zhàn)的雙方。當(dāng)服務(wù)器端接收到查看 ROOM 房間號人數(shù)是否為滿。不

37、為滿,則發(fā)送 ”ROOM+n ”,給客戶端,表示可以進(jìn)入。否則發(fā)送“FULL ”。 PLAYERS 在客戶端顯示相同房間用戶列表。DISCONNECT 表示對方斷線。COLOR 得到棋子顏色。 COLORBLACK表示黑棋。WIN 表示獲勝。LOSE 表示失敗。EXIT 表示對方離開房間。ENTER 顯示相同房間中登陸的用戶。STONE 表示對方下棋棋子的坐標(biāo)。MSG 表示聊天的信息,只在相同的房間內(nèi)可見。如果要想讓所有的登陸的用戶都能收到聊天信息,則消息種類為 ”MSGa ”6.4棋盤數(shù)據(jù)結(jié)構(gòu)棋盤設(shè)置成有15*15 個方格。定義了一個二維數(shù)組Map 用于保存棋子在棋盤中的位置。在程序中用常數(shù)

38、1 表 BLACK( 黑棋 ),用 1 表示W(wǎng)RITE( 白棋 ),用 0 表示在此位置上無棋子。 如在 (3,3)位置上有一個黑棋。則 Map33 的值為 1。public static final int BLACK=1, WHITE=-1; 顏色標(biāo)識值private int map;Map 是一個二元數(shù)組,用于保存棋子的位置6.5判斷輸贏算法輸贏的判斷是網(wǎng)絡(luò)五子棋游戲中一個很重要的部分。當(dāng)雙方每放下一個棋子的時候,程序都要進(jìn)行判斷是否已經(jīng)產(chǎn)生了輸贏。如果是,則停止游戲,并發(fā)送結(jié)果給服務(wù)器,服務(wù)器再發(fā)送結(jié)果給對方。橫,豎或者對角線方向上擁有五顆同樣的棋子時,即為勝利。五子相連判斷當(dāng)在棋盤中

39、放入一個棋子時,比如白色。程序要計(jì)算它左邊連在一起的白色棋子的個數(shù),然后計(jì)算右邊與它相連在一起的白色棋子的個數(shù)。再將兩數(shù)相加,如果為四,與自己加起來剛好為五。則白棋獲勝。用同樣的方法在垂直和對角線方向進(jìn)行判斷同色棋子個數(shù)。如果獲勝,則客戶端發(fā)送 WIN 給服務(wù)器,否則由對方下棋,并重復(fù)進(jìn)行相同的運(yùn)算。count()方法用來查找并計(jì)算連在一起的棋子的個數(shù)。P 為基準(zhǔn)坐標(biāo),dx、dy 分別為表示橫向于豎向的變量。col 代表棋子顏色。弱dx 為-1,dy為 0,則計(jì)算左邊連續(xù)棋子的個數(shù);若dx 為 1,dy 為1,則計(jì)算左下到右上連續(xù)棋子的個數(shù)。 dx 與 dy 只取 -1、 0、1 三個值之一。

40、下面是count()方法的代碼。private int count(Point p, int dx, int dy, int col)int i=0;for(; mapp.x+(i+1)*dxp.y+(i+1)*dy=col ;i+); return i;用 check()方法調(diào)用 count()方法,分別在橫、豎和對角線方向上計(jì)算相連同色棋子的個數(shù)。private boolean check(Point p, int col)if(count(p, 1, 0, col)+count(p, -1, 0, col)=4)橫向檢查 return true;if(count(p, 0, 1, col)+count(p, 0, -1, col)=4)豎向檢查 return true;if(count(p, -1, -1, col)+count(p, 1, 1, col)=4)對角線方向檢查 return true;if(count(p, 1, -1, col)+count(p, -1, 1, col)=4)對角線方向檢查 return true;return false;6.6背景音樂圖 64通過

溫馨提示

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

評論

0/150

提交評論