《球球大作戰》原始碼解析(7):遊戲迴圈
系列文章
《球球大作戰》原始碼解析——(1)執行起來
《球球大作戰》原始碼解析:伺服器與客戶端架構
《球球大作戰》原始碼解析:移動演算法
《球球大作戰》原始碼解析(6):碰撞處理
《球球大作戰》原始碼解析(7):遊戲迴圈
《球球大作戰》原始碼解析(8):訊息廣播
《球球大作戰》原始碼解析——(1)執行起來
《球球大作戰》原始碼解析:伺服器與客戶端架構
《球球大作戰》原始碼解析:移動演算法
《球球大作戰》原始碼解析(6):碰撞處理
《球球大作戰》原始碼解析(7):遊戲迴圈
《球球大作戰》原始碼解析(8):訊息廣播
服務端程式中有3個定時器函式,前兩篇解析的moveloop方法處理了玩家的移動,另外兩個方法分別是gameloop和sendUpdates。其中gameloop負責排行榜和食物產生等邏輯。gameloop是在定時器中呼叫,相關語句為:setInterval(gameloop, 1000),即每秒執行1次。下圖為遊戲右上角的排行榜。
排行榜
gameloop先將user表按照重量大小排序,然後把前10名放到topUsers列表中,程式碼如下所示。
- function gameloop() {
- if (users.length > 0) {
- users.sort( function(a, b) { return b.massTotal - a.massTotal; });
- var topUsers = [];
- for (var i = 0; i < Math.min(10, users.length); i++) {
- if(users[i].type == 'player') {
- topUsers.push({
- id: users[i].id,
- name: users[i].name
- });
- }
- }
- ……
- }
緊接著更新leaderboard列表,如果topUsers較之前有改變的話,就標記leaderboardChanged,這樣可以減少不必要的訊息 同步,只傳送有更改的資料。
- if (isNaN(leaderboard) || leaderboard.length !== topUsers.length) {
- leaderboard = topUsers;
- leaderboardChanged = true;
- }
- else {
- for (i = 0; i < leaderboard.length; i++) {
- if (leaderboard[i].id !== topUsers[i].id) {
- leaderboard = topUsers;
- leaderboardChanged = true;
- break;
- }
- }
- }
質量損失
如果小球質量較大,那麼它會定時損耗質量,相關程式碼如下所示。
- for (i = 0; i < users.length; i++) {
- for(var z=0; z < users[i].cells.length; z++) {
- if (users[i].cells[z].mass * (1 - (c.massLossRate / 1000)) > c.defaultPlayerMass && users[i].massTotal > c.minMassLoss) {
- var massLoss = users[i].cells[z].mass * (1 - (c.massLossRate / 1000));
- users[i].massTotal -= users[i].cells[z].mass - massLoss;
- users[i].cells[z].mass = massLoss;
- }
- }
- }
食物和病毒
最後gameloop呼叫balanceMass方法,它先計算現在場上所有食物和所有玩家的質量之和,然後看看食物會不會太少,如果太少則呼叫addFood新增食物,多了就減少一些食物。同理,也增加或減少一些病毒。
- function balanceMass() {
- var totalMass = food.length * c.foodMass +
- users
- .map(function(u) {return u.massTotal; })
- .reduce(function(pu,cu) { return pu+cu;}, 0);
- var massDiff = c.gameMass - totalMass;
- var maxFoodDiff = c.maxFood - food.length;
- var foodDiff = parseInt(massDiff / c.foodMass) - maxFoodDiff;
- var foodToAdd = Math.min(foodDiff, maxFoodDiff);
- var foodToRemove = -Math.max(foodDiff, maxFoodDiff);
- if (foodToAdd > 0) {
- //console.log('[DEBUG] Adding ' + foodToAdd + ' food to level!');
- addFood(foodToAdd);
- //console.log('[DEBUG] Mass rebalanced!');
- }
- else if (foodToRemove > 0) {
- //console.log('[DEBUG] Removing ' + foodToRemove + ' food from level!');
- removeFood(foodToRemove);
- //console.log('[DEBUG] Mass rebalanced!');
- }
- var virusToAdd = c.maxVirus - virus.length;
- if (virusToAdd > 0) {
- addVirus(virusToAdd);
- }
- }
最後依然還是放個廣告吧,筆者出版的一本書《Unity3D網路遊戲實戰》充分的講解怎樣開發一款網路遊戲,特別對網路框架設計、網路協議、資料處理等方面都有詳細的描述,相信會是一本好書的。
作者:羅培羽
專欄地址:https://zhuanlan.zhihu.com/p/28488266
相關文章
- 《球球大作戰》原始碼解析(6):碰撞處理原始碼
- 《球球大作戰》原始碼解析——(9)訊息處理原始碼
- 《球球大作戰》原始碼解析:移動演算法原始碼演算法
- 《球球大作戰》原始碼解析——(1)執行起來原始碼
- 《球球大作戰》原始碼解析(8):訊息廣播原始碼
- 《球球大作戰》原始碼解析:伺服器與客戶端架構原始碼伺服器客戶端架構
- 《球球大作戰》優化之路(上)優化
- 《球球大作戰》優化之路(下)優化
- 淺聊球球大作戰玩法與社交
- 《球勝大本營》——耳目一新的躲避球大作戰
- 網球迴圈賽思路 - 分治法求解(無程式碼)
- 【開源遊戲】Legends-Of-Heroes 基於ET 7.2的雙端C#(.net7 + Unity3d)多人線上英雄聯盟風格的球球大作戰遊戲。遊戲C#Unity3D
- Python寫個“點球大戰”小遊戲Python遊戲
- 《球球大作戰》攜手上海科技館科普援藏,“鯨奇世界”拉薩巡展開幕
- 年度鞋王迪奧AJ1說送就送 CJ最豪橫《球球大作戰》展臺
- 尋找伊犁鼠兔,巨人網路《球球大作戰》發起野生動物保護公益行動
- 51nod 3145 扔球遊戲遊戲
- ForeVR Games進軍檯球遊戲VRGAM遊戲
- python簡單遊戲-反彈球Python遊戲
- 設計一款籃球經理類遊戲:球員屬性遊戲
- PONG - 100行程式碼寫一個彈球遊戲行程遊戲
- 設計一款籃球經理類遊戲(三):球隊的設計遊戲
- 在世界球場一球成名:HMS 生態為遊戲開發者送出的助攻遊戲開發
- 小學期資料結構——消球遊戲資料結構遊戲
- 喵的Unity遊戲開發之路 - 推球:遊戲中的物理Unity遊戲開發
- Netty原始碼解析 -- 事件迴圈機制實現原理Netty原始碼事件
- 從抖音《音躍球球》走紅 看超休閒遊戲究竟能做些什麼?遊戲
- 不打網球也能贏?這款休閒網球遊戲的設計思路有點皮遊戲
- SupertapX全球首次分享:《戀愛球球》等爆款遊戲的立項測試與研發遊戲
- NBA 2K23 Arcade Edition for Mac(籃球遊戲)Mac遊戲
- 使用 Flutter 與 Firebase 製作 I/O 彈球遊戲Flutter遊戲
- 《戴森球計劃》火了,“科幻遊戲”前途幾何?遊戲
- # 火題小戰 A.玩個球
- spring原始碼深度解析— IOC 之 迴圈依賴處理Spring原始碼
- 設計一款籃球經理類遊戲(三):球員升級、裝備、技能與組合遊戲
- PDF迴圈互助矩陣遊戲dapp系統開發搭建(原始碼交付)矩陣遊戲APP原始碼
- 設計一款籃球經理類遊戲(二):球員二級屬性與資料屬性遊戲
- 買球賽的軟體哪個好 手機線上球賽買球appAPP