一个卡牌游戏的DEMO(0)
最近有一个卡牌游戏的创意,打算用Unity把Demo实现出来练练手。我尽量尝试每天记录一下开发的进度。
打算在这里主要记录游戏设计和开发的过程,作为自己的一个摸索的记录。
虽然只有一个人在做,但还是打算用git来做一下版本控制,毕竟回退之类的相当方便
https://github.com/LouisHuangGT/Yggdrasills-dream
这个游戏类似于卡牌游戏和类《神界:原罪》的回合制RPG结合。玩家扮演一个召唤师,可以将随从召唤到战场上(类似炉石和万智牌),而在战场上则遵循回合制战棋游戏的规则。玩家每个回合的资源由Action Point决定。做任何的动作:移动随从,攻击、打出卡牌都会消耗Action Point,因此玩家必须合理的规划自己的Action Point来进行对战。
此外,我们的Action Point不像炉石或万智牌一样每回合增长,而更像战场女武神,每一个玩家召唤的强力角色(例如一个英雄单位)都会提高总的Action Point。为了增加趣味性,还为每个队伍增加一个Magic Point资源,玩家作为召唤师,召唤到战场上的随从是靠法力进行维持的,因此在战场上的每一个单位都会占用一定的Magic Point,玩家需要规划自己召唤出的随从:例如可以召唤一个强力的随从,但这会占用全部的MP;也可以召唤许多脆弱的随从。游戏设计上大致就是这样。一些具体的细节规则我还在进行调整。
可以看到,从实现的角度来看,我们主要要开发两套系统:一个战棋类回合制RPG和一个卡牌系统。两者其实耦合程度很低,完全可以分开来进行实现。我打算先从比较核心的战棋类回合制游戏入手。
在写代码之前我们先分析一遍战棋类回合制RPG的战斗流程:
首先是回合内的流程:
之后是回合间的流程
这个流程我们把它拆成两块来实现。首先一个全局的TurnManager负责管理回合的进行:例如回合的切换等,这个类也负责用鼠标选取的方式生成一个controllingUnit,使得玩家可以对其进行操作。即第一张流程图到选取单位这个部分的内容在TurnManager中实现。而对于单个单位的操作可以抽象出来,由一个controller来进行。controller负责接收按钮的回调,确定玩家下的指令,并分配当前这个controller正在操作的unit来执行这个指令。Controller主要通过一个Run函数进行实现,这个函数输入一个选中的单位,然后对这个单位进行一系列的玩家操作。返回操作是否成功/完成。如果操作成功则进入下一个选单位流程,否则不做任何操作,继续这个操作(如流程图1所示)。
玩家的单位目前用一个基类Unit来处理,玩家的具体操作以及一系列的判定就在unit中进行实现。
首先是TurnManager的update()实现:
整个游戏进程的执行相当于全部在这个update中实现。这个update的作用相当于选中单位和对应的操作后等待操作完成,操作完成后选下一个单位,如果没有完成则阻塞等待操作完成(这里的阻塞利用了update每帧循环调用的特性来实现,不需要自己写一个死循环来阻塞)
void Update () {if (selectedUnit != null){if (controller.run(selectedUnit)){team[currenTeamIndex].ActionPoint--;selectedUnit = selectUnit();}//选中一个单位,把它放到controller进行操作,并返回一个操作是否完成的布尔值。//如果操作完成,那么这个队伍的AP减少1,并选一个新的单位//如果操作还没完成,那么不做任何事情,下一帧继续这个操作}if (team[currenTeamIndex].ActionPoint <= 0){team[currenTeamIndex].ActionPoint = team[currenTeamIndex].maxActionPoint;currenTeamIndex = 1 - currenTeamIndex;}//当一个队伍的AP小于等于0时,我们重置这个队伍的AP并将当前的控制权转移到另一支队伍上面(即改变当前索引值)}
其中的SelectUnit函数实现比较简单,目前用了一个鼠标raycast的方法来选中对应物体
GameObject selectUnit(){if (Input.GetMouseButtonUp(0)){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hit;if (Physics.Raycast(ray, out hit)){if (isIn(hit.transform.gameObject, team[currenTeamIndex].units))//判断选中的这个单位是不是在(isIn)当前的队伍列表中,只有选中当前队伍的单位才返回return hit.transform.gameObject;elsereturn null;}elsereturn null;}elsereturn null;}
有了TurnManager以后,我们就可以开始实现Controller里面的Run函数。这个函数负责给selectedUnit分配一个操作,并执行。
public bool run(GameObject selectedUnit){controllerMenu.SetActive(true);Unit unit = selectedUnit.GetComponent<Unit>();bool result = false;switch (currentState){case State.IDLE:result = false;break;case State.MOVE:result = unit.Move();break;case State.ATTACK:result = unit.Attack();break;case State.SKILL:result = unit.Cast();break;case State.SUMMON:result = unit.Summon();break;default:result = false;break;}if (result == true){currentState = State.IDLE;controllerMenu.SetActive(false);}return result;}
目前暂定有四种操作:移动、攻击、使用技能(一些随从有主动技能)和召唤(即使用卡牌)。在unit类中进行具体实现。
其中currentState由四个按钮的回调函数来设置对应的值,例如按下Move按钮对应的值就是State.MOVE。最后这个函数需要返回一个执行的结果,如果进行了操作,那么返回操作的结果,如果没有按下任何按钮(没有输入,即IDLE状态),则返回false。
最后,在Unit类中,实现了一个移动的功能
public bool Move(){if (Input.GetMouseButtonUp(0)){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hit;if (Physics.Raycast(ray, out hit)){agent.SetDestination(hit.point);}}if (agent.remainingDistance < agent.radius && agent.hasPath)return true;elsereturn false;}
一个比较简单的点击地面移动的实现。每次执行的时候检测是否有鼠标按键抬起,如果有则射一道光束到地面,并用NavMeshAgent将当前单位移动过去。设置完目的地后判断一下剩余距离是否小于agent的半径,如果是的说明到达目的地,返回true说明操作结束,可以进行下一个单位的选择和操作;如果没有,说明操作没有结束,返回false,下次update继续这个操作。
这边的实现其实会有一点bug,如果选择move以后在到达目的地前不停点击鼠标会使单位不停的重新定向,可以考虑在input里面加一个flag使得在到达目的地前只能接受一次鼠标的输入。另外在移动过程中我个人倾向于还是需要把菜单暂时关闭,这个需要调整一下controller中的实现。
代码写完以后场景就比较好处理了。我做了一个贼简单的场景,其中蓝色方块是己方单位,红色方块是敌方单位。选中效果还没有加上,但目前已经可以接近回合制式的移动各个单位了。
今天基本上把回合制的框架搭了个七七八八,下面可以往里面填unit中的几个操作的实现了。下面一个比较麻烦是一套RPG系统,例如实现血量、攻击等等机制。另外ActionPoint这个机制也要做更复杂的实现,每一个技能、每一个动作都应该有一个自己消耗的ActionPoint。最后,其实这样去实现一个回合制的流程动作应该还有不少bug,还要等后面慢慢进行重构。
一个卡牌游戏的DEMO(0)相关推荐
- EUI卡牌游戏的制作全过程
转载自:https://bbs.egret.com/forum.php?mod=viewthread&tid=50009&highlight=%E5%8D%A1%E7%89%8C 为了 ...
- 天池 在线编程 卡牌游戏(01背包)
文章目录 1. 题目 2. 解题 1. 题目 你跟你的朋友在玩一个卡牌游戏,总共有 n 张牌. 每张牌的成本为 cost[i] 并且可以对对手造成 damage[i] 的伤害. 你总共有 totalM ...
- [省选联考 2020 B 卷] 卡牌游戏 题解c++
看到这题,真的忒简单啊! 咳咳,开个玩笑.关于这题: 题目描述 轩轩某天想到了一个卡牌游戏,游戏规则如下: 初始时轩轩的手中有自左向右排成一排的 n 张卡牌,每张卡牌上有一个整数分值. 接下来,轩轩每 ...
- SPS | 卡牌游戏Splinterlands,你也可以达到最强王者
那些最好的买卖,刚开始的时候,从数字上看,几乎都会告诉你不要买.--沃伦·巴菲特 现在的链游,概念预售为多,真正能玩的少.不少项目,游戏还没做出来,就开始炒预期,或者收一笔不少的入场费. 我今天想跟大 ...
- 《刀塔传奇》最初不是卡牌游戏——专访龙图COO王彦直
http://game.donews.com/201407/2814031.shtm "最早是以投资商的身份去合作,后来又转换成发行商的身份去合作." 6月28日,<刀塔传奇 ...
- CCF201612-5 卡牌游戏(募集解题代码)
试题编号: 201612-5 试题名称: 卡牌游戏 时间限制: 3.0s 内存限制: 256.0MB 问题描述: 问题描述 小Q和小M是游戏数值策划师,他们最近在测试自己新设计的卡牌对战游戏.游戏总共 ...
- 算法题 - 卡牌游戏问题 - Python
问题描述: 卡牌游戏问题 小a和小b玩一个游戏,有 n张卡牌,每张上面有两个正整数 x, y.取一张牌时,个人积分增加 x,团队积分增加 y.求小a,小b各取若干张牌,使得他们的 个人积分相等,且 ...
- java卡牌游戏详解
代码如下: package zxc;//文件夹名称 import java.awt.*; import java.awt.event.ActionEvent; import java.awt.even ...
- 基于QT开发的开源局域网联机UNO卡牌游戏报告(附github仓库地址)
源代码: https://github.com/yunwei37/UNO-game-oop 目录 1. 需求分析 1.1. UNO卡牌游戏的基本功能 1.2. UNO卡牌游戏的规则 2. 总体设计 3 ...
最新文章
- 公司终于决定放弃微服务传统设计模式,全面拥抱 DDD!
- java mina多线程_Java多线程基础总结九:Mina窥探(1)
- Github标星2w+,热榜第一,如何用Python实现所有算法
- performance and scalability
- Facebook 最新可佩戴 AR 设备、AR 设备未来五年市场扩张、语音社交新创Swell等|Decode the Week...
- Iphone4信号,苹果象个被惯坏的孩子
- c语言入门敲打,C语言基础三(敲打键盘、寻找资料,循环语句)
- 仅需6道题轻松掌握Python异常捕获 | Python技能树征题
- 豆丁 道客巴巴 千图网 千库网 包图网 我图网 摄图网 巧办网 万方设计 中国知网 VIP会员一个月开通方法,十网通用
- 十大简单排序:桶排序
- 计算机休眠模式是关机吗,电脑中的待机、休眠、睡眠和关机状态的区别。
- edge搁置标签页_如何自定义Microsoft Edge的新标签页
- java数字转汉字大写(全)
- 关于斐讯K2无管理员密码路由器重置问题
- c++中字符数组与字符串的转换
- 科研 | 国家自然科学基金委 | 资助项目简介
- 【181018】基于MFC文档方式制作的飞碟射击游戏
- HTML七种加密解密
- ubuntu系统matlab2021a安装及设置matlab快捷方式
- 张宇1000题线性代数 第一、二章 行列式、余子式和代数余子式的计算