位置: 编程技术 - 正文

Unity3D游戏开发之回合制游戏原型的实现(Unity3D游戏开发(第2版))

编辑:rootadmin

推荐整理分享Unity3D游戏开发之回合制游戏原型的实现(Unity3D游戏开发(第2版)),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:Unity3D游戏开发标准教程,Unity3D游戏开发基础,Unity3D游戏开发标准教程吴亚峰于复兴人民邮电出版社,Unity3D游戏开发(第2版),Unity3D游戏开发标准教程,Unity3D游戏开发pdf,Unity3D游戏开发毕业论文,Unity3D游戏开发(第2版),内容如对您有帮助,希望把文章链接给更多的朋友!

大家好,欢迎大家关注我的博客,我是秦元培,我的博客地址是blog.csdn.net/qinyuanpei。

今天呢,我们来说说回合制。博主曾经坦言自己是一个喜欢国产RPG游戏的人,《仙剑奇侠传》、《轩辕剑》、《古剑奇谭》等游戏都为博主带来了许多温暖的回忆。那么什么是回合制呢?让我们将视线转移到三足鼎立的三国时代,只见张飞挺着丈八蛇矛,大喝一声:三姓家奴休走,与我大战三百回合。布大怒,举起画戟,便要刺来。这是我们记忆中最原始的关于回合印象,可见这里的回合是指对战双方武将骑着马对冲,人随着马的惯性对打,如果双方都没有死,就调转马头,再来一次。这便是最初的回合的概念。而追朔到欧洲的燧石枪时代,对战双方则是按照各自阵营站成整齐的一排,听口令按次序互相击毙。当你打完后,就必须等待我开枪,这才是回合制的精髓,在《刺客信条》等游戏中我们可以一窥当年欧洲战场之宏伟壮观。同样地,当两个人要决斗时,就是拿着手枪挨个打,直到有人倒下为止,这就是回合制,伟大的诗人普希金就是这样死的。可见回合制是体现人文精神的、尊重规则、尊重原则的一种历史产物。而在我们的生活中,篮球、扑克、象棋、麻将都是回合制的,如果没有回合制,就将没有规则和秩序。真正的侠客不在于武,而在于适可而止,我们不是在战场上胡乱厮杀,而是而是冷静地停下来,安静地思考策略,谋划下一回合的进攻和防守。而这就是回合制,如果说回合制代表了人类最原始的一种文化形态,那么这种形态可能是一种落后的形态,因为最初的游戏受到硬件水平的影响,回合制是一种最为折中的办法。从这个角度上来看,回合制非但不落后,而且有点高贵、古典的气息流淌在里面,这就是为什么国产单机游戏都喜欢使用回合制这一战斗模式的原因所在,我们不羡慕国外游戏大作的酣畅淋漓、我们不羡慕国外游戏大作的奢华精致,我们只想找回属于我们的最初的归属。那是一种流淌了五千年的血液,那是一段述说了五千年的故事,那是一个执着了五千年的梦想,因为如此,所以我们懂得了什么叫做热爱,什么叫做温暖,什么叫做责任,什么叫做感动。好了,今天的游戏我们就先聊到这里啦,下面我们开始今天的内容。

在文章开始,我们已将回合制的战斗模式讲解得很清楚了。那么,如果在Unity3D游戏中实现一个回合制游戏呢?我们从最简单的一对一模式来设计回合制游戏的原型。我们可以游戏的状态划分为下面三种状态:

1、我方角色生命&#;为0,则游戏结束,角色输。

2、敌方角色生命&#;为0,则游戏结束,角色赢。

3、如果双方角色生命&#;均不为0,则反复执行下面的过程:

当当前操作状态为AI时,敌人根据AI算法逻辑行动 当当前操作状态为玩家时,根据玩家操作执行行动

这就是我们今天实现回合制游戏的算法原型。我们下面将根据这一原型来实现一个回合制游戏的示例。首先我们创建一个简单的游戏场景,如图所示:

在这个游戏场景中,我们的Samuzai 将作为我们的游戏主角,而Gorilla将作为我们的敌人。我们分别为它们创建对应的脚本文件Player.cs、EnemyAI.cs以及用于全局控制的TurnGame.cs。Player.cs脚本负责玩家相关逻辑的实现,EnemyAI脚本负责敌人AI的相关逻辑,TurnGame脚本负责回合制游戏的核心部分。好了。我们下面来一起来看这三部分的脚本代码:

Unity3D游戏开发之回合制游戏原型的实现(Unity3D游戏开发(第2版))

首先在Player脚本中,我们需要做三件事情:(1)显示和隐藏玩家的操作界面、(2)玩家攻击招式的设定、(3)玩家生命&#;的设计。我们来一起看代码:

[csharp] view plaincopyusing UnityEngine; using System.Collections; public class Player : MonoBehaviour { //定义玩家最大生命&#;为 public int HP=; //是否等待玩家输入 public bool isWaitPlayer=true; //当前回合数 private int index=1; //动画组件 private Animation mAnimation; void Start () { mAnimation=GetComponent<Animation>(); } //受到伤害 void OnDamage(int mValue) { HP-=mValue; } void OnGUI() { //如果处于等待玩家输入状态,则显示操作窗口 if(isWaitPlayer) { GUI.Window(0,new Rect(Screen.width/2&#;,Screen.height/2-,,),InitWindow,"请选择技能或仙术"); } } void InitWindow(int ID) { if(GUI.Button(new Rect(0,,,),"御剑术")) { mAnimation.Play("Attack"); //将操作权交给敌人 isWaitPlayer=false; Debug.Log("在第"&#;index&#;"回合:主角使用了御剑术"); index&#;=1; } if(GUI.Button(new Rect(0,,,),"万剑诀")) { mAnimation.Play("Attack"); //将操作权交给敌人 isWaitPlayer=false; Debug.Log("在第"&#;index&#;"回合:主角使用了万剑诀"); index&#;=1; } if(GUI.Button(new Rect(0,,,),"仙风云体")) { mAnimation.Play("Attack"); //将操作权交给敌人 isWaitPlayer=false; Debug.Log("在第"&#;index&#;"回合:主角使用了仙风云体"); index&#;=1; } if(GUI.Button(new Rect(0,,,),"化相真如")) { mAnimation.Play("Attack"); //将操作权交给敌人 isWaitPlayer=false; Debug.Log("在第"&#;index&#;"回合:主角使用了化相真如"); index&#;=1; } if(GUI.Button(new Rect(0,,,),"酒神")) { mAnimation.Play("Attack"); //将操作权交给敌人 isWaitPlayer=false; Debug.Log("在第"&#;index&#;"回合:主角使用了酒神"); index&#;=1; } } } 在该脚本中,我们设定角色的最大生命&#;为,然后通过一个bool类型的isWaitPlayer来判断是否处于等待玩家执行下一步行动的状态,如果处于改状态则显示操作界面,这样玩家就可以施展不同的技能,这里我们使用了系统的GUI系统。最终实现的效果是类&#;于仙剑奇侠传游戏的效果,如图:

接下里我们来讲解敌人AI的脚本,敌人需要在玩家执行结束后随机进行一个操作,所以这里需要用到概率,我们一起来看脚本:

[csharp] view plaincopyusing UnityEngine; using System.Collections; public class EnemyAI : MonoBehaviour { //定义敌人最大生命&#;为 public int HP=; public bool isWaitPlayer=true; //当前回合数 private int index=1; //动画组件 private Animation mAnimation; void Start() { mAnimation=GetComponentInChildren<Animation>(); } void OnDamage(int mValue) { HP-=mValue; } /// <summary> /// 执行敌人的AI算法 /// </summary> public void StartAI() { if(!isWaitPlayer) { if(HP>) { //%的攻击招式一 if(Random.Range(1,5)%5!=1) { Debug.Log("在第"&#;index&#;"回合:敌人使用了攻击招式一"); mAnimation.Play("Howl"); //在这里加上特效和伤害 index&#;=1; isWaitPlayer=true; } //%的攻击招式二 else { Debug.Log("在第"&#;index&#;"回合:敌人使用了攻击招式二"); mAnimation.Play("Howl"); index&#;=1; isWaitPlayer=true; } }else { switch(Random.Range(1,5)%5) { case 0: Debug.Log("在第"&#;index&#;"回合:敌人使用了攻击招式三"); mAnimation.Play("Howl"); index&#;=1; isWaitPlayer=true; break; case 1: Debug.Log("在第"&#;index&#;"回合:敌人使用了攻击招式四"); mAnimation.Play("Howl"); index&#;=1; isWaitPlayer=true; break; case 2: Debug.Log("在第"&#;index&#;"回合:敌人使用了攻击招式五"); mAnimation.Play("Howl"); index&#;=1; isWaitPlayer=true; break; } } } } } 类&#;地,我们在这里使用一个bool类型的变量isWaitPlayer来表示敌人是否处于等待玩家执行操作的状态,如果该&#;为false,则表明玩家已经执行完操作,此时敌人应该按照AI算法来实现随机的攻击,其中概率部分的代码如下:[csharp] view plaincopyRandom.Range(1,5)%5!=1 这一句代码表示%的概率,因为只有Random.Range(1,5)返回&#;为5时结果才会为1。如果我们以后希望在游戏中为敌人增加概率,我们都可以使用这种方法。游戏中使用概率的地方还是比较多的,比如在仙剑奇侠传游戏中的逃跑率、暴击率、避让率都是通过这种方式来实现的。大家可能注意到了我在这两个脚本中所有技能或者招式都是使用了一个动画,这当然是为了简化程序,让我们专注于游戏的核心实现,这一点希望大家谅解啊,而在两个脚本中的回合数index主要是为了调试程序的方便,具体应用中可以不用这个变量。好了,在介绍完玩家和敌人的脚本后,我们一起来看今天的核心脚本——TurnGame脚本:[csharp] view plaincopyusing UnityEngine; using System.Collections; public class TurnGame : MonoBehaviour { /// <summary> /// 回合制游戏战斗模式原型 /// 说明:本程序以最简单一对一回合制游戏为例,基于Unity3D游戏实现回合制游戏算法 /// 如果需要实现多人对多人的回合制游戏算法,需要设计行动条算法 /// 基本的思路是将游戏状态划分为三种状态: /// 1、我方角色生命&#;为0,游戏结束,玩家输 /// 2、敌方角色生命&#;为0,游戏结束,玩家赢 /// 3、双方生命&#;均不为0,则循环执行下列过程: /// 当当前操作状态为AI时,敌人根据AI算法逻辑行动 /// 当当前操作状态为玩家时,根据玩家操作执行行动 /// </summary> //定义玩家及敌人 public Transform mPlayer; public Transform mEnemy; //定义玩家及敌人脚本类 private Player playerScript; private EnemyAI enemyScript; //默认操作状态为玩家操作 private OperatorState mState=OperatorState.Player; //定义操作状态枚举 public enum OperatorState { Quit,//游戏结束 EnemyAI,//AI逻辑 Player//玩家逻辑 } void Start () { //获取玩家及敌人脚本类 playerScript=mPlayer.GetComponent<Player>(); enemyScript=mEnemy.GetComponent<EnemyAI>(); } //延迟等待显示操作界面 IEnumerator WaitUI() { yield return new WaitForSeconds(1); enemyScript.isWaitPlayer=true; } //延迟等待 IEnumerator WaitAI() { yield return new WaitForSeconds(2.5F); enemyScript.isWaitPlayer=false; } //为AI设计延迟时间,使其在我方行动结束后2.5F秒的时间内发起攻击 IEnumerator UpdateLater() { yield return new WaitForSeconds(2.5F); //敌人停止等待 enemyScript.isWaitPlayer=false; //敌人执行AI enemyScript.StartAI(); } void Update () { //如果敌我双方有一方生命&#;为0,则游戏结束 if(playerScript.HP==0) { mState=OperatorState.Quit; Debug.Log("玩家输"); }else if(enemyScript.HP==0) { mState=OperatorState.Quit; Debug.Log("玩家赢"); }else { switch(mState) { case OperatorState.Player: //如果玩家操作结束,则立即隐藏操作界面,等待2秒钟后敌人AI操作开始 if(!playerScript.isWaitPlayer) { //让敌人等待2秒钟再发起攻击 StartCoroutine("UpdateLater"); //执行完后等待玩家,5秒钟后显示操作界面,玩家可以继续操作 StartCoroutine("WaitUI"); mState=OperatorState.EnemyAI; } break; case OperatorState.EnemyAI: //如果敌人AI操作结束,则玩家开始操作 if(enemyScript.isWaitPlayer) { //玩家操作 playerScript.isWaitPlayer=true; StartCoroutine("WaitUI"); //操作完后执行AI StartCoroutine("WaitAI"); mState=OperatorState.Player; } break; } } } } 在这段脚本中,我们按照一开始在文章开头设计的算法原型,定义状态枚举OperatorState,然后根据不同的状态去执行不同的逻辑。这块的代码是博主调试了很多次才调试出来的,所以这一部分的代码可能会有点乱。前面两种状态的判定比较简单,只要在逻辑中添加相应的逻辑,比如显示游戏胜利、游戏失败等。而对于第三种状态,我们将其分为两种状态,并在这两种状态中通过改变状态&#;来实现状态的切换。基本的思路是:

1、轮到玩家时,如果玩家执行操作已经结束,则隐藏操作界面,延迟2秒后敌人将发起攻击,当敌人执行完攻击后5秒再次显示操作界面,为玩家的下一轮操作做好准备。

2、轮到敌人时,如果敌人AI操作已经结束,则轮到玩家操作,操作结束后将操作权交给敌人。

这段程序中博主用到了协程,不过博主感觉这里协程用得不是很好,如果大家有什么好的建议,欢迎大家给我留言,作为一个有节操的程序员,接受别人的建议比闭门造车更重要。好了,我们来看看最终程序运行的效果吧:

当然这里博主没有给脚本添加伤害部分的代码,所以到目前为止,敌我双方走没有对对方造成实际的伤害,呵呵,这个大家可以通过调用OnDamage()方法来实现,这里我们就不再说了。由于今天的截图文件比较大,所以给大家发不了GIF演示,这里给出下载地址,感兴趣的同学可以自己去下载。

注意:由于在博客设计这个算法的时候存在问题,这个回合制游戏在第一次攻击的时候有Bug,玩家攻击结束后操作界面不会隐藏

参考文章:【Visual C&#;&#;】游戏开发笔记十六 讲解一个完整的回合制游戏demo

学习游戏开发推荐浅墨的博客: 每日箴言:不要去等谁,所有的不期而遇都在路上。

好了,今天的博客就是这样了,博主去写作业了。喜欢我的博客请记住我的名字:秦元培,我博客地址是blog.csdn.net/qinyuanpei。

转载请注明出处,本文作者:秦元培,本文出处:

Unity3D游戏开发之鼠标旋转、缩放实现3D物品展示

OnApplicationFocus 前两天用到ngui做拖拽效果,将一张图片拖拽到另一个固定的子里,看的是NGUI的一个demo做的,但是会有一个问题,就是在推拽过程中,如果切换应用程

unity项目之一飞机自由分行和发射子弹 unity飞机大战之一,场景的基本搭建,和飞机的自由飞行与与发射子弹;1.场景搭建先把资源包导入进来,然后在设计栏里面,建立几个文件夹,分别有R

标签: Unity3D游戏开发(第2版)

本文链接地址:https://www.jiuchutong.com/biancheng/375775.html 转载请保留说明!

上一篇:unity3d 异步socket packet序列化(unity socket udp)

下一篇:Unity3D游戏开发之鼠标旋转、缩放实现3D物品展示(Unity3D游戏开发培训课程大纲)

  • 附加税税率分别是多少
  • 新冠肺炎捐赠账务处理
  • 携程代订住宿发票能作为差旅费报销吗
  • 增值税普通发票有什么用
  • 事业单位补提折旧怎么处理
  • 办税人员绑定企业审核谁审核
  • 国家电子产品投诉电话
  • 已认证红冲需要退回发票吗
  • 车间用的电线计入什么科目
  • 防暑降温用品计算方法
  • 子公司固定资产移到母公司
  • 库存现金日记账格式
  • 老板垫付员工工资怎么写条子
  • 职工福利部门的工资
  • 资产拍卖税费谁承担
  • 向银行借款一年是长期还是短期
  • 免税农产品收入是否计入30万销售额
  • 营改增土地增值税的计算
  • 不得扣除任何费用的是
  • 一般纳税人和小微企业的区别
  • 定额发票使用年限规定
  • 成本费用怎么做分录
  • 技术服务费属于什么大类
  • 销售旧房增值税销售额怎么算
  • 票据贴现业务的风险
  • 日用品做账时放什么东西
  • 如何取消开始菜单的程序
  • 收支两条线是指
  • 年报企业控股情况怎么填
  • 双网卡冲突会发生什么现象
  • ryzen3 2200g相当于i几
  • 进程核心栈
  • 上市公司发行股票是好还是坏
  • 机器设备拆除增值税税率
  • 小规模纳税人进项可以抵扣吗
  • vue3.0项目
  • 固定资产折旧的计算方法
  • 货币资金属于
  • 社保代扣代缴会计分录怎么做
  • symfony框架经验总结
  • php linux 环境搭建
  • 企业从应付职工工资中代扣的职工房租应借记
  • 购买方未抵扣,销售方申请红字
  • react roter
  • 财务支出表怎么做
  • 企业的职工福利费应当按照应付工资总额的14%计提
  • 劳务费发票怎么入账
  • dedecms采集怎么用
  • 解决胃胀气最快方法
  • 成本核算方法是指
  • 金蝶迷你版怎么打印明细账
  • 一次还本付息债券定价公式
  • 经营活动现金流量净额是什么意思
  • 房地产企业实际发生的税金及附加
  • 间接人工费用计入什么科目
  • 什么混合销售
  • 关税 账务处理
  • 买车险要先付钱再上牌吗
  • 利息收入缴纳税率怎么算
  • 待抵扣进项税额和进项税额的区别
  • 工程物资属于什么科目资产负债表
  • 接待客户的旅游活动
  • sqlserver 获取字符位置
  • windows vista安装光盘进入dos
  • window2008 64位系统没有office组件问题分析及解决
  • linux命令放在哪个路径
  • windows无法启动,可能原因
  • wind10怎么打开摄像头
  • linux diff用法
  • linux page buffer cache深入理解
  • unity3d协程的作用
  • javascript自定义属性
  • 如何进行arp病毒防范
  • linux c语言获取当前路径
  • js制作网页制作步骤
  • unity导入设置在哪里
  • webview自定义视频播放器
  • jquery获取浏览器宽度
  • html5table
  • 山西省网上营业执照申请官网?
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设