游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2222|回复: 0

《球球大作战》源码解析(7):游戏循环

[复制链接]

1万

主题

1万

帖子

3万

积分

论坛元老

Rank: 8Rank: 8

积分
36572
发表于 2019-3-22 11:44:02 | 显示全部楼层 |阅读模式
154401odzz7rzh2le72dfd.jpg


服务端程序中有3个定时器函数,前两篇解析的moveloop方法处理了玩家的移动,另外两个方法分别是gameloop和sendUpdates。其中gameloop负责排行榜和食物产生等逻辑。gameloop是在定时器中调用,相关语句为:setInterval(gameloop, 1000),即每秒执行1次。下图为游戏右上角的排行榜。

2.png

排行榜

gameloop先将user表按照重量大小排序,然后把前10名放到topUsers列表中,代码如下所示。

  1. function gameloop() {

  2.     if (users.length > 0) {

  3.         users.sort( function(a, b) { return b.massTotal - a.massTotal; });



  4.         var topUsers = [];



  5.         for (var i = 0; i < Math.min(10, users.length); i++) {

  6.             if(users[i].type == 'player') {

  7.                 topUsers.push({

  8.                     id: users[i].id,

  9.                     name: users[i].name

  10.                 });

  11.             }

  12.         }

  13.         ……

  14. }
复制代码

紧接着更新leaderboard列表,如果topUsers较之前有改变的话,就标记leaderboardChanged,这样可以减少不必要的消息 同步,只发送有更改的数据。

  1. if (isNaN(leaderboard) || leaderboard.length !== topUsers.length) {

  2.             leaderboard = topUsers;

  3.             leaderboardChanged = true;

  4.         }

  5.         else {

  6.             for (i = 0; i < leaderboard.length; i++) {

  7.                 if (leaderboard[i].id !== topUsers[i].id) {

  8.                     leaderboard = topUsers;

  9.                     leaderboardChanged = true;

  10.                     break;

  11.                 }

  12.             }

  13.         }
复制代码

质量损失

如果小球质量较大,那么它会定时损耗质量,相关代码如下所示。

  1. for (i = 0; i < users.length; i++) {

  2.             for(var z=0; z < users[i].cells.length; z++) {

  3.                 if (users[i].cells[z].mass * (1 - (c.massLossRate / 1000)) > c.defaultPlayerMass && users[i].massTotal > c.minMassLoss) {

  4.                     var massLoss = users[i].cells[z].mass * (1 - (c.massLossRate / 1000));

  5.                     users[i].massTotal -= users[i].cells[z].mass - massLoss;

  6.                     users[i].cells[z].mass = massLoss;

  7.                 }

  8.             }

  9.         }
复制代码

食物和病毒

最后gameloop调用balanceMass方法,它先计算现在场上所有食物和所有玩家的质量之和,然后看看食物会不会太少,如果太少则调用addFood添加食物,多了就减少一些食物。同理,也增加或减少一些病毒。

  1. function balanceMass() {

  2.     var totalMass = food.length * c.foodMass +

  3.         users

  4.             .map(function(u) {return u.massTotal; })

  5.             .reduce(function(pu,cu) { return pu+cu;}, 0);



  6.     var massDiff = c.gameMass - totalMass;

  7.     var maxFoodDiff = c.maxFood - food.length;

  8.     var foodDiff = parseInt(massDiff / c.foodMass) - maxFoodDiff;

  9.     var foodToAdd = Math.min(foodDiff, maxFoodDiff);

  10.     var foodToRemove = -Math.max(foodDiff, maxFoodDiff);



  11.     if (foodToAdd > 0) {

  12. //console.log('[DEBUG] Adding ' + foodToAdd + ' food to level!');

  13.         addFood(foodToAdd);

  14. //console.log('[DEBUG] Mass rebalanced!');

  15.     }

  16.     else if (foodToRemove > 0) {

  17. //console.log('[DEBUG] Removing ' + foodToRemove + ' food from level!');

  18.         removeFood(foodToRemove);

  19. //console.log('[DEBUG] Mass rebalanced!');

  20.     }



  21.     var virusToAdd = c.maxVirus - virus.length;



  22.     if (virusToAdd > 0) {

  23.         addVirus(virusToAdd);

  24.     }

  25. }

复制代码

最后依然还是放个广告吧,笔者出版的一本书《Unity3D网络游戏实战》充分的讲解怎样开发一款网络游戏,特别对网络框架设计、网络协议、数据处理等方面都有详细的描述,相信会是一本好书的。

v2-71fc8085617f1503a534b04f8f8c6e61_hd.png



作者:罗培羽
专栏地址:https://zhuanlan.zhihu.com/p/28488266

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2024-4-25 19:49

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表