mud 板


LINE

看板 mud  RSS
大家好! 歡迎收看從0開始的 MUD 開發第 3 集 在上一集我們已經實作了多執行緒的 telnet echo server 雖然我們的 server 可以支援複數使用者同時連線 但是使用者之間並沒有辦法互相溝通 所以這一集我們要講的是如何透過 java 內建的資料結構(HashMap)收集, 管理使用者 同時建立一個 PlayerManager, 藉由 PlayerManager 提供一個統一的操作介面 // PlayerManager.class // ✂--------------請沿虛線剪下-------------- package core; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; public class PlayerManager { // 宣告 static 的變數儲存 PlayerManager 的 instance // 這個寫法可以讓 PlayerManager 這個 class 被載入時, 立刻執行自己的建構子 private static PlayerManager instance = new PlayerManager(); // 用來儲存所有使用者的 Map private static Map<String, Player> players; // 重要! 一個 private 的建構子, 確保沒有其他程式可以 new PlayerManager() private PlayerManager() { players = new ConcurrentHashMap<>(); } // 一個 static 的 getInstance() 方法取代原有的建構子 // 原本常見的 PlayerManager pm = new PlayerManager(); // 寫法改為 PlayerManager pm = PlayerManager.getInstance(); public static PlayerManager getInstance() { return instance; } // 以下是真正提供給其他程式使用的方法 // 包括了新增、移除使用者的 addPlayer, removePlayer // 檢查使用者是否上線的 isPlayerOnline // 對所有使用者下指令的 forEach public void addPlayer(String name, Player player) { players.put(name, player); } public void removePlayer(String name) { players.remove(name); } public boolean isPlayerOnline(String name) { return players.containsKey(name); } public void forEach(BiConsumer<? super String, ? super Player> biConsumer) { players.forEach(biConsumer); } } // ✂--------------請沿虛線剪下-------------- 有了 PlayerManager 的支援, 原本的 Player.run() 功能也得到了進一步的擴充 // 在原有的 Player class 中新增一個 String playerName 儲存使用者的 ID private String playerName; public void run() { try { // 剛寫好的 PlayerManager 在這邊派上用場, 讓他來負責處理關於使用者的事務 PlayerManager pm = PlayerManager.getInstance(); write("歡迎來到 telnet chat server! (多執行緒版本)"); write("請問您的大名?"); // 一個簡易判斷線上是否有同名使用者的小程式 // 如果有同名使用者則一直執行無限迴圈, 直到使用者輸入了不衝突的新 ID String name; while (pm.isPlayerOnline(name = read())) { write("線上已經有一個叫做" + name + "的使用者了! 請重新輸入"); } // 當使用者輸入了獨一無二的 ID 後, 先對所有線上使用者廣播 // 再將目前的使用者加入 players playerName = name; pm.forEach((k, v) -> v.write(playerName + "上線囉")); pm.addPlayer(playerName, this); write(playerName + "你好! 歡迎進入聊天室"); while (true) { String input = read(); if ("quit".equalsIgnoreCase(input)) { socket.close(); // 別忘了使用者下線後必須把他移除 pm.removePlayer(playerName); pm.forEach((k, v) -> v.write(playerName + "離開了")); break; } // 原本只是呼叫個別使用者的 write() // 現在改為使用 forEach 呼叫所有使用者的 write() 達到 chat 的效果 pm.forEach((k, v) -> v.write("【閒聊】" + playerName + "說:" + input)); } } catch (IOException ignored) {} } 以下是三開連線的畫面 如何? MUD 的味道是不是開始慢慢出現了? XD https://i.imgur.com/9l27OV9.png -- ╔═ ═╦╦═════╦═════╗ ◤◤◤ ╠╣飛鳥ももこ╠═╗ ║ ║╚═════╝ ╚═╦═╣ ║╔══════╗╔═╩═╣ █◤ ╠╣Momoko Asuka╠╝ ║ ◣◢◣◢╩╩══════╩════╝ --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 211.72.253.40 (臺灣)
※ 文章網址: https://webptt.com/m.aspx?n=bbs/mud/M.1575532413.A.3C7.html







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Boy-Girl站內搜尋

TOP