我目前正在用C ++开发3D动作/ RPG游戏,我想在选择脚本语言来编写游戏的AI方面有一些建议。我的团队来自一个改装背景,事实上我们仍然在完成哥特式游戏的模型工作。在那个游戏中(我们也从中得到了灵感)使用了DAEDALUS语言(由游戏制作者Piranha Bytes创建)。 Here is a full description of said language.
要注意的主要问题是它使用的实例比类更多。游戏引擎是关闭的,因此人们只能猜测这种语言的内部实现,但我在脚本语言中寻找的主要内容(理想情况下,它非常相似,但最好也比DAEDALUS更强大)是事实有事实上的3'分离'的类 - 即类,实例和(实例的实例?)。
如果我提供一个例子,我认为理解我想要的东西会更容易。定期NPC。首先,你定义了一个类(我理解)镜像引擎内的(类或结构):
CLASS C_NPC
{
VAR INT id ; // absolute ID des NPCs
VAR STRING name [5] ; // Namen des NPC
VAR STRING slot ;
VAR INT npcType ;
VAR INT flags ;
VAR INT attribute [ATR_INDEX_MAX] ;
VAR INT protection [PROT_INDEX_MAX];
VAR INT damage [DAM_INDEX_MAX] ;
VAR INT damagetype ;
VAR INT guild,level ;
VAR FUNC mission [MAX_MISSIONS] ;
var INT fight_tactic ;
VAR INT weapon ;
VAR INT voice ;
VAR INT voicePitch ;
VAR INT bodymass ;
VAR FUNC daily_routine ; // Tagesablauf
VAR FUNC start_aistate ; // Zustandsgesteuert
// **********************
// Spawn
// **********************
VAR STRING spawnPoint ; // Beim Tod, wo respawnen ?
VAR INT spawnDelay ; // Mit Delay in (Echtzeit)-Sekunden
// **********************
// SENSES
// **********************
VAR INT senses ; // Sinne
VAR INT senses_range ; // Reichweite der Sinne in cm
// **********************
// Feel free to use
// **********************
VAR INT aivar [50] ;
VAR STRING wp ;
// **********************
// Experience dependant
// **********************
VAR INT exp ; // EXerience Points
VAR INT exp_next ; // EXerience Points needed to advance to next level
VAR INT lp ; // Learn Points
};
然后,您还可以定义原型(设置一些默认值)。但是你如何实际定义一个NPC是这样的:
instance BAU_900_Ricelord (Npc_Default) //Inherit from prototype Npc_Default
{
//-------- primary data --------
name = "Ryzowy Ksiaze";
npctype = NPCTYPE_GUARD;
guild = GIL_BAU;
level = 10;
voice = 12;
id = 900;
//-------- abilities --------
attribute[ATR_STRENGTH] = 50;
attribute[ATR_DEXTERITY] = 10;
attribute[ATR_MANA_MAX] = 0;
attribute[ATR_MANA] = 0;
attribute[ATR_HITPOINTS_MAX]= 170;
attribute[ATR_HITPOINTS] = 170;
//-------- visuals --------
// animations
Mdl_SetVisual (self,"HUMANS.MDS");
Mdl_ApplyOverlayMds (self,"Humans_Arrogance.mds");
Mdl_ApplyOverlayMds (self,"HUMANS_DZIDA.MDS");
// body mesh ,bdytex,skin,head mesh ,headtex,teethtex,ruestung
Mdl_SetVisualBody (self,"Hum_Body_CookSmith",1,1,"Hum_Head_FatBald",91 , 0,-1);
B_Scale (self);
Mdl_SetModelFatness(self,2);
fight_tactic = FAI_HUMAN_STRONG;
//-------- Talente --------
Npc_SetTalentSkill (self,NPC_TALENT_1H,1);
//-------- inventory --------
CreateInvItems (self, ItFoRice,10);
CreateInvItem (self, ItFoWine);
CreateInvItems(self, ItMiNugget,40);
EquipItem (self, Heerscherstab);
EquipItem (self, MOD_AMULETTDESREISLORDS);
CreateInvItem (self, ItMi_Alchemy_Moleratlubric_01);
//CreateInvItem (self,ItKey_RB_01);
EquipItem (self, Ring_des_Lebens);
//-------------Daily Routine-------------
daily_routine = Rtn_start_900;
};
FUNC VOID Rtn_start_900 ()
{
TA_Boss (07,00,20,00,"NC_RICELORD");
TA_SitAround (20,00,24,00,"NC_RICELORD_SIT");
TA_Sleep (24,00,07,00,"NC_RICEBUNKER_10");
};
如您所见,实例声明更像是构造函数,从内部设置值和调用函数。如果不是另外一件事,这仍然不会造成太多问题:这个实例的多个副本。例如,你可以产生多个BAU_900_Ricelord
,并且每个都跟踪它自己的AI状态,生命点等。
现在我认为实例在引擎内部表示为int(甚至可能是NPC的id),因为每当(在脚本中)使用表达式BAU_900_Ricelord
时,它只能被赋值为int变量,以及在NPC上运行的大多数函数都采用该int值。但是要直接修改其生命值等,你必须做var C_NPC npc = GetNPC(Bau_900_Ricelord); npc.attribute[ATR_HITPOINTS] = 10;
之类的事情,即得到代表它的实际C_NPC对象。
最后回顾一下 - 是否有可能在你所知道的任何脚本语言中获得这种行为,或者我不得不自己制作?或者也许有一种更好的方式来代表NPC及其行为。用于脚本编写的IDEAL语言将是C#,因为我只是喜欢这种语言,但不知何故我怀疑在C#中尝试实现类似的行为是可行的还是确实可行。
非常感谢
答案 0 :(得分:3)
C#可以用作脚本语言。
除了c#之外,lua作为游戏脚本语言非常受欢迎
您的npc示例可以解决如下:
答案 1 :(得分:1)
我会使用Javascript。我自己正在开发一款游戏引擎,用于实现Chrome中使用的V8 javascript引擎。它非常容易实现,Javascript是一种非常强大的语言,完全基于原型。
答案 2 :(得分:1)
我认为,虽然你希望语言支持3级/类实例,但如果你实际上只有1,那么它将有所帮助。
静态语言通常有两个级别 - 在编译时定义的“类”和在运行时从类创建的“实例”。这很有道理,因为确切地知道你想要预先确定多少个类是很实际的,并且通常不确切地知道有多少个实例。类成为千篇一律,实例是cookie。
但最终,抛开类和实例的概念是完全不同的,并认为一个类是一个东西,(a)允许你创造新的东西和(b)作为这些新东西应该如何应该的中心参考法案。那些事情反过来也可以创造新事物,等等。
在像C ++和Java这样的语言中,我们通常通过使用类构造函数定义的一组属性分配内存块来执行(a),并且(b)通过将一些引用保留回类的方法(例如,通过一个v-table)。但是你可以只复制一个对象,包括其中的所有方法引用,其中一个将是该对象的'实例'的构造函数。这是prototype-based programming并且提供了一个非常简单的继承模型,因为你的“类”与任何其他对象是一样的,除了它们提供了一种创建计为实例的新对象的方法。
恰巧世界上最流行的脚本语言 - 可能是世界上最流行的语言 - 为您提供原型继承。 Javascript就是我所指的,它是嵌入游戏中的一个非常好的选择,其优点是被开发人员广泛认可并且在今天非常积极地工作。网上有很多教程,但其中一个涉及各种继承方法的是here。可能需要一段时间才能习惯,特别是如果你来自传统的OO背景,并且有明确的课堂/实例部门,但是值得学习差异并评估自己的利弊。