我正在开发一个游戏引擎。它应该是一个基于实体/组件的实体。为了开发游戏本身,我想使用某种脚本语言来实际创建实体。
例如,如果我想添加一种对玩家具有侵略性的怪物,它将是一个具有多个组成部分的实体。这些组件会随着怪物类型的变化而变化,因此,如果我有一百种不同类型的怪物,那么在我的游戏中,我就不必直接在游戏代码中为每个怪物创建新的方法。
我应该使用脚本语言来描述该实体,还是使用组件?更一般而言,我应该如何在游戏中使用脚本?
我正在开发一个游戏引擎。它应该是一个基于实体/组件的实体。为了开发游戏本身,我想使用某种脚本语言来实际创建实体。
例如,如果我想添加一种对玩家具有侵略性的怪物,它将是一个具有多个组成部分的实体。这些组件会随着怪物类型的变化而变化,因此,如果我有一百种不同类型的怪物,那么在我的游戏中,我就不必直接在游戏代码中为每个怪物创建新的方法。
我应该使用脚本语言来描述该实体,还是使用组件?更一般而言,我应该如何在游戏中使用脚本?
Answers:
我的游戏使用实体组件框架并使用脚本来定义实体(这不会直接定义行为,我将在最后详细讨论)。脚本定义了用于创建每个实体的实际组件。它使用我创建的简单脚本语言。这是我的脚本之一的简化版本:
ENTITY:"Goblin"
{
description="It's currently their age."
commonname="goblin"
pluralCommonName="goblins"
childname="gob'in"
pluralChildName="gob'ins"
active=Nocturnal
tags=Mobile
baseAttributes="OrganicMobileCreature"
[Model]{
meshname="Goblin"
texturename="GoblinTexture"
}
[Motion]{
maxvelocity=0.01:0.015
locomotion=Walk,Swim
}
[Skills]{
ALL=0.01:0.05,Mine=8.3:8.8,PlaceCube=8.3:8.8
}
[Inventory]{
maxItems=2
Allow=ALL
Disallow=NONE
}
}
其中大部分是自我描述,但以下是一些要点:
baseAttributes
标记引用了另一个脚本文件,该文件定义了我不想多次重新定义的通用组件。它包含类似的组件position
,liferequirements
依此类推。如果再次在此处定义任何组件,则此组件将覆盖通用组件。[NAME] { }
集合都定义了一个将添加到这些实体的新组件。0.01:0.015
),当创建新的妖精时,它将使用具有该范围内随机值的组件来创建。因此,每个妖精的技能和速度都会略有不同。此设置定义了所有妖精将具有放置立方体和挖掘的非常好的技能,这实际上只是出于我自己的测试目的。但是,我敢肯定,您可以猜到,将值更改为我想要的值非常容易。这整个过程包括创建一个自定义解析器,某种用于保存实体定义的结构(我称我的Lexicon!)和一个用于获取这些实体定义并生成新实体的工厂。对我来说,该系统仍处于早期阶段,但事实证明它确实非常好。这是一个非常强大的系统,用于快速定义实体,并允许您使用创建的组件来创建所需的任何实体。如果您不愿意创建自己的解析器,我认为XML会很好地工作。我将我的推后递归解析器转换为我自己,该解析器是用某种编成的编程语言编写的。
如您所见,这定义了实体。我提到它并没有直接定义行为。但是,它可以轻松地定义诸如仇恨的敌人以及对所述敌人的反应有多积极。这就像定义用于控制此类行为的任何组件一样简单。我的实体还具有定义以下内容的智能组件(未显示):
无论您的定义如何,都是系统驱动该组件中的数据,从而影响实体的行为。
if player.hasPoints(10) then i++ end skillTree[i]
将是一些伪代码。但是,我不知道该问题与该职位有何关系。
如果您真正需要的只是一种定义Monster组件的方法,那么XML可以很好地在C#和Java上快速实现。
您的xml可能是
<?xml version="1.0" encoding="UTF-8"?>
<mobs>
<mob>
<personality>Aggressive</personality>
<intelligence>20</intelligence>
</mob>
</mobs>
然后您的Mob类可能看起来像。(Java)
public class Mob {
private IPersonality personality;
private Integer intelligence
//** Getters & Setters **//
}
IPpersonality是接口。
然后,您可以加载xml并通过工厂解析每个值。
例如,将Personality Value解析到PersonalityFactory中,这很简单:
public IPersonality getPersonality(String personalityName) {
if(personalityName.equals("Aggressive")) {
return new AggressivePersonality();
}
else if(personalityName.equals("Passive")) {
return new PassivePersonality();
}
else {
//Maybe allow for no personality (We all know monster like that ;) )
return null;
}
}
然后你可以像这样建立暴民
Mob mob = new Mob();
mob.setPersonality(getPersonality(xmlValue));
mobList.add(mob);
关键是您的引擎知道xml的格式,并拥有所有需要的工厂。
xml的优点之一是您可以定义自己的模式以确保格式始终正确,请参见此处。
希望这可以帮助
我认为Python很好。如果要向程序中添加脚本功能,则LUA通常也是不错的选择。
您可以使用XML来描述怪物的行为,这将涉及实际游戏代码中的一些编码,因为您将根据行为(速度,怪物使用的武器类型,等)在您的游戏代码中使用的行为。
如果使用脚本引擎(例如LUA),则可以将此代码从预编译程序转移到运行时加载的脚本文件中。为此,您必须将“怪物”的API公开给脚本引擎。这样您就可以从外部调用怪物游戏代码的方法。