获取Agent角色的动作列表

在VC++中获取Agent角色的动作列表
 
2001-08-24· ·Adding··yesky

 

  Microsoft Agent是一个能在应用程序用户界面中显示指定的人物造型的ActiveX控件,其动画人物最显著的特点就是造型美观,它一般有两部分:一是精灵本身,另一部分是被称作Balloon的语言提示部分,它能在精灵上方显示出Agent所说的话。Microsoft已经为最新的Agent 2.0提供了4种标准人物造型,它们是Genie、Merlin、Robby、Peedy,下载地址是:http://msdn.microsoft.com/workshop/imedia/agent/agentdl.asp,并公开这些角色的动作列表。这样,在网页或应用程序中使用Play方法就摆出各种不同的姿势,如听、看、读、写等。

  但如果能直接从角色文件ACS中获取相应的动作列表就可将Office 2000光盘中所有的"Office助手"角色为己所用!岂不快哉!

  ACS是一种单结构角色文件,它将角色数据与动画数据存放在一个文件中,故每个ACS文件都比较大。

  ACS文件中,角色动作列表数据是处在角色数据与动画数据之间的某个位置处,该位置的地址是在文件开头第0C字节开始用4个字节来表示的。例如DOT.ACS文件中,角色动作列表数据地址为0007F86D。

  将文件指针移至该地址处,角色动作名称就可以看到了。一开始的4个字节表示动作个数,随后是各个动作的相关数据。动作数据中,头4个字节表示动作名称的字符个数,随后便是各个字符数据,注意ACS文件是用双字节来表示一个字符,再往后是2个字节的保留数据、角色数据地址(4个字节)以及角色数据字节数(4个字节)。

  上述结构可用图1来表示(以DOT.ACS为例)。

 

  知道了ACS文件中动作列表数据所在的位置,就可用下列Visual C++代码将其读出:

CFile agentFile(m_strFileName,CFile::modeRead| CFile::typeBinary );
unsigned long lAdress, lActNum, lCharNum, i, j;
int ch;

agentFile.Seek(12L,CFile::begin);
agentFile.Read(&lAdress,4);
agentFile.Seek(lAdress,CFile::begin);
agentFile.Read(&lActNum,4);

CString str,strChar;
for (i=0; i str.Empty();
agentFile.Read(&lCharNum,4);
for (j=0; j agentFile.Read(&ch,2);
strChar.Format(_T("%c"),(char)ch);
str = str + strChar;
}
m_listAct.AddString(str);
agentFile.Seek(10L,CFile::current);
}

agentFile.Close();
 

  这样就可在应用程序中加入Agent角色动作列表读取功能,并依照Agent所提供的Play方法将播放这些动作,图2就是一个的例子。
 --------------------------------------
shappy:Delphi中的实现。

procedure TForm1.Button9Click(Sender: TObject);
var
  c:array[0..3] of char;
  plw:PLongWord;
  baseAdd:longword;
  actCnt,len,i,j:integer;
  actName:string;
begin
  ListBox1.Clear;
  fStream1:=TFileStream.Create( _path+'PEEDY.ACS',fmOpenRead);
  fStream1.Position:=$c;
  plw:=@(c[0]);
  fStream1.Read(c,4);
  baseAdd:=plw^+4;
  fStream1.Position:=plw^;
  fStream1.Read(c,4);
  actCnt:=plw^;  //action count
  for i:=0 to actCnt-1 do begin
    fStream1.Read(c,4);
    len:=plw^;  //action name length
    actName:='';
    for j:=0 to len-1 do begin
      fStream1.Read(c,2);
      actName:=actName+c[0];
    end;
    ListBox1.Items.add(actName);
    fStream1.Position:=fStream1.Position+10;
  end;

  fStream1.free;

posted on 2007-05-14 10:08  shappy  阅读(303)  评论(0编辑  收藏  举报

导航