怎样理解脚本.docx_第1页
怎样理解脚本.docx_第2页
怎样理解脚本.docx_第3页
怎样理解脚本.docx_第4页
怎样理解脚本.docx_第5页
已阅读5页,还剩126页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

理解脚本使用这样一个有限的行为集合,就不再需要复杂的可编译脚本语言了。相反,只需要告诉脚本系统要使用哪些行为,以及这些行为将使用怎样的选项以实现游戏的功能。对于这种方法,最大的好处就是不再需要为指定一个简单的行为而罗列代码行,可以通过编号来引用行为和选项。举个例子,Play Sound行为的编号为4,而且该行为仅要求一个输入,即播放声音的编号。在脚本中只存储两个数值:一个对应于行为,另一个代表了声音。使用数值表示行为(代替文本)的方法可以使这种类型脚本的处理既快速又简单。Mad Lib Scripting系统的设计创建在游戏中想到的行为,可以通过创建或编辑脚本来填充那些空白点(称之为条目entries)。对于每个行为,请明确提供一个可供空白条目填充的选项列表,它的类型可以从一行文本到一串数字。接着将行为和空白条目进行编号,以便脚本系统可以引用它们,以下是一些行为列表的范例:1. Character (*NAME*) takes (*NUMBER*) damage.2. Print (*TEXT*).3. Play sound effect titled (*SOUND_NAME*).4. Play music titled (*MUSIC_NAME*).5. Create object (*OBJECT_NAME*) at coordinates (*XPOS*),(*YPOS*).6. End script processing.在这6种行为中,都有0个或多个空白条目位于括号内,每个空白条目包含了一个文本字符串或者一个数字,这个行为与可能条目(以及条目的类型)的列表被称之为行为模板(action template),如下图所示:一旦使用了行为模板,就可以使用它们的编号而不是行为的文本进行引用(文本的存在只是为了使用户能够更容易理解每个行为所实现的功能)。MLS系统的编写为了使MLS系统功能尽可能强大,需要设计它以便可以支持多重行为的模板,而且每个行为模板都包含不受数量限制的行为。以这种方式,就可以将系统复用到任何想要的项目中。当一个脚本完成时,将脚本读入到引擎中,并处理各自的行为,为每个由脚本编辑器所输入的行为使用指定的条目。一个行为模板需要保存行为的列表,包括文本、条目编号以及每个条目的数据。每个行为按它们在列表中的索引值进行编号,同时每个行为中的空白条目也被加以编号。可以为每个条目指定一种类型(文本型、整数型、浮点型、布尔型、多重选择型),如下所示:0. No entry type1. Text entry2. Boolean value3. Integer number4. Float number5. Multiple choice (a choice from a list of text selections)每个条目类型都有一个独特的特征,字符串类型的长度是可以变化的,数字型可以是两个数字范围之间的任何数值,而布尔值可以是TRUE或者FALSE。至于多重选项型,每个选项都有它自己的文本字符串(脚本从一个列表中获取选项,而且所选选项的索引编号比它的文本更适用)。行为可以采用如下格式:Action #1: Spell targets (*MULTIPLE_CHOICE*).Possible choices for blank entry #1:1. Player character2. Spell caster3. Spell target4. Nobody我们通过创建结构体ENTRY_RULE和ACTION来处理条目规则与行为。enum ENTRY_TYPE ENTRY_NONE = 0, ENTRY_TEXT, ENTRY_BOOL, ENTRY_INT, ENTRY_FLOAT, ENTRY_CHOICE ;typedef char* char_ptr;typedef int BOOL;/=/ Structures to store information about a single blank entry./=typedef struct ENTRY_RULElong type; / type of blank entry (ENTRY_TEXT, ENTRY_BOOL, )/ The following two unions contain the various information about a single blank entry, / from the min/max values (for int and float types), as well as the number of choices / in a multiple choice entry.unionlong long_min; / min value of long typefloat float_min; / min value of float typelong num_choices; / number of choices in list;unionlong long_max; / max value of long typefloat float_max; / max value of float typechar_ptr* choices; / choice text array ;/ structure constructor to clear to default valuesENTRY_RULE()memset(this, 0, sizeof(*this);/ structure destructor to clean up used resourcesENTRY_RULE()/ special case for choice typeif(type = ENTRY_CHOICE & choices != NULL)for(long i = 0; i num_choices; i+) delete choicesi;delete choices; *ENTRY_RULE_PTR;/=/ Structure that store a single action./=typedef struct ACTIONlong index; / action index 0, number of action - 1char text256; / action textshort num_entries_rule; / number of entries in actionENTRY_RULE_PTR entries_rule; / array of entry structuresACTION* next; / next action in linked listACTION()memset(this, 0, sizeof(*this);ACTION()delete entries_rule;delete next; *ACTION_PTR;行为模板被存储为文本文件,同时每个行为的文本被包括在括号中。每个包含条目的行为(标记为文本中的波浪字符)紧跟着是条目数据的列表。每个条目由一个描述条目类型(文本型、布尔型、整型、浮点型或选项型)的单词开始。对于文本类型而言并没有更多的需要信息,对于布尔类型来说也是如此。而作为整数和浮点型,则要求一个最小值和最大值。最后,选项类型条目后跟着的是可供选择的编号以及每个选项的文本(包括在引号里)。如下所示: If flag # is thenINT 0 255BOOLElseEndifSet flag # to INT 0 255BOOLPrint TEXTMove character to , , FLOAT 0.0 2048.0FLOAT 0.0 2048.0FLOAT 0.0 2048.0Character pointsCHOICE 3 Main Character Caster TargetCHOICE 2GainsLoosesINT 0 128CHOICE 2HitMagicEngage in battle sequence #INT 0 65535End Script第二篇脚本条目的创建因为ENREY_RULE结构仅包含了行为和条目的规则,所以需要另外的结构数组去存储每个条目的数据。这些新的结构包括了在条目中所使用的文本、布尔值、多重选项,我们使用结构体ENTRY来表示。/=/ structure that store all entries fact information./=typedef struct ENTRYlong type; / type of blank entry (ENTRY_TEXT, ENTRY_BOOL, )unionlong io_value; / used for saving/loadinglong length; / length of text (0 terminator)long selection; / selection in choiceBOOL bool_value; / BOOL valuelong long_value; / long baluefloat float_value; / float value;char* text; / entry text bufferENTRY()memset(this, 0, sizeof(*this);ENTRY()delete text; *ENTRY_PTR;在处理脚本条目的过程中,当一个脚本出现了许多条目时,最麻烦的问题也就接踵而来。脚本中的每个行为都要求一个相匹配的ENTRY_RULE结构,其依次包含了一定数量的ENTRY结构。为了更好地处理一个脚本的结构,还需要其他的结构来记录属于脚本行为的每个条目,我们将它命名为SCRPT。/=/ structure that store all /=typedef struct SCRIPTlong action_index; / 0, number of actions - 1long num_entries; / number of entries in this actionENTRY_PTR entries; / array of entriesSCRIPT* prev; / previous in linked listSCRIPT* next; / next in linked listSCRIPT()memset(this, 0, sizeof(*this);SCRIPT()delete entries;delete next; *SCRIPT_PTR;prev和next维护了整个脚本的连接列表,为了构造SCRIPT结构的连接列表,从代表脚本的第一个行为的根结构开始,然后使用next和prev将SCRIPT结构连接起来,如下图所示: ACTION_TEMPLATE类的整合理解了行为模板所使用的结构以及所容纳的脚本后,现在开始将它们整合到一起创建一个加载并处理脚本的类。/=/ This class encapsulate script save and load./=typedef class ACTION_TEMPLATEprivate:long m_num_actions; / number of actions in templateACTION_PTR m_root_action; / list of template actions public:ACTION_TEMPLATE();ACTION_TEMPLATE();BOOL load_actions(const char* filename);void free();long get_num_actions();ACTION_PTR get_root_action();ACTION_PTR get_action(long act_index);SCRIPT_PTR create_script(long act_index);long get_num_entries_rule(long act_index);ENTRY_RULE_PTR get_entry_rule(long act_index, long entry_rule_index);void expand_default_action_text(char* buffer, ACTION_PTR action);BOOL expand_action_text(char* buffer, SCRIPT_PTR script); *ACTION_TEMPLATE_PTR;实现:/-/ Get quoted line from file./-static BOOL _get_quoted_line(FILE* fp, char* data, long max_data_size)int c;long pos = 0;/ read until a quote is reached (or EOF)while(1)if(c = fgetc(fp) = EOF)return FALSE;if(c = )/ read until next quot (or EOF)while(1)if(c = fgetc(fp) = EOF)return FALSE;/ return text when 2nd quote foundif(c = )datapos = 0;break;/ add acceptable text to lineif(c != 0x0a & c != 0x0d) / if character is not linefeed, not carriage.if(pos max_data_size-1)datapos+ = c;break;return TRUE;/-/ Get word from file./-static BOOL _get_word(FILE* fp, char* data, long max_data_size)int c;long pos = 0;/ reset word to emptydata0 = 0;/ read until an acceptable character foundwhile(1)if(c = fgetc(fp) = EOF)data0 = 0;return FALSE;/ check for start of wordif(c != 32 & c != 0x0a & c != 0x0d) / if character is not blank, not linefeed, not carriage.datapos+ = c;/ loop until end of word (or EOF)while(c = fgetc(fp) != EOF)/ break on acceptable word seperatorsif(c = 32 | c = 0x0a | c = 0x0d)break;/ add if enough room leftif(pos next = NULL;if(act_ptr = NULL)m_root_action = act;elseact_ptr-next = act;act_ptr = act;/ copy action textstrcpy(act-text, text);/ store action indexact-index = m_num_actions;/ increase the number of actions loadedm_num_actions+;size_t text_len = strlen(text);/ count the number of entries in the actionfor(size_t i = 0; i num_entries_rule+;/ allocated and read in entries (if any)if(act-num_entries_rule != 0)act-entries_rule = new ENTRY_RULEact-num_entries_rule;for(short entry_index = 0; entry_index num_entries_rule; entry_index+)ENTRY_RULE_PTR entry_rule = &act-entries_ruleentry_index;/ get type of entry_get_word(fp, text, size);if(!stricmp(text, TEXT) / TEXT type, nothing data.entry_rule-type = ENTRY_TEXT;else if(!stricmp(text, INT) / LONG type, get min and max valuesentry_rule-type = ENTRY_INT;/ get min value_get_word(fp, text, size);entry_rule-long_min = atol(text);/ get max value_get_word(fp, text, size);entry_rule-long_max = atol(text);else if(!stricmp(text, FLOAT) / FLOAT type, get min and max valuesentry_rule-type = ENTRY_FLOAT;/ get min value_get_word(fp, text, size);entry_rule-float_min = (float) atof(text);/ get max value_get_word(fp, text, size);entry_rule-float_max = (float) atof(text);else if(!stricmp(text, BOOL) / BOOL type, no options.entry_rule-type = ENTRY_BOOL;else if(!stricmp(text, CHOICE) / CHOICE type, get number of entries and entrys texts.entry_rule-type = ENTRY_CHOICE;/ get the number of choices_get_word(fp, text, size);entry_rule-num_choices = atol(text);entry_rule-choices = new char_ptrentry_rule-num_choices;/ get each entry textfor(long choice_index = 0; choice_index num_choices; choice_index+)_get_quoted_line(fp, text, size);entry_rule-choiceschoice_index = strdup(text);fclose(fp);return TRUE;/-/ Return number of actions in template./-long ACTION_TEMPLATE:get_num_actions()return m_num_actions;/-/ Return root ACTION structure./-ACTION_PTR ACTION_TEMPLATE:get_root_action()return m_root_action;/-/ Return specified ACTION structure./-ACTION_PTR ACTION_TEMPLATE:get_action(long act_index)/ return error if higher than number of actionsif(act_index = m_num_actions)return NULL;ACTION_PTR act_ptr = m_root_action;/ scan listwhile(act_ptr)if(act_ptr-index = act_index)return act_ptr;act_ptr = act_ptr-next;return NULL;/-/ Create script from specified action index./-SCRIPT_PTR ACTION_TEMPLATE:create_script(long act_index)/ make sure it is a valid actionif(act_index = m_num_actions)return NULL;ACTION_PTR act_ptr;/ get pointer to actionif(act_ptr = get_action(act_index) = NULL)return NULL;/ create new SCRIPT structureSCRIPT_PTR script = new SCRIPT;script-action_index = act_index;script-num_entries = act_ptr-num_entries_rule;script-entries = new ENTRYscript-num_entries;/ set up each entryfor(long i = 0; i num_entries; i+)script-entriesi.type = act_ptr-entries_rulei.type;/ set up entry data based on typeswitch(script-entriesi.type)case ENTRY_TEXT:script-entriesi.text = NULL;break;case ENTRY_INT:script-entriesi.long_value = act_ptr-entries_rulei.long_min;break;case ENTRY_FLOAT:script-entriesi.float_value = act_ptr-entries_rulei.float_min;break; case ENTRY_BOOL:script-entriesi.bool_value = TRUE;break; case ENTRY_CHOICE:script-entriesi.selection = 0;break;return script;/-/ Return number of entries rule in the specified action./-long ACTION_TEMPLATE:get_num_entries_rule(long act_index)/ get pointer to specified actionACTION_PTR act_ptr = get_action(act_index);/ return 0 if on errorif(act_ptr = NULL)return 0;return act_ptr-num_entries_rule;/-/ Return specified entry rule in specified action./-ENTRY_RULE_PTR ACTION_TEMPLATE:get_entry_rule(long act_index, long entry_rule_index)ACTION_PTR act_ptr = get_action(act_index);if(act_ptr = NULL | entry_rule_index = act_ptr-num_entries_rule)return NULL;return &(act_ptr-entries_ruleentry_rule_index);/-/ Expand action text using min/first/TRUE choice values./-void ACTION_TEMPLATE:expand_default_action_text(char* buffer, ACTION_PTR action)/ copy action text into buffer if no entries ruleif(action-num_entries_rule = 0)strcpy(buffer, action-text);return;/ expand entry types into action textsize_t buf_pos = 0;long rule_index = 0;size_t text_len = strlen(action-text);const size_t mem_size = 256;for(size_t i = 0; i texti = )if(action-entries_rulerule_index.type = ENTRY_TEXT)memcpy(&bufferbuf_pos, (*TEXT*), 8);buf_pos += 8;else if(action-entries_rulerule_index.type = ENTRY_INT)sprintf(memory, (*%lu*), action-entries_rulerule_index.long_min);memcpy(&bufferbuf_pos, memory, strlen(memory);buf_pos += strlen(memory);else if(action-entries_rulerule_index.type = ENTRY_FLOAT)sprintf(memory, (*%lf*), action-entries_rulerule_index.float_min);memcpy(&bufferbuf_pos, memory, strlen(memory);buf_pos += strlen(memory);else if(action-entries_rulerule_index.type = ENTRY_BOOL)memcpy(&bufferbuf_pos, (*TRUE*), 8);buf_pos += 8;else if(action-entries_rulerule_index.type = ENTRY_CHOICE)memcpy(&bufferbuf_pos, (*, 2);buf_pos += 2;char* choice = action-entries_rulerule_index.choices0;size_t choice_len = strlen(choice);memcpy(&bufferbuf_pos, choice, choice_len);buf_pos += choice_len;memcpy(&bufferbuf_pos, *), 2);buf_pos += 2;rule_index+;elsebufferbuf_pos+ = action-texti;bufferbuf_pos = 0;/-/ Expand action text using selections./-BOOL ACTION_TEMPLATE:expand_action_text(char* buffer, SCRIPT_PTR script)/ get a pointer to the specified actionACTION_PTR act_ptr = get_action(script-action_index);if(act_ptr = NULL)return FALSE;/ copy action text into buffer if no entriesif(act_ptr-num_entries_rule = 0)strcpy(buffer, act_ptr-text);return TRUE;/ expand entry types into action textsize_t buf_pos = 0;size_t entry_index = 0;char memory256;size_t memory_length; size_t act_text_length = strlen(act_ptr-text);for(size_t i = 0; i texti = )if(act_ptr-entries_ruleentry_index.type = ENTRY_TEXT & script-entriesentry_index.type = ENTRY_TEXT) memcpy(&bufferbuf_pos, (*, 2);buf_pos += 2;if(script-entriesentry_index.text)for(long j = 0; j entriesentry_index.textj = 0)break;bufferbuf_pos+ = script-entriesentry_index.textj;memcpy(&bufferbuf_pos, *)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论