silverlight---游戏中的人工智能之追逐与闪躲
时间:2010-10-15 来源:Skiper
近来在学习silverlight ,WPF,每天都沉浸在编程和设计的海洋中。感觉光学不练习没成就感啊,所以决定来这里写点东西,毕竟很久没写文章了,哈哈哈。好了,废话不多说了,开始silverlight与游戏中的人工智能之旅啦~~~
本课的重点是追逐和闪躲,相信玩过游戏的都知道,无论你是玩太空战机的射击游戏,还是策略模拟游戏,或者是角色扮演游戏,游戏中的非玩家角色,也就是NPC如果有机会,都会来追杀你,或者看到自己的生命值不多的时候,逃离你。
追逐和闪躲主要由两部分组成:
1.做出追或者逃跑的策略。
2.开始追逐,或者逃跑。
如果更加复杂一些的话,除了这个之外。还包括一部分,就是在追逐或者逃跑的过程中避开障碍物。这一部分,今天我们不考虑,以后再说,嘿嘿。
现在我们的目的已经明确了,然后,相信聪明的同学一下就能想出解决的方法:
在每次游戏循环中,更新追逐者的坐标,让追逐者的坐标离被追的越来越近(^^ 追女孩子也是这样的),紧追不舍啊。。。这种方法虽然简单,但是是不考虑追逐者和被追的各自的行进方向和速度的。因此在实际应用中,游戏中需要整合实时的物理引擎,然后考虑位置和速度,让追逐者试着拦截被追的,而不是像现在一样一直傻乎乎的追逐下去,如果速度一样,就追不到了~~今天我们就利用silverlight这个美女(我感觉silverlight是女的,不知道是不是~?~)来设计我们的第一个追逐闪躲程序。
开发环境:Silberlight 4 ,Visual Studio 2010,windows7;
1.首先创建一个Silberlight Application----命名有SLAI—lesson1;
2.打开MainPage.xaml 文件,修改代码为:
Code:- <UserControl x:Class="SLAI_lesson1.MainPage"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- d:DesignHeight="300" d:DesignWidth="400">
- <Canvas x:Name="LayoutRoot" Background="White">
- </Canvas>
- </UserControl>
把原来的<Grid x:Name="LayoutRoot" Background="white"> </Grid>
- 改成-- <Canvas x:Name="LayoutRoot" Background="White"> </Canvas>
- 这样做的原因是Canvas画布对象更方便对它里面的对象进行绝对定位。等等我们要把怪物和人类放到Canvas 画布中去,进行追逐与闪躲的模拟。
接着,我们转到MainPage.xmal.cs文件;整个文件的代码如下:
- namespace SLAI_lesson1
- {
- public partial class MainPage : UserControl
- {
- Rectangle _human, _monster; /*_human 人类 _monster 怪兽*/
- DispatcherTimer _dispatchertime;
- double monsterX, monsterY, humanX, humanY; /*怪兽和人类的坐标*/
- public MainPage()
- {
- InitializeComponent();
- _human = new Rectangle();
- _human.Width = 40; //设置矩形的宽度
- _human.Height = 40; //设置矩形的高度
- _human.Fill = new SolidColorBrush(Colors.Red); //填充颜色
- _human.SetValue(Canvas.LeftProperty, 100.0); //设定人类的x坐标
- _human.SetValue(Canvas.TopProperty, 150.0); //设置人类的y坐标
- _monster = new Rectangle();
- _monster.Width = 40;
- _monster.Height = 40;
- _monster.Fill = new SolidColorBrush(Colors.Black);
- _monster.SetValue(Canvas.LeftProperty, 50.0);
- _monster.SetValue(Canvas.TopProperty, 80.0);
- LayoutRoot.Children.Add(_human);
- LayoutRoot.Children.Add(_monster);
- _dispatchertime = new DispatcherTimer();
- _dispatchertime.Interval = TimeSpan.FromMilliseconds(200);
- _dispatchertime.Tick += new EventHandler(_dispatchertime_Tick);
- _dispatchertime.Start();
- }
- void _dispatchertime_Tick(object sender, EventArgs e)
- {
- monsterX = (double)_monster.GetValue(Canvas.LeftProperty); //得到当前怪物的x坐标
- monsterY = (double)_monster.GetValue(Canvas.TopProperty);
- humanX = (double)_human.GetValue(Canvas.LeftProperty);
- humanY = (double)_human.GetValue(Canvas.TopProperty);
- Catch(monsterX, monsterY, humanX, humanY);
- RunAway(monsterX, monsterY, humanX, humanY);
- _human.SetValue(Canvas.LeftProperty, humanX);
- _human.SetValue(Canvas.TopProperty, humanY);
- _monster.SetValue(Canvas.LeftProperty, monsterX);
- _monster.SetValue(Canvas.TopProperty, monsterY);
- }
- /// <summary>
- /// 基本追逐函数
- /// </summary>
- /// <param name="moX"></param>
- /// <param name="moY"></param>
- /// <param name="huX"></param>
- /// <param name="huY"></param>
- public void Catch(double moX,double moY,double huX,double huY)
- {
- monsterX = moX;
- monsterY = moY;
- humanX = huX;
- humanY = huY;
- if (monsterX > humanX) //如果怪物当前坐标大于人类的,就往回跑
- {
- monsterX-=4;
- }
- else if (monsterX <humanX) //如果怪物当前坐标小于人类的,就向前追
- {
- monsterX+=4;
- }
- if (monsterY > humanY) //与x坐标类似
- {
- monsterY-=4;
- }
- else if (monsterY < humanY)
- {
- monsterY+=4;
- }
- }
- /// <summary>
- /// 基本闪躲算法
- /// </summary>
- /// <param name="moX"></param>
- /// <param name="moY"></param>
- /// <param name="huX"></param>
- /// <param name="huY"></param>
- public void RunAway(double moX, double moY, double huX, double huY)
- {
- monsterX = moX;
- monsterY = moY;
- humanX = huX;
- humanY = huY;
- if (humanX> monsterX) // 如果人类当前x坐标大于怪物就继续往前逃命
- {
- humanX+=4;
- }
- else if (humanX < monsterX) //如果当前人类x坐标小于怪物x坐标就往后逃命
- {
- humanX-=4;
- }
- if (monsterY > humanY)
- {
- monsterY-=4;
- }
- else if (humanY < monsterY)
- {
- humanY-=4;
- }
- }
- }
- }
我们用2个rectangle 矩形代表怪兽和人类,然后在程序中放入一个dispatchertimer ,每过200ms触发一次追逐函数和闪躲函数,并且重新设置当前的坐标点,这样。两个矩形 就开始在屏幕上追逐与逃跑了。最后发一个运行的图片: