怎样理解脚本.docx
- 文档编号:6113052
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:80
- 大小:1.23MB
怎样理解脚本.docx
《怎样理解脚本.docx》由会员分享,可在线阅读,更多相关《怎样理解脚本.docx(80页珍藏版)》请在冰豆网上搜索。
怎样理解脚本
理解脚本
使用这样一个有限的行为集合,就不再需要复杂的可编译脚本语言了。
相反,只需要告诉脚本系统要使用哪些行为,以及这些行为将使用怎样的选项以实现游戏的功能。
对于这种方法,最大的好处就是不再需要为指定一个简单的行为而罗列代码行,可以通过编号来引用行为和选项。
举个例子,PlaySound行为的编号为4,而且该行为仅要求一个输入,即播放声音的编号。
在脚本中只存储两个数值:
一个对应于行为,另一个代表了声音。
使用数值表示行为(代替文本)的方法可以使这种类型脚本的处理既快速又简单。
MadLibScripting系统的设计
创建在游戏中想到的行为,可以通过创建或编辑脚本来填充那些空白点(称之为条目entries)。
对于每个行为,请明确提供一个可供空白条目填充的选项列表,它的类型可以从一行文本到一串数字。
接着将行为和空白条目进行编号,以便脚本系统可以引用它们,以下是一些行为列表的范例:
1.Character(*NAME*)takes(*NUMBER*)damage.
2.Print(*TEXT*).
3.Playsoundeffecttitled(*SOUND_NAME*).
4.Playmusictitled(*MUSIC_NAME*).
5.Createobject(*OBJECT_NAME*)atcoordinates(*XPOS*),(*YPOS*).
6.Endscriptprocessing.
在这6种行为中,都有0个或多个空白条目位于括号内,每个空白条目包含了一个文本字符串或者一个数字,这个行为与可能条目(以及条目的类型)的列表被称之为行为模板(actiontemplate),如下图所示:
一旦使用了行为模板,就可以使用它们的编号而不是行为的文本进行引用(文本的存在只是为了使用户能够更容易理解每个行为所实现的功能)。
MLS系统的编写
为了使MLS系统功能尽可能强大,需要设计它以便可以支持多重行为的模板,而且每个行为模板都包含不受数量限制的行为。
以这种方式,就可以将系统复用到任何想要的项目中。
当一个脚本完成时,将脚本读入到引擎中,并处理各自的行为,为每个由脚本编辑器所输入的行为使用指定的条目。
一个行为模板需要保存行为的列表,包括文本、条目编号以及每个条目的数据。
每个行为按它们在列表中的索引值进行编号,同时每个行为中的空白条目也被加以编号。
可以为每个条目指定一种类型(文本型、整数型、浮点型、布尔型、多重选择型),如下所示:
0.Noentrytype
1.Textentry
2.Booleanvalue
3.Integernumber
4.Floatnumber
5.Multiplechoice(achoicefromalistoftextselections)
每个条目类型都有一个独特的特征,字符串类型的长度是可以变化的,数字型可以是两个数字范围之间的任何数值,而布尔值可以是TRUE或者FALSE。
至于多重选项型,每个选项都有它自己的文本字符串(脚本从一个列表中获取选项,而且所选选项的索引编号比它的文本更适用)。
行为可以采用如下格式:
Action#1:
Spelltargets(*MULTIPLE_CHOICE*).
Possiblechoicesforblankentry#1:
1.Playercharacter
2.Spellcaster
3.Spelltarget
4.Nobody
我们通过创建结构体ENTRY_RULE和ACTION来处理条目规则与行为。
enumENTRY_TYPE{ENTRY_NONE=0,ENTRY_TEXT,ENTRY_BOOL,ENTRY_INT,ENTRY_FLOAT,ENTRY_CHOICE};
typedefchar*char_ptr;
typedefintBOOL;
//============================================================================
//Structurestostoreinformationaboutasingleblankentry.
//============================================================================
typedefstructENTRY_RULE
{
longtype;//typeofblankentry(ENTRY_TEXT,ENTRY_BOOL,
)
//Thefollowingtwounionscontainthevariousinformationaboutasingleblankentry,
//fromthemin/maxvalues(forintandfloattypes),aswellasthenumberofchoices
//inamultiplechoiceentry.
union
{
longlong_min;//minvalueoflongtype
floatfloat_min;//minvalueoffloattype
longnum_choices;//numberofchoicesinlist
};
union
{
longlong_max;//maxvalueoflongtype
floatfloat_max;//maxvalueoffloattype
char_ptr*choices;//choicetextarray
};
//structureconstructortocleartodefaultvalues
ENTRY_RULE()
{
memset(this,0,sizeof(*this));
}
//structuredestructortocleanupusedresources
~ENTRY_RULE()
{
//specialcaseforchoicetype
if(type==ENTRY_CHOICE&&choices!
=NULL)
{
for(longi=0;i delete[]choices[i]; delete[]choices; } } }*ENTRY_RULE_PTR; //============================================================================ //Structurethatstoreasingleaction. //============================================================================ typedefstructACTION { longindex;//actionindex[0,numberofaction-1] chartext[256];//actiontext shortnum_entries_rule;//numberofentriesinaction ENTRY_RULE_PTRentries_rule;//arrayofentrystructures ACTION*next;//nextactioninlinkedlist ACTION() { memset(this,0,sizeof(*this)); } ~ACTION() { delete[]entries_rule; deletenext; } }*ACTION_PTR; 行为模板被存储为文本文件,同时每个行为的文本被包括在括号中。 每个包含条目的行为(标记为文本中的波浪字符)紧跟着是条目数据的列表。 每个条目由一个描述条目类型(文本型、布尔型、整型、浮点型或选项型)的单词开始。 对于文本类型而言并没有更多的需要信息,对于布尔类型来说也是如此。 而作为整数和浮点型,则要求一个最小值和最大值。 最后,选项类型条目后跟着的是可供选择的编号以及每个选项的文本(包括在引号里)。 如下所示: "Ifflag#~is~then" INT0255 BOOL "Else" "Endif" "Setflag#~to~" INT0255 BOOL "Print~" TEXT "Movecharacterto~,~,~" FLOAT0.02048.0 FLOAT0.02048.0 FLOAT0.02048.0 "Character~~~~points" CHOICE3 "MainCharacter" "Caster" "Target" CHOICE2 "Gains" "Looses" INT0128 CHOICE2 "Hit" "Magic" "Engageinbattlesequence#~" INT065535 "EndScript" 第二篇 脚本条目的创建 因为ENREY_RULE结构仅包含了行为和条目的规则,所以需要另外的结构数组去存储每个条目的数据。 这些新的结构包括了在条目中所使用的文本、布尔值、多重选项,我们使用结构体ENTRY来表示。 //============================================================================ //structurethatstoreallentriesfactinformation. //============================================================================ typedefstructENTRY { longtype;//typeofblankentry(ENTRY_TEXT,ENTRY_BOOL, ) union { longio_value;//usedforsaving/loading longlength;//lengthoftext(0terminator) longselection;//selectioninchoice BOOLbool_value;//BOOLvalue longlong_value;//longbalue floatfloat_value;//floatvalue }; char*text;//entrytextbuffer ENTRY() { memset(this,0,sizeof(*this)); } ~ENTRY() { delete[]text; } }*ENTRY_PTR; 在处理脚本条目的过程中,当一个脚本出现了许多条目时,最麻烦的问题也就接踵而来。 脚本中的每个行为都要求一个相匹配的ENTRY_RULE结构,其依次包含了一定数量的ENTRY结构。 为了更好地处理一个脚本的结构,还需要其他的结构来记录属于脚本行为的每个条目,我们将它命名为SCRPT。 //============================================================================ //structurethatstoreall //============================================================================ typedefstructSCRIPT { longaction_index;//[0,numberofactions-1] longnum_entries;//numberofentriesinthisaction ENTRY_PTRentries;//arrayofentries SCRIPT*prev;//previousinlinkedlist SCRIPT*next;//nextinlinkedlist SCRIPT() { memset(this,0,sizeof(*this)); } ~SCRIPT() { delete[]entries; deletenext; } }*SCRIPT_PTR; prev和next维护了整个脚本的连接列表,为了构造SCRIPT结构的连接列表,从代表脚本的第一个行为的根结构开始,然后使用next和prev将SCRIPT结构连接起来,如下图所示: ACTION_TEMPLATE类的整合 理解了行为模板所使用的结构以及所容纳的脚本后,现在开始将它们整合到一起创建一个加载并处理脚本的类。 //============================================================================ //Thisclassencapsulatescriptsaveandload. //============================================================================ typedefclassACTION_TEMPLATE { private: longm_num_actions;//numberofactionsintemplate ACTION_PTRm_root_action;//listoftemplateactions public: ACTION_TEMPLATE(); ~ACTION_TEMPLATE(); BOOLload_actions(constchar*filename); voidfree(); longget_num_actions(); ACTION_PTRget_root_action(); ACTION_PTRget_action(longact_index); SCRIPT_PTRcreate_script(longact_index); longget_num_entries_rule(longact_index); ENTRY_RULE_PTRget_entry_rule(longact_index,longentry_rule_index); voidexpand_default_action_text(char*buffer,ACTION_PTRaction); BOOLexpand_action_text(char*buffer,SCRIPT_PTRscript); }*ACTION_TEMPLATE_PTR; 实现: //------------------------------------------------------------------------ //Getquotedlinefromfile. //------------------------------------------------------------------------ staticBOOL_get_quoted_line(FILE*fp,char*data,longmax_data_size) { intc; longpos=0; //readuntilaquoteisreached(orEOF) while (1) { if((c=fgetc(fp))==EOF) returnFALSE; if(c=='"') { //readuntilnextquot(orEOF) while (1) { if((c=fgetc(fp))==EOF) returnFALSE; //returntextwhen2ndquotefound if(c=='"') { data[pos]=0; break; } //addacceptabletexttoline if(c! =0x0a&&c! =0x0d)//ifcharacterisnotlinefeed,notcarriage. { if(pos data[pos++]=c; } } break; } } returnTRUE; } //------------------------------------------------------------------------ //Getwordfromfile. //------------------------------------------------------------------------ staticBOOL_get_word(FILE*fp,char*data,longmax_data_size) { intc; longpos=0; //resetwordtoempty data[0]=0; //readuntilanacceptablecharacterfound while (1) { if((c=fgetc(fp))==EOF) { data[0]=0; returnFALSE; } //checkforstartofword if(c! =32&&c! =0x0a&&c! =0x0d)//ifcharacterisnotblank,notlinefeed,notcarriage. { data[pos++]=c; //loopuntilendofword(orEOF) while((c=fgetc(fp))! =EOF) { //breakonacceptablewordseperators if(c==32||c==0x0a||c==0x0d) break; //addifenoughroomleft if(pos data[pos++]=c; } //addendoflinetotext data[pos]=0; break; } } returnTRUE; } //------------------------------------------------------------------------ //Constructor,zeromemberdata. //------------------------------------------------------------------------ ACTION_TEMPLATE: : ACTION_TEMPLATE() { memset(this,0,sizeof(*this)); } //------------------------------------------------------------------------ //Destructor,releaseallocatedmemory. //------------------------------------------------------------------------ ACTION_TEMPLATE: : ~ACTION_TEMPLATE() { free(); } //------------------------------------------------------------------------ //Releaseallocatedmemory. //------------------------------------------------------------------------ voidACTION_TEMPLATE: : free() { deletem_root_action; m_num_actions=0; } //------------------------------------------------------------------------ //Loadanactiontemplate. //------------------------------------------------------------------------ BOOLACTION_TEMPLATE: : load_actions(constchar*filename) { constintsize=256; //freepreviousactionstructures free(); FILE*fp; //opentheactionfile if((fp=fopen(filename,"rb"))==NULL) returnFALSE; ACTION_PTRact_ptr=NULL; //keeploopinguntilendoffilefound while (1) { chartext[size]; //getnextquotedaction if(! _get_quoted_line(fp,text,size)) break; //quitifnoactiontext if(text[0]==0) break; //allocateonactionstructureandappendittolist ACTION_PTRact=newACTION; act->next=NULL; if(act_ptr==NULL) m_root_action=act; else act_ptr->next=act; act_ptr=act;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 怎样 理解 脚本