silverlight---游戏中的人工智能之追逐与闪躲
2016-03-19 00:00
531 查看
前言:
近来在学习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文件;整个文件的代码如下:
Code:
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触发一次追逐函数和闪躲函数,并且重新设置当前的坐标点,这样。两个矩形 就开始在屏幕上追逐与逃跑了。最后发一个运行的图片:
近来在学习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文件;整个文件的代码如下:
Code:
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触发一次追逐函数和闪躲函数,并且重新设置当前的坐标点,这样。两个矩形 就开始在屏幕上追逐与逃跑了。最后发一个运行的图片:
相关文章推荐
- Aidl实现跨进程通信小例子
- UVa 10976 - Fractions Again?!
- 不能在析构函数里面抛出异常 http://blog.csdn.net/wind19/article/details/8213406
- RAID各级别特性
- HDU5046 Airport dancing links 重复覆盖+二分
- Starting httpd: httpd: apr_sockaddr_info_get() failed for subversion
- fail-fast机制
- 开发板mount宿主机出现提示:mount: nfs mount failed: Bad file descriptor的解决方案
- Failed to create an IPC Port: 拒绝访问
- GCJ 2008 APAC local onsites C Millionaire
- 219. Contains Duplicate II
- 172. Factorial Trailing Zeroes
- Pairs Forming LCM 素数筛和素因子分解
- RAID详解
- 70. Climbing Stairs
- 深入分析AIDL原理
- 217. Contains Duplicate
- 知乎日报(Know almost daily chrome version)
- 知乎日报(Know almost daily chrome version)
- 删除 除了main.mp4以外的全部文件的脚本