游戏中每隔 xx 分钟回复一格体力 数据库一般是怎么存储的?

2022-07-08 17:00:40 +08:00
 dfgxcvbcv

不太可能每分钟都遍历一次体力没满的用户吧

6520 次点击
所在节点    数据库
37 条回复
joesonw
2022-07-08 17:05:14 +08:00
1 ,数据一般是在内存里,然后落地到数据库的
2 ,有用时间轮的,有每次请求检查上次更新的
3 ,离线用户是登录的时候计算
elioti
2022-07-08 17:05:41 +08:00
那就查询的时候更新呗
banmuyutian
2022-07-08 17:05:47 +08:00
盲猜延时消费消息?
MoYi123
2022-07-08 17:05:50 +08:00
和令牌桶一样的做法啊.
ranleng
2022-07-08 17:12:49 +08:00
上一次恢复的时间,当前时间,每恢复 1hp 的时间, 就能算出来了。
算完之后更新下上一次恢复的时间就行了
fanyingmao
2022-07-08 17:14:45 +08:00
现在就在写体力恢复的代码,就更查询时更新,数据库存一个时间和当前体力值,查询就对比当前时间和存的时间差多少,恢复多少体力,然后在把时间加上恢复体力*单位时间。
wfhtqp
2022-07-08 17:15:10 +08:00
只存储剩余体力以及上次消耗体力的时间,下次消耗的时候计算是否满足并更新数据。前端直接根据上次体力计算显示当前体力
libook
2022-07-08 17:15:37 +08:00
没做过游戏,只是有个脑洞,尽可能避免定时任务。

记录上一次查询时间以及同时计算出来的体力值,活跃的用户每次来请求体力值的时候用上一次体力值与上一次到现在的时间长度来算涨多少体力值,超过体力上限就设为上限值,然后把新算的体力值和当前时间记录下来。性能和 PV 有关,和总用户数量无关。
xianyv
2022-07-08 17:17:55 +08:00
unity 的话有 Time 类可以计算时间间隔,或者使用协程间隔时间
ahill
2022-07-08 17:32:47 +08:00
当前体力=当前时间- 上限范围内使用体力总数
所以不需要记录当前体力,只需要记录 160*8min 内每次使用体力的时间和数量即可。最多是 160/20=8 条记录
登陆的时候查询计算一次之后就在客户端计算,扣体力的时候后台校验一下
IssacTomatoTan
2022-07-08 17:38:54 +08:00
体力值 +1 是游戏客户端根据人物状态自己展示 + - 的,不和服务端交流。

服务端负责存下最后一次对体力值的修改,当游戏客户端发起请求说有人砍了我一刀我死了没呀?服务端就获取最后体力修改的时间,来计算到当前时间应有的体力值,然后计算这一刀的减去值,记录下最新的体力值,返回客户端死没死。
mango88
2022-07-08 17:42:28 +08:00
数据库存上一次恢复时间,算的时候,
min( (当前时间 - 上一次恢复时间) / 恢复一点体力需要的时间 + 当前剩余体力, 体力上限)
yolee599
2022-07-08 20:45:36 +08:00
存一个时间戳,用时更新
v23x
2022-07-08 20:48:59 +08:00
这种东西就直接按时间加上去就好了呀....用户什么时候离线的这些全都是有的
churchill
2022-07-08 21:09:33 +08:00
@IssacTomatoTan 那我找到这个发请求的方法 jump 掉 不就无敌了吗
tairan2006
2022-07-08 21:31:10 +08:00
异步落库常规操作

没听说过服务器回档么?
rekulas
2022-07-08 21:41:40 +08:00
时间相减即可计算出来,很简单
升级版问题:facebook 是如何推送用户消息的,要知道头部用户一个贴可能要推送给上千万人,而每个用户可能关注了数百个甚至上千个其他用户
weidaizi
2022-07-08 21:57:26 +08:00
像体力这种一般不落库,在追求速度的游戏当中(第一人称射击类,即使战略类)基本都是客户端自己算,服务器为了反外挂,会落一些数据到文件而不是数据库。MMORPG 类型的,我早年做游戏的时候,有服务器算的,也有客户端算的,但是也都不落库。一般需要落库的是一些等级,充值以及装备呀之类的
Martens
2022-07-08 22:50:12 +08:00
服务器记一个时间戳,查询时更新
客户端登录时同步,自己维护
moen
2022-07-09 00:00:15 +08:00
我曾经玩过的一个手游就是记录某个时刻和当时的体力值,下面是客户端反编译的代码相关的部分:
```
public new int St
{
get
{
if (base.St >= SingletonInstance<UserService>.SharedInstance.MaxSt)
{
return base.St;
}
double num = (SingletonInstance<TimeService>.SharedInstance.ServerDateTime - base.StUpdatedAt).TotalSeconds / ServerConsts.HealStInterval.TotalSeconds;
return Mathf.Min(SingletonInstance<UserService>.SharedInstance.MaxSt, base.St + (int)num);
}
}
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/864966

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX