无论是单机游戏还是网络游戏,丰富剧情的背后都离不开NPC默默无闻的工作;有的吆喝着卖药卖武器 ,有的做为宠物常拌左右,更灵活的还可以如《暗黑破坏神》那样,作为随从协助杀敌。强大的游戏离不 开高智能的AI,而AI的背后则隐藏着更为复杂的技术,脚本系统就是其核心。想深入了解游戏脚本的朋友 ,我推荐阅读脚本AI与脚本引擎这篇文章。简单的说,脚本,以独立于游戏主程序代码之外为特征,可以 让游戏设计者而不是游戏程序员编写和精制大部分的游戏结构,玩家同样可以很轻易的溶入到脚本的编写 中并创造出一个全新的游戏世界,这一切都展示了脚本简单神奇之美。
本节,我将在上一节创建的梦幻西游世界中添加一些精灵NPC,并为它们附加一些简单的脚本AI,目的 是让游戏显得更为生气勃勃,乐趣无边。
在与嵌入式脚本语言Lua & JavaScript的交互这篇文章中,我已很详细的讲解了如何实现 Silverlight程序与JavaScript脚本的交互。于是,我们首先同样的需要在梦幻西游Demo源码中添加一个 JavaScript脚本文件,并在嵌有游戏Demo的Index.htm页面里对该脚本进行调用:
接着,我们还要在程序中加入作为脚本调用对象的一些精灵自身方法;这里,我添加了两种方法:连 续随机说话及连续随意跑动:
/// <summary>
/// 连续随机说话
/// </summary>
/// <param name="content"></param>
[ScriptableMember]
public void RandomSay(string content) {
Dialog dialog = new Dialog() {
Duration = 5,
LocatedSpriteWidth = BodyWidth,
Top = BodyTop
};
this.Children.Add(dialog);
dialog.Completed += (s, e) => {
this.Children.Remove(s as Dialog);
HtmlPage.Window.Invoke("RandomSay", this, new int[] { TalkContentCode });
};
dialog.Show(content);
}
/// <summary>
/// 连续随机跑动
/// </summary>
/// <param name="startX">走动范围起点X</param>
/// <param name="startY">走动范围起点Y</param>
/// <param name="endX">走动范围终点X</param>
/// <param name="endY">走动范围终点Y</param>
[ScriptableMember]
public void RandomMoveTo(int startX, int startY, int endX, int endY) {
Random random = new Random();
int x = random.Next(startX, endX);
int y = random.Next(startY, endY);
Point start = this.Coordinate;
Point end = new Point(x, y);
this.destination = end;
double spendTime = Math.Sqrt(Math.Pow((end.X - start.X) / LocatedScene.GridSize, 2) + Math.Pow((end.Y - start.Y) / LocatedScene.GridSize, 2)) * Speed * LocatedScene.GridSize; //计算总的移动花费
PointAnimation pointAnimation = new PointAnimation() {
To = end,
Duration = new Duration(TimeSpan.FromMilliseconds (spendTime))
};
Storyboard.SetTarget(pointAnimation, this);
Storyboard.SetTargetProperty(pointAnimation, new PropertyPath ("Coordinate"));
Move();
StopMovingAnimation();
moveingAnimation = new Storyboard();
moveingAnimation.Children.Add(pointAnimation);
moveingAnimation.Completed += (s, e) => {
RandomMoveTo(startX, startY, endX, endY);
};
moveingAnimation.Begin();
}