五子棋网络对战 java实现
五子棋網(wǎng)絡(luò)對戰(zhàn) java實現(xiàn)
最近期末考試,壓力實在是太大了。專業(yè)不對口的痛苦,別人永遠體會不來。閑暇之余,便想著鞏固一下java的基礎(chǔ)知識,以前看別人寫的游戲,心里都覺得哇 好厲害啊,我什么時候才可以寫出自己的游戲,當然我最想做的不是游戲,因為我感覺我只有欣賞美的能力,卻沒有制造美的能力。好了,廢話這么多,哎,我就是喜歡啰嗦。**
視頻傳送門:在線演示
**
游戲消息傳輸構(gòu)思:
? 首先呢,寫一個程序,最重要的就是構(gòu)思啦,那么首先想到的是網(wǎng)絡(luò)實現(xiàn)的方式,在這里我們可以用http協(xié)議去傳輸我們的數(shù)據(jù),也可以采用封裝的TCP/ip的socket去實現(xiàn)我們想要的功能,在網(wǎng)絡(luò)這個世界,一切皆socket,包括你熟知的http協(xié)議,瀏覽器與web服務(wù)器初次連接時就是用socket實現(xiàn)的,學(xué)過java的都知道Tomcat這個web服務(wù)器吧,那么這就好了,Tomcat給客戶端傳輸數(shù)據(jù)也是socket連接的,你也可以通過socket實現(xiàn)自己的web服務(wù)器了,好了,傳輸協(xié)議確定了,那么接下來就要考慮游戲構(gòu)思了
游戲構(gòu)思:
? 既然要寫網(wǎng)絡(luò)游戲嘛,那么肯定要有一個客戶端,一個服務(wù)端對吧。這是最典型的C/S(Client/Server),對于WEB而言的話,那么是B/S(Browser/Server).那么我們就選擇一個最簡單的C/S模型吧。
1. Server實現(xiàn)大致思路
? 然后呢,服務(wù)端接受客戶端的連接,然后保存每一個客戶端連接的socket對象,每連接一個客戶端,則開啟一個線程去讀當前客戶端消息的線程,然后定義我們游戲的消息頭,消息頭很重要,能夠微量防止不法連接。然后就是對消息體的一些處理邏輯了。到這里先不要考慮連接數(shù),實際上,這么寫是最笨的做法,想想,萬一有一萬個連接,難道就要開一萬個線程去讀每個socket客戶端的消息嗎?對于很大的連接數(shù),這里就不要考慮了,我們只追求基本功能能夠?qū)崿F(xiàn)即可,剛開始不要考慮那么多。你只要知道這是一個最簡單的游戲的制作過程
Server implements :(偽代碼)
class Server {static Map<Socket,String> Clients = new HashMap<>(Socket,String);ServerSocket serverSocket;main(){//監(jiān)聽本機6666端口serverSocket = new ServerSocket(6666)Client = serverSocket.accpet();//服務(wù)端開啟監(jiān)聽new HandleClient(Client).start();//啟動當前客戶端監(jiān)聽//連接上則添加到map列表,名字默認為空Clients.put(Client,"");} } class HandleClient extends Thread{Socket Client;BufferedReader br;//當前Socket的Reader對象BufferedWriter bw;//當前Socket的Wirter對象BufferedWriter otherbw //另一個玩家的writer對象HandleClient(Socket Client){this.Client = Client;}public void run(){bw = new BufferedWriter(new OutputStreamWriter(Client.getoutputStream());br= new BufferedReader(new OutputStreamReader(Client.getinputStream()); while(true){String msg = bf.readLine();String msgStr[] = msg.split(":");//定義消息頭,消息如果滿足消息頭if(msgStr[0].equals("MSGTYPE")){//。。。。消息解析處理過程//對消息體用“#” 切割 拿到消息的Key,如果當前消息是發(fā)來自己的名字 ,// 那么 就把這個連接添加到Serverif(msgStr[1].splint("#")[0].equals("MYNAME")){//更新改Socket玩家的姓名Server.Clients.put(Client,msgStr[1].splint("#")[1]); //接下來 的代碼就不寫了 直接看我的工程即可,服務(wù)端游戲思路大致就是這樣。就是這樣切割消息體來進入相應(yīng)的處理}}}} }思考:
? 這里為什么HandleClient類里我還寫了一個 《BufferedWriter otherbw //另一個玩家的writer對象》 這句代碼,你可能有所疑惑,為什么都有了一個bw,還要一個otherbw,但是你忘了嗎,我們要寫的五子棋是雙人對戰(zhàn)的,這里 這個服務(wù)器的當前線程,當有人加入到房間,或者是自己創(chuàng)建的房間,有人加入進來,拿Server的靜態(tài)對象Clients找到加入房間玩家的Socket,接著拿到輸出流,不就可以直接給他發(fā)消息了嗎?這里要好好想想了啊,這里是重點
1. Client實現(xiàn)大致思路
? 然后,客戶端實現(xiàn)過程當眼也很簡單了啊,直接建立一個Socket對象去連接服務(wù)端,然后發(fā)送相應(yīng)的消息體,服務(wù)端響應(yīng)后,返回給客戶端對應(yīng)的消息。這里我給大家舉一個完整的消息例子。
Client--------------->Server (連接成功)
BEGIN:
發(fā)送MyName--------->Server (保存到Server的Clients對象里)
發(fā)送創(chuàng)建房間---------->Server (向服務(wù)器發(fā)送一條創(chuàng)建房間的消息,服務(wù)器記錄當前玩家創(chuàng)建了房間,然后調(diào)用bw.write(“MSGTYPE:CreateRoomSuccess\r\n”))通知當前玩家建立房間成功
Gameing:
點擊棋盤,觸發(fā)監(jiān)聽器 ,發(fā)送落子坐標---------->Server(接受到當前玩家的落子坐標信息,轉(zhuǎn)發(fā)給另一個 玩家,怎么轉(zhuǎn)發(fā)呢?前面不是直接拿到了otherbw,那么這時候直接調(diào)用加入玩家的bw即可向?qū)Ψ桨l(fā)消息。)
Client implements :(偽代碼)
class Client{main(){new Room();} } class Room extends Jframe{static String MyName; //自己的名字static Socket socket;BufferedReader br;//當前Socket的Reader對象BufferedWriter bw;//當前Socket的Wirter對象BufferedWriter otherbw //另一個玩家的writer對象Jframe(){//MouseLister 實現(xiàn)監(jiān)聽鼠標點擊事件addMouseListener(new MouseListener{// 如果點擊到某個坐標是開始游戲if(x>=xxx&&x<=xxx&&y>=xxx&&y<=xxx){String name = JOptionPane.showInternalInputDialog(null,"請給你取一個個性的名字把!")if(socket==null){//這里的localhost默認是本機的地址 // 如果你的Hosts文件沒有定義localhost,那么改成 127.0.0.1socket = new Socket("localhost",6666);bw = new BufferedWriter(new OutputStreamWriter(Client.getoutputStream());br= new BufferedReader(new OutputStreamReader(Client.getinputStream()); }//進入游戲窗口new PlayGmae();//開啟線程讀取消息 ,為什么要開啟線程讀取消息?因為//readLine()方法是阻塞的,要是不開線程,那么主線 程就會卡了。new ReadMsg().start();}})} }//讀取消息 class ReadMsg extends Thread(){public void run(){while(true){String msg = br.readLine();String msgStr = msg.splint(":");if(msgStr[0].equals("MSGTYPE")){....//相關(guān)處理過程}} }// 實現(xiàn)相關(guān)界面class PlayGame extends Jframe{PlayGame(){//實現(xiàn)相關(guān)界面 addMouseListener(new MouseListener{//增加點擊 區(qū)域 消息監(jiān)聽 比如不同區(qū)域 有不同的功能啊// 開始游戲 棋盤 認輸 悔棋等等 都有自己的坐標信息啊。點擊執(zhí)行相關(guān)的功能// eg :當前區(qū)域 :認輸if(x>=xxx&&x<=xxx&&y>=xxx&&y<=xxx){int staus= JOptionPane.showInternalConfirmDialog(this, "確認要認輸嗎", );if(staus==0){bw.write("MSGTYPE:GAMEING#renshu");}});}}游戲截圖:
1. Server
Server我沒有寫界面直接啟動就好了,不過要想觀察后臺信息,在控制臺輸入 "java -jar Server.jar"即可
服務(wù)端后臺消息:
2.Client
直接雙擊打開即可,也可以在控制臺輸入 "java -jar Client.jar"即可觀察后臺信息
Begin:
取名字:
空房間列表:
創(chuàng)建的房間
有房間:
加入房間玩家:
開始游戲:
聊天內(nèi)容:
關(guān)于作者:
總結(jié):
好了,這就是游戲?qū)崿F(xiàn)的大致思路,感覺就是這么一步一步來的,這個游戲斷斷續(xù)續(xù),都怪考試太多了,哎,我寫了兩周才完成了所有功能…,一邊復(fù)習(xí),一邊考試。其實大多時間都再調(diào)試BUG,要么是點擊出問題,要么是創(chuàng)建房間加入出問題…各種問題,當然,要想實現(xiàn)自己想要的游戲,努力一下還是挺好的。到現(xiàn)在為止,游戲可以創(chuàng)建多個房間,如果游戲廳房間太多則多頁顯示,可以自由加入任何創(chuàng)建的房間
關(guān)于待補充的:
游戲還有 很多要完善的地方,比如 房間觀戰(zhàn),送?動畫特效,人機對戰(zhàn),哎,有時間我再完善,沒時間,這個小項目就到這里,新的2019,要繼續(xù)努力,送給每一個看到此篇文章的人,愿你們都能開心過好每一天。
1. My github address:
五子棋網(wǎng)路多人對戰(zhàn)(一定給個Star鼓勵下嘛)
我已經(jīng)把工程所有資源包括代碼都放到了github上了,不要忘記給我一個start呀
總結(jié)
以上是生活随笔為你收集整理的五子棋网络对战 java实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据分析师 2020-8-09笔试题目
- 下一篇: 第一章 数据仓库理论专题