游戏脚本管理 (一)
前言:
在自己制作了单机泡泡堂的游戏之后,感觉应该加入游戏脚本的支持,通过一段时间学习,我将学的一些步骤和经验包括代码写了下来.
一、实现以指令为基础的游戏脚本语言
现在说的是理论方法,你马上可以实现一种以指令为基础的语言。首先设计一组简单的指令,用于显示文本,并加入简单的循环。最终用MessageBox对话框显示出来。
设计语言第一个步骤,建立自己的指令,为了更直观我建立一个指令表,列表如下:
文本控制指令表
命令
参数
描述
PrintString
string
输出字符串
PrintStringLoop
string,count
根据count指定输出次数
NewLine
None
增加一个空行
WaitForKeyPress
None
等待按键
二、编写一个脚本
首先确认你认为所需要的功能,目前它就是上表列的4条指令。它最好为一个标准的文本文件。
PrintString "这是一种以指令为基础的语言" PrintString "也是一个简单的脚本代码" Newline PrintString "但它相当的简单" Newline PrintStringLoop "将被输出4次" 4 Newline PrintString "等下将执行等待按键操作" WaitForKeyPress
三、编写TScript类
这段代码相当简单,主要体现于分解字符串的操作,根据不同的指令来执行不同的代码。
unit uScripting;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms;
const
//四个指令的常量定义 COMMAND_PRINTSTRING = ''''PrintString''''; COMMAND_NEWLINE = ''''Newline''''; COMMAND_PRINTSTRINGLOOP = ''''PrintStringLoop''''; COMMAND_WAITFORKEYPRESS = ''''WaitForKeyPress'''';
type TScript = class private FCommandList: TStrings; //保存脚本 procedure GetCommand(Index: integer; var strCommand: string); //获取一个命令 procedure GetStrParam(Index: integer; var strParam: string); //获取一个字符串参数 procedure GetIntParam(Index: integer; var intParam: integer); //获取一个整形参数 public constructor Create; destructor Destroy; override; procedure LoadScript(AFile: string); //装入脚本 procedure UnLoadScript; //清空脚本 procedure RunScript(); //运行脚本 end;
implementation
{ TScript }
constructor TScript.Create; begin FCommandList := TStringList.Create; end;
destructor TScript.Destroy; begin FCommandList.Clear; FCommandList.Free; inherited Destroy; end;
procedure TScript.GetCommand(Index: integer; var strCommand: string); begin if Pos(#32, Trim(FCommandList.Strings[Index])) <> 0 then strCommand := Trim(Copy(Trim(FCommandList.Strings[Index]), 1, Pos(#32, Trim(FCommandList.Strings[Index])))) else strCommand := Trim(FCommandList.Strings[Index]); end;
procedure TScript.GetIntParam(Index: integer; var intParam: integer); var cCurrChar : string; g_iCurrScriptLineChar: Integer; begin
g_iCurrScriptLineChar := Pos(''''"'''', FCommandList.Strings[Index]) + 1; g_iCurrScriptLineChar := Pos(''''"'''', Copy(FCommandList.Strings[Index], g_iCurrScriptLineChar + 1, length(FCommandList.Strings[Index]))) + g_iCurrScriptLineChar + 1; intParam := 0;
while (g_iCurrScriptLineChar <= Length(FCommandList.Strings[Index])) do begin cCurrChar := copy(FCommandList.Strings[Index], g_iCurrScriptLineChar, 1); if (cCurrChar = ''''#'''') or (cCurrChar = #13) or (cCurrChar = #10) then break; if (cCurrChar[1] in [''''0''''..''''9'''']) then intParam := StrToInt(IntToStr(intParam) + cCurrChar); inc(g_iCurrScriptLineChar, 1); end;
end;
procedure TScript.GetStrParam(Index: integer; var strParam: string); var cCurrChar : string; g_iCurrScriptLineChar: Integer; begin
g_iCurrScriptLineChar := Pos(''''"'''', FCommandList.Strings[Index]) + 1; strParam := '''''''';
while (g_iCurrScriptLineChar < Length(FCommandList.Strings[Index])) do begin cCurrChar := copy(FCommandList.Strings[Index], g_iCurrScriptLineChar, 1); if (cCurrChar = ''''"'''') or (cCurrChar = #13) or (cCurrChar = #10) then break; strParam := strParam + cCurrChar; inc(g_iCurrScriptLineChar, 1); end;
end;
procedure TScript.LoadScript(AFile: string); begin if FileExists(AFile) then FCommandList.LoadFromFile(AFile) else raise Exception.Create(''''无效的脚本文件''''); end;
procedure TScript.RunScript; var strCommand : string; strParam : string; intParam : integer; i : Integer; iCurr : integer; sResult : string; begin if FCommandList.Count < 0 then Exit; sResult := '''''''';
for i := 0 to FCommandList.Count - 1 do begin GetCommand(i, strCommand); if Uppercase(strCommand) = Uppercase(COMMAND_PRINTSTRING) then //检查指令是否匹配 begin GetStrParam(i, strParam); //获取字符串参数 sResult := sResult + strParam + #13#10; //保存结果 end else if UpperCase(strCommand) = UpperCase(COMMAND_PRINTSTRINGLOOP) then begin GetStrParam(i, strParam); GetIntParam(i, intParam); //获取整形参数
for iCurr := 0 to intParam - 1 do begin sResult := sResult + strParam + #13#10; //循环输出次数 end; end else if UpperCase(strCommand) = UpperCase(COMMAND_NEWLINE) then begin sResult := sResult + #13#10; end else if UpperCase(strCommand) = UpperCase(COMMAND_WAITFORKEYPRESS) then begin Application.Title := ''''等待按键''''; while true do begin Application.ProcessMessages; if GetInputState() then break; end; Application.Title := ''''按键完成''''; end else begin sResult := sResult + ''''无效指令!'''' + #13#10; end;
end;
Application.MessageBox(PAnsiChar(sResult), ''''运行结果'''', 0 [1] [2] 下一页 [常用软件]评测:Gmail Beta(一) [VB.NET程序]把握VB.NET中的流(Stream) (一) [VB.NET程序]从Csharp走到VB.Net(一):MyClass保留字 [Delphi程序]一 个 实 用 的Delphi 屏 幕 拷 贝 程 序 的 设 [Delphi程序]Multi-Tier结构程序开发基础教程 (一) [Delphi程序]StringGrid使用全书( 一) [Delphi程序]Integer GUID和Comb做主键的效率测试(Delphi+acce… [网页制作]DreamwaverMX与ASP.NET(一) [Web开发]XPDL学习与分享 一 [Web开发]ADO.net学习记录 (一)
|