从零开始做一个SLG游戏(七):游戏系统以及配置表

作者:观复 2019-10-23

本文主要是来梳理下游戏内的基本系统(虽然只是照搬polytopia的,但是还是要总结一下),并预先做一些配置表,并实现读取。

一、经济系统


1.总述

经济系统可以是整个游戏的核心。在本游戏中只有一种资源:金币。

每个回合都会获得一定数量的金币。

金币主要有两种来源:城市基本产出和建筑的额外产出。

金币的消耗方式有三种:1.建造建筑2.解锁科技3.建造士兵,而士兵维持是不需要额外的金币的。

2.城市的建设

和文明类游戏一样,每个地块都有其所属的城市。

在城市等级比较低的时候,只有该城市周围1格的地块属于那座城市。而城市等级到达一定程度时,可以解锁让城市范围扩张为2格。

地块的开发分两种:对于资源的收集和对于地形的开发。

每个地块上都有对应的地形,针对不同的地形,可以建设不同的建筑,比如森林地形可以建造伐木场,沃土地形可以建造农田等。

而在这个地形的基础上,有些地块可能会有一些额外的资源,比如动物和植物等,玩家在前期可以通过采集的方式来增加人口。

3.配置表设计

以下是配置表的设计:

首先是地形表。


在本系列最早的文章内,已经介绍了地形的生成方法,前文定义了Water,Plain,Mountain三种地形,对应海拔1,2,3。现在再加一种新的海拔0用以代表深海。这样4种高度的地形就齐了。

而同一海拔的地形会有多种形态,比如海拔为2的平原将有平原、沃土、森林三种情况,通过科技这几种状态甚至可以相互转换。而区分这几种状态的方式是增加额外的装饰物。而资源id便是装饰物的文件名,填0表示没有任何装饰物。

移动力花费指的是士兵移动走上去所需要消耗的移动点数。

然后是资源表。


和上面一样,资源id指的是资源对应的文件名,生成地图的时候,将根据所属的海拔分配资源。比如鲸鱼就只能出现在海拔为0的深海区域内。

奖励类型分两种,类型1指的是给所在的城市增加人口,类型2指的是直接增加金币。

接下来是建筑表:


地形指的是建造所需要的地形,对于的是地形表中的id,其中34这种两位数的id指的是3和4两种地形都可以,因为地形种类没有超过10,所以就用这种方式实现了(如果超过10其实也可以,不过需要把10以上的数字改为abcd)

邻近建筑指的是有些建筑建造,需要周边地块拥有某些建筑。比如谷仓建造需要旁边的地块上有农田。

作用类型1指的是直接增加人口,比如码头的作用就是给该城市增加2人口。

作用类型2指的是,根据周边地块某建筑的数量来加人口,比如谷仓的效果是周围有一个农田就加1人口,所以谷仓的邻近建筑是3(农田),作用类型是2,效果是1。

作用类型3指的是根据周围某建筑的数量直接增加回合金币,这也是唯一的一个直接通过建筑增加回合金币的途径。

最后是城市表:


后续实现的时候会根据效果id实现对应的效果。其中1,2,3级城市的2个效果是2选一的。

二、科技系统

科技系统简单说就是花费金币解锁科技,而随着城市数量的增加,科技花费也要增加。

公式如下:

科技花费=(基础花费+(城市数量-1)*科技等级)*(1-科技减免)

科技分为3个等级,其基础花费分别为5,6,7

科技减免指的是某个科技点了之后会有一个科技花费20%减免的效果。

下面是科技花费表:


很简单的一张表。

下面是科技表:


这张表数量有点多,并且作用代码一栏我没填。将来实现的时候会把这张表完善起来。

三、兵种系统

先把兵种表附上:


兵种就不多说了,大部分SLG游戏都差不多。

比较注意的是:

1.船是无法直接制造的。陆地单位在码头处下海后,能变成一艘小船,小船的血量以及血量上限和该单位在陆地上时相当。

2.A攻击了B,如果A在B的攻击范围内,则B会在同时进行一次反击。

攻击伤害=攻击方血量*攻击方攻击/(防守方防御*(1+防守方防御加成))

反击伤害=反击方血量*(反击方防御*(1+反击方防御加成))/攻击方攻击

四、配置表的导入和读取

1.配置表的保存

配置表的我是用excel保存的,导出方式是导出为csv文件。


csv文件的导出很简单,先切换到想要保存的那个excel标签页。


然后选择另存为。


然后在保存类型的时候切换到csv就行了,记得文件名也要改一下,因为这次导出的只是一个标签。


然后再在下面这个目录中建立CSV文件夹,并且把想要读取的csv文件都放进去。

2.配置表格式的修改

这是的配置表有两个问题:首先unity对csv格式据说不是很支持,最好改成txt格式。然后就是,这时候保存出来的编码是非utf-8的,所以unity直接读会读不出来。

这两个问题手动操作肯定也是能够解决的(用txt打开,改编码然后另存为txt格式),但是太麻烦了,尤其随着制作的推进,表越来越多,每次都手动修改会浪费大量时间。

这时候就需要做一个内置工具了:

  1. using System.IO;
  2. using System.Text;
  3. using UnityEditor;
  4. using UnityEngine;

  5. public class TranslateUTF8
  6. {
  7.         [MenuItem("MyMenu/UTF8Transform")]
  8.         static private void TransformUTF8()
  9.         {
  10.                 string spriteDir = Application.dataPath + "/Resources/CSV";
  11.                 DirectoryInfo rootDirInfo = new DirectoryInfo(spriteDir);
  12.                 foreach (FileInfo csvFile in rootDirInfo.GetFiles("*.csv", SearchOption.AllDirectories))
  13.                 {
  14.                         string csvpath = csvFile.FullName;
  15.                         Translate(csvpath);
  16.                 }
  17.                 Debug.Log("utf8转换成功");
  18.         }

  19.         private static void Translate(string path)
  20.         {
  21.                 string content = File.ReadAllText(path, Encoding.Default);
  22.                 File.Delete(path);
  23.                 File.WriteAllText(path.Remove(path.LastIndexOf("."))+".txt", content, Encoding.UTF8);
  24.                 Debug.Log(path + " 转换完毕");
  25.         }
  26. }
复制代码

这是我以前写的一个转化工具,功能是把Resources/CSV这个文件夹下的所有csv文件转化成utf-8的txt文件,并把原来的csv文件删除掉。

在项目中新建一个脚本文件,然后把这段代码复制进去把原来的替换掉就能使用。


这时候,回到unity界面,会出现一个MyMenu菜单栏,进去后点击一下就行了。

3.配置表的读取


配置表是csv格式的。csv格式的意思是,原excel中,每一行的单元格之间,用逗号分隔开,如上图。

所以在填写配置表时,要尽量避免逗号的出现。以下是代码:

  1. public class CSVUtil
  2. {

  3.         public static List<string[]> Process(string filePathName)
  4.         {
  5.                 TextAsset asset = Resources.Load(filePathName) as TextAsset;
  6.                 string file = asset.text;
  7.                 List<string[]> ls = new List<string[]>();
  8.                 if (file == "")
  9.                 {
  10.                         return default(List<string[]>);
  11.                 }
  12.                 else
  13.                 {
  14.                         string[] strList = file.Split("\r\n"[0]);
  15.                         foreach (string str in strList)
  16.                         {
  17.                                 string s = str.Replace("\n", "");
  18.                                 if (s != "")
  19.                                 {
  20.                                         ls.Add(s.Split(","[0]));
  21.                                 }
  22.                         }
  23.                         return ls;
  24.                 }
  25.         }
  26. }
复制代码


"\r\n"是换行符,但不知道是什么原因,我用"\r\n"来分割字符串后,还是有"\n"留下来,所以我在下面处理的时候把“\n”又去掉了一次。

相关阅读:
从零开始做一个SLG游戏(一):六边形网格
从零开始做一个SLG游戏(二):用mesh实现简单的地形
从零开始做一个SLG游戏(三):用unity绘制图形
从零开始做一个SLG游戏(四):UI系统之主界面搭建
从零开始做一个SLG游戏(五):UI系统之弹窗功能

从零开始做一个SLG游戏(六):UI系统扩展

作者:观复
专栏地址:https://zhuanlan.zhihu.com/p/70155323


最新评论
暂无评论
参与评论

商务合作 查看更多

编辑推荐 查看更多