silverlight---游戏中的人工智能之追逐与闪躲

前言:

       近来在学习silverlight ,WPF,每天都沉浸在编程和设计的海洋中。感觉光学不练习没成就感啊,所以决定来这里写点东西,毕竟很久没写文章了,哈哈哈。好了,废话不多说了,开始silverlight与游戏中的人工智能之旅啦~~~

      本课的重点是追逐闪躲,相信玩过游戏的都知道,无论你是玩太空战机的射击游戏,还是策略模拟游戏,或者是角色扮演游戏,游戏中的非玩家角色,也就是NPC如果有机会,都会来追杀你,或者看到自己的生命值不多的时候,逃离你。

      追逐和闪躲主要由两部分组成:

       1.做出追或者逃跑的策略。

       2.开始追逐,或者逃跑。

如果更加复杂一些的话,除了这个之外。还包括一部分,就是在追逐或者逃跑的过程中避开障碍物。这一部分,今天我们不考虑,以后再说,嘿嘿。

      现在我们的目的已经明确了,然后,相信聪明的你一下就能想出解决的方法:

在每次游戏循环中,更新追逐者的坐标,让追逐者的坐标离被追的越来越近(^^  追女孩子也是这样的),紧追不舍啊。。。这种方法虽然简单,但是是不考虑追逐者和被追的各自的行进方向和速度的。因此在实际应用中,游戏中需要整合实时的物理引擎,然后考虑位置和速度,让追逐者试着拦截被追的,而不是像现在一样一直傻乎乎的追逐下去,如果速度一样,就追不到了~~今天我们就利用silverlight这个美女(我感觉silverlight是女的,不知道是不是~?~)来设计我们的第一个追逐闪躲程序。

     开发环境:Silberlight 4 ,Visual Studio 2010,windows7;

    1.首先创建一个Silberlight Application----命名有SLAI—lesson1;

    2.打开MainPage.xaml 文件,修改代码为:

Code:
  1. <UserControl x:Class="SLAI_lesson1.MainPage"  
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  5.     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  6.     mc:Ignorable="d"  
  7.     d:DesignHeight="300" d:DesignWidth="400">  
  8.   
  9.     <Canvas x:Name="LayoutRoot" Background="White">  
  10.           
  11.     </Canvas>  
  12. </UserControl>  

把原来的<Grid x:Name="LayoutRoot" Background="white"> </Grid>

  1. 改成--   <Canvas x:Name="LayoutRoot" Background="White">     </Canvas> 

     

     

    • 这样做的原因是Canvas画布对象更方便对它里面的对象进行绝对定位。等等我们要把怪物和人类放到Canvas 画布中去,进行追逐与闪躲的模拟。

    接着,我们转到MainPage.xmal.cs文件;整个文件的代码如下:

     

    Code:
    1. namespace SLAI_lesson1   
    2. {   
    3.     public partial class MainPage : UserControl   
    4.     {   
    5.         Rectangle _human, _monster;      /*_human 人类 _monster 怪兽*/
    6.         DispatcherTimer _dispatchertime;   
    7.         double monsterX, monsterY, humanX, humanY;   /*怪兽和人类的坐标*/
    8.         public MainPage()   
    9.         {   
    10.             InitializeComponent();   
    11.             _human = new Rectangle();   
    12.             _human.Width = 40;                         //设置矩形的宽度
    13.             _human.Height = 40;                              //设置矩形的高度
    14.             _human.Fill = new SolidColorBrush(Colors.Red);   //填充颜色
    15.             _human.SetValue(Canvas.LeftProperty, 100.0);       //设定人类的x坐标
    16.             _human.SetValue(Canvas.TopProperty, 150.0);        //设置人类的y坐标
    17.             _monster = new Rectangle();   
    18.             _monster.Width = 40;   
    19.             _monster.Height = 40;   
    20.             _monster.Fill = new SolidColorBrush(Colors.Black);   
    21.             _monster.SetValue(Canvas.LeftProperty, 50.0);   
    22.             _monster.SetValue(Canvas.TopProperty, 80.0);   
    23.             LayoutRoot.Children.Add(_human);   
    24.             LayoutRoot.Children.Add(_monster);   
    25.           _dispatchertime = new DispatcherTimer();   
    26.            _dispatchertime.Interval = TimeSpan.FromMilliseconds(200);   
    27.             _dispatchertime.Tick += new EventHandler(_dispatchertime_Tick);   
    28.             _dispatchertime.Start();   
    29.               
    30.                  
    31.               
    32.         }   
    33.   
    34.      void _dispatchertime_Tick(object sender, EventArgs e)   
    35.         {   
    36.       monsterX = (double)_monster.GetValue(Canvas.LeftProperty); //得到当前怪物的x坐标  
    37.       monsterY = (double)_monster.GetValue(Canvas.TopProperty);   
    38.             humanX = (double)_human.GetValue(Canvas.LeftProperty);   
    39.             humanY = (double)_human.GetValue(Canvas.TopProperty);   
    40.             Catch(monsterX, monsterY, humanX, humanY);   
    41.             RunAway(monsterX, monsterY, humanX, humanY);   
    42.             _human.SetValue(Canvas.LeftProperty, humanX);   
    43.             _human.SetValue(Canvas.TopProperty, humanY);   
    44.             _monster.SetValue(Canvas.LeftProperty, monsterX);   
    45.             _monster.SetValue(Canvas.TopProperty, monsterY);   
    46.         }   
    47.         /// <summary>   
    48.         /// 基本追逐函数   
    49.         /// </summary>   
    50.         /// <param name="moX"></param>   
    51.         /// <param name="moY"></param>   
    52.         /// <param name="huX"></param>   
    53.         /// <param name="huY"></param>   
    54.         public void Catch(double moX,double moY,double huX,double huY)   
    55.         {   
    56.                
    57.             monsterX = moX;   
    58.             monsterY = moY;   
    59.             humanX = huX;   
    60.             humanY = huY;   
    61.             if (monsterX > humanX)   //如果怪物当前坐标大于人类的,就往回跑
    62.             {   
    63.                 monsterX-=4;   
    64.             }   
    65.   
    66.             else if (monsterX <humanX)   //如果怪物当前坐标小于人类的,就向前追
    67.             {   
    68.                 monsterX+=4;   
    69.             }   
    70.   
    71.             if (monsterY > humanY)        //与x坐标类似
    72.             {   
    73.                 monsterY-=4;   
    74.             }   
    75.             else if (monsterY < humanY)   
    76.             {   
    77.                 monsterY+=4;   
    78.             }   
    79.         }   
    80.         /// <summary>   
    81.         /// 基本闪躲算法   
    82.         /// </summary>   
    83.         /// <param name="moX"></param>   
    84.         /// <param name="moY"></param>   
    85.         /// <param name="huX"></param>   
    86.         /// <param name="huY"></param>   
    87.         public void RunAway(double moX, double moY, double huX, double huY)   
    88.         {   
    89.   
    90.             monsterX = moX;   
    91.             monsterY = moY;   
    92.             humanX = huX;   
    93.             humanY = huY;   
    94.             if (humanX> monsterX)         // 如果人类当前x坐标大于怪物就继续往前逃命
    95.             {   
    96.                 humanX+=4;   
    97.             }   
    98.   
    99.             else if (humanX < monsterX)   //如果当前人类x坐标小于怪物x坐标就往后逃命
    100.             {   
    101.                 humanX-=4;   
    102.             }   
    103.   
    104.             if (monsterY > humanY)   
    105.             {   
    106.                 monsterY-=4;   
    107.             }   
    108.             else if (humanY < monsterY)   
    109.             {   
    110.                humanY-=4;   
    111.             }   
    112.            
    113.            
    114.         }   
    115.     }   
    116. }  

我们用2个rectangle 矩形代表怪兽和人类,然后在程序中放入一个dispatchertimer ,每过200ms触发一次追逐函数和闪躲函数,并且重新设置当前的坐标点,这样。两个矩形 就开始在屏幕上追逐与逃跑了。最后发一个运行的图片:

posted @ 2010-10-15 16:45  Sirk  阅读(1011)  评论(0编辑  收藏  举报