做单机游戏的时候,制作人突然提了一个“体力系统”的需求。目前的很多游戏无论是网游还是单机,都有体力系统,我想可能是因为平衡玩家而限制游戏玩法或者是怕玩家无限制的玩游戏疲惫的原因吧。不管怎么说,让我们一起来研究一下体力系统应该怎么做。

本来我以为体力系统挺容易的,后来一做才发现并不是很简单。先在网上搜了一下有关体力的系统的设计思路,结果没有搜到相关信息,算了,自己设计吧。

对于单机游戏来说,因为没有联网的服务器验证,所以只能靠获取设备系统的时间来做体力恢复。这样的话,我在candycrash的小游戏中遇到过这种情况:当玩家体力耗尽时,把系统的时间向后调若干小时,那么再进游戏,游戏体力时满的,此时游戏再次用完后 ,仍可以继续往后调时间,体力继续恢复满了。但是,一旦用户把时间调回当前时间,那么倒计时显示的分钟数将计算为先前调时间最长的时间,也就是几百甚至上千上万分钟,要想继续玩只能向后大幅度调时间。这样做可能有些弊端,就是玩家一旦调整时间,会极大的限制玩家。所以经过商议,我确定将最大体力恢复上限设定一个固定值,当超过上限以后,按最大值倒计时,即使玩家向后调了时间,当改回系统时间的时候,仍然可以等待一点时间继续游戏。

体力系统的恢复时间需要涉及到存储,一旦退出游戏,再次进入游戏的时候仍然要显示体力恢复倒计时。我设计的体力恢复时间存储的最小单位是分钟(minute),当然,也可以以秒(second)为单位存储。存储的时间是体力不满时恢复到所有的体力时的时间点(忽略秒),而想到这个存储的内容,基本上也就解决了体力恢复系统的核心问题。 以下例子是以分钟为单位编写的。

1.首先是进入游戏时体力系统的初始化:

</pre><pre name="code" class="csharp">
</pre><pre name="code" class="csharp">public void DealPower(){//判断是不是第一次进游戏,如果是第一次进游戏那么体力给满格,记录数据if(!PlayerPrefs.HasKey("powerMonth")){//记录回复满的时间NoteRecoverDate(DateTime.Now.Month,DateTime.Now.Day,DateTime.Now.Hour,DateTime.Now.Minute);Global.CRole.PowerValue = ConstPreference.MAX_NPC_POINT_COUNT;RefreshPowerShow();}else{//如果不是第一次//1.取出存储的时间(忽略秒)DateTime dt = new DateTime(DateTime.Now.Year,PlayerPrefs.GetInt("powerMonth"),PlayerPrefs.GetInt("powerDay"),PlayerPrefs.GetInt("powerHour"),PlayerPrefs.GetInt("powerMinute"),0);//2.与当前时间比较if(DateTime.Compare(DateTime.Now,dt)>=0){//当前时间比记录的时间晚:那么此时应该获得满格体力值并且记录当前时间NoteRecoverDate(DateTime.Now.Month,DateTime.Now.Day,DateTime.Now.Hour,DateTime.Now.Minute);Global.CRole.PowerValue = ConstPreference.PLAYER_MAX_POWER;RefreshPowerShow();//刷新UI显示}else{//3.当前时间比记录的时间早:那么看早多长时间(此种情况适用于体力正在恢复,然后退出游戏再进入游戏,体力仍未恢复满时)DateTime now = new DateTime(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,DateTime.Now.Hour,DateTime.Now.Minute,0);bool isStop = false;//做while循环停止的标记int minute = 1;//恢复满所有的体力需要的所有分钟数int max = ConstPreference.PLAYER_MAX_POWER*ConstPreference.PLAYER_POWER_RECOVER;//max:设定恢复时间的上限点数乘以恢复一点体力需要的分钟数即最长分钟数while(!isStop){if(DateTime.Compare(now.AddMinutes(minute),dt)>=0){isStop = true;}else{minute += 1;}//4.当前的时间比记录的时间早minute分钟if(minute == max){//如果超过了上限则停止。此种情况适用于玩家修改系统时间后改回原系统时间的情况isStop = true;}}//4.当前的时间比记录的时间早minute分钟if(minute == max){  //5.提前的时间超过的下限,此时为零体力零计时,应从最大时间开始计时(此种情况适用于玩家故意调时间引起的特殊情况)Global.CRole.PowerValue = 0;//玩家体力为0RefreshPowerShow(ConstPreference.PLAYER_POWER_RECOVER);}else{//从最大值开始倒计时Global.CRole.PowerValue = (int)((ConstPreference.PLAYER_MAX_POWER*ConstPreference.PLAYER_POWER_RECOVER - minute)/ConstPreference.PLAYER_POWER_RECOVER);RefreshPowerShow((ConstPreference.PLAYER_MAX_POWER*ConstPreference.PLAYER_POWER_RECOVER - minute)%ConstPreference.PLAYER_POWER_RECOVER);}}}
}

以上方法是初始化方法。其中,NoteRecoverDate()方式为存储时间的方法,PlayerPrefs.GetInt("powerMonth")是取出保存的月份int值。使用系统的时间,需要添加using System。或者使用System.DateTime.Now来获取时间。在比较时间或者获取差值的时候还可以使用时间的减法来计算。

2.刷新UI显示

</pre><pre name="code" class="csharp">
<pre name="code" class="csharp">
public void RefreshPowerShow(int minute = 0){if(powerValue != null){powerValue.text = Global.CRole.PowerValue.ToString();}if(minute == 0){//可能是购买体力值,已加满,或者是刚进游戏满格体力if(Global.CRole.PowerValue >= ConstPreference.PLAYER_MAX_POWER){if(powerTime != null){powerTime.text = "00:00";}powerTimeInt = 0;//与powerTime同步的int值:为0时静止,否则就是119-0的倒计时isTimeByTime = false;//暂停与继续的标记,开关}}else{powerTimeInt = minute*60-1;isTimeByTime = true;//开启计时器}
}
</pre><p></p><pre>

3.增加体力和减小体力都需要重新计算并存储恢复满体力的时间点:

</pre><pre name="code" class="csharp"><pre name="code" class="csharp">public bool CostPower(){//返回值为布尔值,用来判断是否还有体力进行游戏if(Global.CRole.PowerValue <= 0)return false;//如果当前是满格体力if(Global.CRole.PowerValue == ConstPreference.PLAYER_MAX_POWER){Global.CRole.PowerValue -= 1;//开始倒计时powerTimeInt = ConstPreference.PLAYER_POWER_RECOVER * 60-1;RefreshPowerShow();isTimeByTime = true;}else{Global.CRole.PowerValue -= 1;RefreshPowerShow();}DealSaveData();//重新计算并存储时间return true;
}
<pre name="code" class="csharp">public void AddPower(int val){Global.CRole.PowerValue += val;if(Global.CRole.PowerValue > ConstPreference.PLAYER_MAX_POWER){Global.TipsFormMgr.OpenForm(null,CConstString.Tips_FullPower,false);//公有提示窗口,提示体力超限Global.CRole.PowerValue = ConstPreference.PLAYER_MAX_POWER;}DealSaveData();//重新计算并存储时间RefreshPowerShow();
}

4.倒计时方法

</pre><pre name="code" class="csharp">/// <summary>
/// 每秒执行一次.
/// </summary>
public void RefreshTimeBySceond(){if(!isTimeByTime){//暂停游戏powerTimeInt = 0;if(powerTime != null){powerTime.text = "00:00";}}else{//体力恢复进程if(powerTime != null){powerTime.text = SwitchIntToString(powerTimeInt);}if(powerTimeInt == 0){//计时完成,体力值+1Global.CRole.PowerValue += 1;if(powerValue != null){powerValue.text = Global.CRole.PowerValue.ToString();//把int转换成时间字符串即“00:00” }//如果体力值已满,那么暂停计时if(Global.CRole.PowerValue >= ConstPreference.PLAYER_MAX_POWER){isTimeByTime = false;}else{//如果体力值未满,那么继续计时powerTimeInt = ConstPreference.PLAYER_POWER_RECOVER * 60-1;}}elsepowerTimeInt -= 1;}
}

5.恢复体力的计算与存储

//存储体力恢复满的时间点:只有在消耗体力或者增加体力时才调用此方法
void DealSaveData(){//计算剩余分钟数int leftmin = (ConstPreference.PLAYER_MAX_POWER - Global.CRole.PowerValue)*ConstPreference.PLAYER_POWER_RECOVER- (int)((ConstPreference.PLAYER_POWER_RECOVER*60 - powerTimeInt)/60);if(leftmin<=0){NoteRecoverDate(DateTime.Now.Month,DateTime.Now.Day,DateTime.Now.Hour,DateTime.Now.Minute);}else{DateTime dt = DateTime.Now.AddMinutes(leftmin);NoteRecoverDate(dt.Month,dt.Day,dt.Hour,dt.Minute);}
}

以上就是我设计的简单的单机游戏的体力系统,欢迎大家提出意见和不足,谢谢!

制作单机游戏体力系统相关推荐

  1. Unity3D制作3dRPG游戏——登录系统

    Unity3D制作3dRPG游戏--登录系统 目录 Unity3D制作3dRPG游戏--登录系统 设定辅助摄像机(登录界面背景) UI界面设计 编写代码GameManage思路过程 代码GameMan ...

  2. 单机游戏体力恢复的思路

    以6分钟恢复1体力 满体力是100为例子 注释: (int) SaveData._instance.PS为专门存储数据的类里边的体力 存储时间的对象TIME类 using System; using ...

  3. 只需要一点点C++基础,新手也可以制作单机游戏内存修改器

    声明:本文只是为了初学C++的,能够做出一些实用的东西,跳出管理系统的束缚,提升学习的兴趣,在这里选取了单机游戏,请不要尝试在线游戏,违发而已未必可行. 序:首先我们需要一个Qt+VS环境 Qt从ht ...

  4. android 玩pc游戏,Shield掌机试玩: Android系统 可玩PC单机游戏

    Nvidia即将在北美及加拿大等地推出的新型态Android携带型游戏掌机「Shield」本次在美国E3展中开放玩家试玩,现场除了可透过Shield玩到<Dead Trigger 2>以及 ...

  5. 计算机可以编程游戏吗,我的世界真正的大神,在游戏中编程,制作出能玩的单机游戏...

    原标题:我的世界真正的大神,在游戏中编程,制作出能玩的单机游戏 都知道,我的世界是一款沙盒建造类游戏,从2009年发行至今,有着不错的热度和源源不断的玩家涌入.虽然游戏中所呈现的并不是华丽精致高清的特 ...

  6. creator 跳跃弧线_(转)CocosCreator零基础制作游戏《极限跳跃》八、添加游戏积分系统...

    CocosCreator零基础制作游戏<极限跳跃>八.添加游戏积分系统 前面我们实现了整个游戏的流程,下面我们来完善游戏的积分系统..先来分析下游戏的积分,第一次展示积分的地方就是我们的游 ...

  7. python五子棋游戏from tkinter import_Python tkinter制作单机五子棋游戏

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 以下文章来源于Python家庭,作者Python家庭 实战项目:使用Python ...

  8. 单机游戏制作系列之二——基本框架

    单机游戏制作系列之二--基本框架 笔者个人的想法,是打算将这个系列的文章写成通用性的,不局限于某一种语言,也不局限于某一种引擎,但是水平有限,预计是达不到这个效果.以下仅以C++来举例,如果其他的语言 ...

  9. 单机游戏制作系列之一——初期准备

    单机游戏制作系列之一--初期准备 说来也滑稽,上一篇博客发出来之后,各种大事小情就排山倒海的来了,所以之前计划好的这样一个系列的文章,只好一直停留在腹稿阶段.最近忙里偷闲,把它真正写出来. 之前一直写 ...

最新文章

  1. 【网络流】解题报告:luogu P2740 [USACO4.2]草地排水Drainage Ditches(Edmonds-Karp增广路,最大流模板)
  2. 微生物分类学研究利器:模式微生物基因组数据库
  3. dnf跨一服务器修复,DNF跨区服务器炸裂:一阶段史诗回档,官方补偿何在
  4. NR 5G UE发起的去注册流程
  5. hibernate 管理 Session(单独使用session,非spring)
  6. STM32分类及命名方法
  7. 端计算(2)-android studio 的sdk,avd,grade及其它缓存配置
  8. 一步步编写操作系统 5 配置bochs
  9. 如何开发rest接口服务_如何简化网络请求接口开发
  10. 第二章 Qt Widgets项目的创建、运行和发布的过程
  11. MySQL的lock tables和unlock tables的用法
  12. 免费搭建无限容量个人网盘
  13. Linux中etc目录详解大全总汇详解
  14. 大学生毕业后的档案问题如何处理
  15. CSS3知识点笔记————基础(五星)
  16. UVA 12905 Volume of Revolution (几何,微积分)
  17. 前端开发思想及建议--整理
  18. Mac更新系统后无法使用git
  19. php高仿网络硬盘,高仿永硕网盘E盘源码
  20. 东软始业教育考试(2022.9.11)

热门文章

  1. zk session expire会引起HA模式的rm一直处于standby吗
  2. scrapy框架开发爬虫实战——css语法
  3. 【框架学习】spring 事务处理原理
  4. 优雅的在latex中插入MATLAB代码 | 解决MATLAB代码中文乱码问题
  5. OA、CRM、ERP之间的区别对比
  6. 【毕业设计】JSP自动排课管理系统(源代码+论文+开题报告)
  7. echarts-员工看板排版设计
  8. 独家 | AI与汽车研究报告:学者、产业、趋势全景报告(附下载)
  9. 数据治理:数据质量的度量维度!
  10. python 绘制k线图_利用python numpy+matplotlib绘制股票k线图的方法