第八章 游戏中的数据(Data in Game)
在之前的章节中,我们进行地图对象的生成,移动等操作。
这一章本来可以进行战斗的编写,不过数据缺失是一个问题。
所以这一章我们先来建立一些数据,以及如何编辑它们,是否需要生成配置文件等。
文章目录
一 创建新项目(Create New Project)
这一小节,我们来创建一个新项目专门处理数据,并且添加一些必要的结构。
1 数据的一些说明(Data Description)
我们先来谈谈数值型的数据,数值型的数据在游戏中是最为常见的,就算只是一个小游戏也包含类似分数这样的数值。同样的,我们的SRPG游戏也包含许多数值数据。
SRPG中常见的基本数值数据:生命值,魔法值(怒气,能量等),攻击力,防御力。
当然,我们上一章移动所用的移动力也是数值型的,还有攻击范围等。
这些静态数据的存储方式有多种,可以直接在Unity中保存成ScriptableObject
,也可以保存成配置文件(txt, xml, json, csv
等)。我们的大部分数据拿xml
作为本次配置文件,少部分其它。
SRPG也是RPG,所以它们很近似,甚至相同。在RPG游戏的战斗中,最常用的属性计算就是角色属性与物品属性(武器和装备等)结合,在SRPG中也同样是这样。且职业同样限制了使用的武器种类。不过每种游戏都有细微的差别,在战斗情况中典型的是:
-
《火焰之纹章》系列:武器损坏或没有武器无法进行攻击,攻击范围和武器有关;同时魔法(魔法书)也归类为武器,而不是技能;武器都有耐久度,耐久度归零后武器损坏或降低大量战斗属性;游戏中只有被动技能。
-
《新神奇传说3》《曹操传》等:攻击范围(攻击和技能)和人物或职业有关。
-
《机器人大战》系列:攻击范围只与技能有关,且技能类似于《FE》系列的武器,只是把耐久换成了弹药,弹药使用完不能进行攻击,也有无限弹药的技能(比如近战技能)。
以上只是举了一些例子,可能表达有误,但都大同小异。
2 创建项目(Create Project)
好了,说了这么多,我们来创建一个新项目来完成数据上的编辑。
打开Unity,创建新的项目并命名为“SRPG_Datas”。
由于我们需要用到主工程的少部分东西,所以复制主工程的如下文件到新工程:
-
ClassType.cs
-
WeaponType.cs
-
TerrainType.cs
-
MoveConsumptionInfo.cs
并加入我们的基础框架(见第六章):
-
Framework_Library.dll
-
Framework_Library_Editor.dll
3 通用战斗属性(Common Fight Properties)
项目已经创建好了,说回来我们的游戏,我们的数据模板参考《FE4》,先来看战斗属性。
在战斗属性中,有些属性在各个地方都存在,比如“力量(STR)”,“防御(DEF)”或“速度(SPD)”等,在人物,武器和升级属性中都存在,这样的属性我们单独建立一个枚举与结构体表示。
战斗属性枚举(FightPropertyType.cs):
using System;
namespace DR.Book.SRPG_Dev
{
[Serializable]
public enum FightPropertyType : int
{
/// <summary>
/// 力量
/// </summary>
STR = 0,
/// <summary>
/// 魔力
/// </summary>
MAG = 1,
/// <summary>
/// 技巧
/// </summary>
SKL = 2,
/// <summary>
/// 速度
/// </summary>
SPD = 3,
/// <summary>
/// 防御
/// </summary>
DEF = 4,
/// <summary>
/// 魔防
/// </summary>
MDF = 5,
/// <summary>
/// 长度
/// </summary>
MaxLength
}
}
关于战斗属性,我们有枚举,其实可以用一个int[] fightProperties = new int[(int)FightPropertyType.MaxLength];
表示,但我这里还是把它拆开了。
战斗属性(FightProperties.cs):
using System;
using System.Xml.Serialization;
namespace DR.Book.SRPG_Dev.Models
{
[Serializable]
public struct FightProperties
{
/// <summary>
/// 力量
/// </summary>
[XmlAttribute]
public int str;
/// <summary>
/// 魔力
/// </summary>
[XmlAttribute]
public int mag;
/// <summary>
/// 技巧
/// </summary>
[XmlAttribute]
public int skl;
/// <summary>
/// 速度
/// </summary>
[XmlAttribute]
public int spd;
/// <summary>
/// 防御
/// </summary>
[XmlAttribute]
public int def;
/// <summary>
/// 魔防
/// </summary>
[XmlAttribute]
public int mdf;
}
}
我们在战斗属性中加入获取的索引器:
[XmlIgnore]
public int this[FightPropertyType type]
{
get
{
switch (type)
{
case FightPropertyType.STR:
return str;
case FightPropertyType.MAG:
return mag;
case FightPropertyType.SKL:
return skl;
case FightPropertyType.SPD:
return spd;
case FightPropertyType.DEF:
return def;
case FightPropertyType.MDF:
return mdf;
default:
return 0;
//throw new IndexOutOfRangeException("Not Supported");
}
}
}
在进行战斗时,我们是要结合角色信息,装备信息和其它信息的属性。所以在获取时,我们最好能够直接运用加法运算,以获得累加后的属性。(并不需要重载减法,因为减少属性本身就是负的,相加即可)
public static FightProperties operator +(FightProperties lhs, FightProperties rhs)
{
FightProperties fight = new FightProperties
{
str = lhs.str + rhs.str,
mag = lhs.mag + rhs.mag,
skl = lhs.skl + rhs.skl,
spd = lhs.spd + rhs.spd,
def = lhs.def + rhs.def,
mdf = lhs.mdf + rhs.mdf,
};
return fight;
}
4 可用武器(Available Weapons)
可用武器是指角色可以装备并使用的武器列表,在《火焰之纹章》系列中,每个人能够使用的武器是不同的,这是由他们的职业决定的。我们已经有了武器类型(WeaponType.cs
)。就像之前那样,我们建立一个结构体来表示可用的武器等级。
在FE4中,武器只有4个等级(C,B,A,星),我这里是F到星,不过这都是可以改变的;比如,int
的数值可以代表几星武器。
可用武器(AvailableWeapons.cs):
using System;
using System.Xml.Serialization;
namespace DR.Book.SRPG_Dev.Models
{
/// <summary>
/// 可用武器等级:
/// 0 不可用,
/// 1 F,2 E,3 D,4 C,5 B,6 A,7 S,8 星
/// </summary>
[Serializable]
public struct AvailableWeapons
{
/// <summary>
/// 剑
/// </summary>
[XmlAttribute]
public int sword;
/// <summary>
/// 枪
/// </summary>
[XmlAttribute]
public int lance;
/// <summary>
/// 斧
/// </summary>
[XmlAttribute]
public int axe;
/// <summary>
/// 弓
/// </summary>
[XmlAttribute]
public int bow;
/// <summary>
/// 杖
/// </summary>
[XmlAttribute]
public int staff;
[XmlIgnore]
public int this[WeaponType type]
{
get
{
switch (type)
{
case WeaponType.Sword:
return sword;
// 其它由于没有动画,全部都禁用了Obsolete。
//case WeaponType.Lance:
// return lance;
//case WeaponType.Axe:
// return axe;
//case WeaponType.Bow:
// return bow;
//case WeaponType.Staff:
// return staff;
default:
return 0;
//throw new IndexOutOfRangeException("Not supported.");
}
}
}
}
}