如何在游戏暂停时正确停止倒计时定时器

发布时间 - 2026-02-03 00:00:00    点击率:

本文讲解如何通过增量时间(delta time)机制实现游戏倒计时的精准暂停与恢复,避免系统级时间持续累积导致计时失准。核心是仅在播放状态(playstate)下累加时间差,而非依赖全局起始时间戳。

在 Java 游戏开发中,使用 System.currentTimeMillis() 直接计算总耗时(如 elapsedTime = now - startTime)看似简洁,但一旦游戏进入暂停状态(如 gp.gameState == gp.pauseState),该方式会持续“偷跑”——因为 startTime 是固定不变的,而 System.currentTimeMillis() 永远向前推进。结果就是:暂停 5 秒后恢复,倒计时直接少掉 5 秒,严重破坏游戏公平性与体验。

✅ 正确解法:改用增量式时间累加(Delta Time Accumulation)
不再依赖单一初始时间点,而是每帧记录与上一帧的时间差(delta),仅在非暂停状态下将该差值累加到已用时间中。这样,暂停期间 delta 虽然仍可计算,但不会被计入 elapsed,从而实现逻辑上的“时间冻结”。

以下是适配你现有代码结构的推荐实现:

// 声明为类成员变量(确保生命周期贯穿整个游戏)
private long lastUpdateTime = System.currentTimeMillis();
private long accumulatedTime = 0; // 已实际流逝的毫秒数(仅在 playState 下增长)
private final long TOTAL_TIME_MS = 60_000; // 60秒 = 60,000 毫秒

// 在游戏主循环(如 gameLoop() 或 update() 方法中)调用:
public void updateTimer() {
 

long now = System.currentTimeMillis(); long delta = now - lastUpdateTime; // ✅ 关键:仅当处于播放状态且有正向时间差时才累加 if (gp.gameState == gp.playState && delta > 0) { accumulatedTime += delta; lastUpdateTime = now; // 更新基准时间点 } // 计算剩余时间(注意:remainingTime 是基于 accumulatedTime 的实时推导) long remainingTime = TOTAL_TIME_MS - accumulatedTime; if (remainingTime <= 0) { remainingTime = 0; gp.gameOver(); } // 格式化显示(毫秒取余,避免浮点误差) long ms = remainingTime % 1000; long sec = (remainingTime / 1000) % 60; long min = (remainingTime / 1000) / 60; timeString = String.format("%02d:%02d:%03d", min, sec, ms); }

? 关键注意事项:

  • lastUpdateTime 必须在每次成功累加 delta 后立即更新为 now,否则下一帧的 delta 会异常增大;
  • 不要重置 lastUpdateTime 进入暂停态(如设为 System.currentTimeMillis()),否则恢复时会产生巨大 delta,造成跳秒;
  • accumulatedTime 是唯一可信的“已用时间”,所有逻辑(包括超时判断、UI 更新)都应基于它,而非重新计算 now - startTime;
  • 若需支持多次暂停/恢复,此方案天然兼容——无需保存 pauseTime 或手动减法,逻辑更健壮、更易维护。

? 进阶提示:
对于更高精度或跨平台一致性需求,可考虑使用 System.nanoTime() 替代 currentTimeMillis()(注意单位是纳秒,需除以 1_000_000 转毫秒),它不受系统时钟调整影响,更适合游戏时间计量。

采用增量累加模式后,你的倒计时将真正与游戏状态同步:暂停即停,恢复即续,彻底告别“时间偷跑”问题。


# java  # ai  # 游戏开发  # ui  # 倒计时  # 而非  # 已用  # 进阶  # 浮点  # 设为  # 上一  # 不受  # 下一  # 更高 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何用好域名打造高点击率的自主建站?  使用PHP下载CSS文件中的所有图片【几行代码即可实现】  微信小程序 canvas开发实例及注意事项  移动端脚本框架Hammer.js  如何在景安云服务器上绑定域名并配置虚拟主机?  node.js报错:Cannot find module &#39;ejs&#39;的解决办法  手机软键盘弹出时影响布局的解决方法  使用C语言编写圣诞表白程序  Python函数文档自动校验_规范解析【教程】  Python并发异常传播_错误处理解析【教程】  如何在阿里云高效完成企业建站全流程?  Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程  如何打造高效商业网站?建站目的决定转化率  香港服务器租用每月最低只需15元?  js代码实现下拉菜单【推荐】  音乐网站服务器如何优化API响应速度?  Laravel如何实现用户注册和登录?(Auth脚手架指南)  JS中页面与页面之间超链接跳转中文乱码问题的解决办法  laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程  Swift中循环语句中的转移语句 break 和 continue  如何快速上传建站程序避免常见错误?  Laravel怎么发送邮件_Laravel Mail类SMTP配置教程  JavaScript数据类型有哪些_如何准确判断一个变量的类型  百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭  如何基于PHP生成高效IDC网络公司建站源码?  利用vue写todolist单页应用  Android GridView 滑动条设置一直显示状态(推荐)  Win11怎么设置默认图片查看器_Windows11照片应用关联设置  Laravel怎么实现支付功能_Laravel集成支付宝微信支付  javascript中的try catch异常捕获机制用法分析  Laravel项目怎么部署到Linux_Laravel Nginx配置详解  如何将凡科建站内容保存为本地文件?  网站制作价目表怎么做,珍爱网婚介费用多少?  如何挑选高效建站主机与优质域名?  Laravel怎么使用artisan命令缓存配置和视图  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?  如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框  如何在Windows 2008云服务器安全搭建网站?  C++时间戳转换成日期时间的步骤和示例代码  详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)  如何解决hover在ie6中的兼容性问题  免费视频制作网站,更新又快又好的免费电影网站?  Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程  在Oracle关闭情况下如何修改spfile的参数  Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践  如何选择PHP开源工具快速搭建网站?  Laravel如何使用Vite进行前端资源打包?(配置示例)  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  Laravel怎么实现模型属性的自动加密  如何在腾讯云服务器上快速搭建个人网站?