[Silverlight动画]转向行为 - 避开行为

简介: 避开行为与寻找行为彻底相反。实际上,除了代码最后一行用相减代替了相加以外,其它都一样。public void flee(Vector2D target) { Vector2D desiredVelocity = target.

 

避开行为与寻找行为彻底相反。实际上,除了代码最后一行用相减代替了相加以外,其它都一样。
public void flee(Vector2D target) {
    Vector2D desiredVelocity = target.subtract(_postion);
    desiredVelocity.normalize();
    desiredVelocity = desiredVelocity.multiply(_maxSpeed);
    Vector2D force = desiredVelocity.subtract(_velocity);
    _steeringForce = _steeringForce.subtract(force);
}
由于和寻找几乎一样,所以就不详细解释了。最后一句的含义是“很好,既然发现了目标,那就调头往回走吧。”在此为避开做一个简单的测试:
<UserControl
	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"
	xmlns:local="clr-namespace:Steer" xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
	mc:Ignorable="d"
	x:Class="Steer.FleeTest"
	d:DesignWidth="640" d:DesignHeight="480">

	<Grid x:Name="LayoutRoot" Background="White">
		<local:SteeredVehicle x:Name="myStar" HorizontalAlignment="Left" Height="40" VerticalAlignment="Top" Width="40" RenderTransformOrigin="0.5,0.5">
			<ed:RegularPolygon Fill="Blue" Height="40" InnerRadius="1" PointCount="3" Stretch="Fill" Stroke="Black" UseLayoutRounding="False" Width="40" RenderTransformOrigin="0.5,0.5" StrokeThickness="0">
				<ed:RegularPolygon.RenderTransform>
					<CompositeTransform Rotation="90"/>
				</ed:RegularPolygon.RenderTransform>
			</ed:RegularPolygon>
		</local:SteeredVehicle>
	</Grid>
</UserControl>
	public partial class FleeTest : UserControl
    {
        double mouseX = 0;
        double mouseY = 0;
		public FleeTest()
		{
			// Required to initialize variables
            InitializeComponent();
            Loaded += new RoutedEventHandler(SeekTest_Loaded);
        }

        void SeekTest_Loaded(object sender, RoutedEventArgs e)
        {
            myStar.position = new Vector2D(100, 100);
            myStar.edgeBehavior = Vehicle.BOUNCE;
            myStar.velocity.length = 5;
            myStar.velocity.angle = Math.PI / 4;

            MouseMove += new MouseEventHandler(SeekTest_MouseMove);
            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
        }

        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            myStar.flee(new Vector2D(mouseX, mouseY));
            myStar.update();
        }

        void SeekTest_MouseMove(object sender, MouseEventArgs e)
        {
            mouseX = e.GetPosition(null).X;
            mouseY = e.GetPosition(null).Y;
        }
    }
抛开代码中调用的函数名称不谈,最主要的不同是,用两行代码将机车的初始位置放在离场景边缘有一段距离的地方,并且把接触场景边缘后的反应改为反弹。删除这两行再测试,就知道为什么要加这两行了。机车会为了避开鼠标在角落间来回切换,导致近似看不见。
现在我们有了一对正反行为,接下来要做的是为这对行为创建一对机车来看看情况。
<UserControl
	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"
	xmlns:local="clr-namespace:Steer" xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
	mc:Ignorable="d"
	x:Class="Steer.SeekFleeTest1"
	d:DesignWidth="640" d:DesignHeight="480">

	<Grid x:Name="LayoutRoot" Background="White">
		<local:SteeredVehicle x:Name="mySeek" HorizontalAlignment="Left" Height="40" VerticalAlignment="Top" Width="40" RenderTransformOrigin="0.5,0.5" Margin="84,50,0,0">
			<ed:RegularPolygon Fill="#FFFF0C00" Height="40" InnerRadius="1" PointCount="3" Stretch="Fill" Stroke="Black" UseLayoutRounding="False" Width="40" RenderTransformOrigin="0.5,0.5" StrokeThickness="0">
				<ed:RegularPolygon.RenderTransform>
					<CompositeTransform Rotation="90"/>
				</ed:RegularPolygon.RenderTransform>
			</ed:RegularPolygon>
		</local:SteeredVehicle>
		<local:SteeredVehicle x:Name="myflee" HorizontalAlignment="Left" Height="40" VerticalAlignment="Top" Width="40" RenderTransformOrigin="0.5,0.5">
			<ed:RegularPolygon Fill="Blue" Height="40" InnerRadius="1" PointCount="3" Stretch="Fill" Stroke="Black" UseLayoutRounding="False" Width="40" RenderTransformOrigin="0.5,0.5" StrokeThickness="0">
				<ed:RegularPolygon.RenderTransform>
					<CompositeTransform Rotation="90"/>
				</ed:RegularPolygon.RenderTransform>
			</ed:RegularPolygon>
		</local:SteeredVehicle>
	</Grid>
</UserControl>
	public partial class SeekFleeTest1 : UserControl
	{
		public SeekFleeTest1()
		{
			// Required to initialize variables
            InitializeComponent();
            Loaded += new RoutedEventHandler(SeekTest_Loaded);
        }

        void SeekTest_Loaded(object sender, RoutedEventArgs e)
        {
            mySeek.position = new Vector2D(200, 200);
            mySeek.edgeBehavior = Vehicle.BOUNCE;

            myflee.position = new Vector2D(100, 300);
            myflee.edgeBehavior = Vehicle.BOUNCE;

            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
        }

        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            mySeek.seek(myflee.position);
            myflee.flee(mySeek.position);
            mySeek.update();
            myflee.update();
        }
	}
这对机车叫寻找者(_seeker)和避开者(_fleer)。我相信不用再解释寻找者寻找避开者,避开者避开寻找者了吧。先运行一下看看两辆机车互动的效果,然后尝试改变它们的各种参数,再看看会发生什么。
我们还可以把两个行为同时用于一辆机车上。下面的例子中,机车A同时寻找和避开机车B,机车B同时寻找和避开机车C,机车C同时的寻找和避开机车A。这三辆机车会因为追捕各自的目标而形成一个圆。
<UserControl
	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"
	xmlns:local="clr-namespace:Steer" xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
	mc:Ignorable="d"
	x:Class="Steer.SeekFleeTest2"
	d:DesignWidth="640" d:DesignHeight="480">

	<Grid x:Name="LayoutRoot">
		<local:SteeredVehicle x:Name="myA" HorizontalAlignment="Left" Height="40" VerticalAlignment="Top" Width="40" RenderTransformOrigin="0.5,0.5">
			<ed:RegularPolygon Fill="#FFFF0C00" Height="40" InnerRadius="1" PointCount="3" Stretch="Fill" Stroke="Black" UseLayoutRounding="False" Width="40" RenderTransformOrigin="0.5,0.5" StrokeThickness="0">
				<ed:RegularPolygon.RenderTransform>
					<CompositeTransform Rotation="90"/>
				</ed:RegularPolygon.RenderTransform>
			</ed:RegularPolygon>
		</local:SteeredVehicle>
		<local:SteeredVehicle x:Name="myB" HorizontalAlignment="Left" Height="40" VerticalAlignment="Top" Width="40" RenderTransformOrigin="0.5,0.5">
			<ed:RegularPolygon Fill="Blue" Height="40" InnerRadius="1" PointCount="3" Stretch="Fill" Stroke="Black" UseLayoutRounding="False" Width="40" RenderTransformOrigin="0.5,0.5" StrokeThickness="0">
				<ed:RegularPolygon.RenderTransform>
					<CompositeTransform Rotation="90"/>
				</ed:RegularPolygon.RenderTransform>
			</ed:RegularPolygon>
		</local:SteeredVehicle>
		<local:SteeredVehicle x:Name="myC" HorizontalAlignment="Left" Height="40" VerticalAlignment="Top" Width="40" RenderTransformOrigin="0.5,0.5">
			<ed:RegularPolygon Fill="#FFCEFF00" Height="40" InnerRadius="1" PointCount="3" Stretch="Fill" Stroke="Black" UseLayoutRounding="False" Width="40" RenderTransformOrigin="0.5,0.5" StrokeThickness="0">
				<ed:RegularPolygon.RenderTransform>
					<CompositeTransform Rotation="90"/>
				</ed:RegularPolygon.RenderTransform>
			</ed:RegularPolygon>
		</local:SteeredVehicle>
	</Grid>
</UserControl>
	public partial class SeekFleeTest2 : UserControl
	{
		public SeekFleeTest2()
		{
			// Required to initialize variables
            InitializeComponent();
            Loaded += new RoutedEventHandler(SeekTest_Loaded);
		}
        void SeekTest_Loaded(object sender, RoutedEventArgs e)
        {

            myA.position = new Vector2D(200, 200);
            myA.edgeBehavior = Vehicle.BOUNCE;
            myB.position = new Vector2D(400, 200);
            myB.edgeBehavior = Vehicle.BOUNCE;
            myC.position = new Vector2D(300, 260);
            myC.edgeBehavior = Vehicle.BOUNCE;

            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
        }
        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            myA.seek(myB.position);
            myA.flee(myC.position);

            myB.seek(myC.position);
            myB.flee(myA.position);

            myC.seek(myA.position);
            myC.flee(myB.position);

            myA.update();
            myB.update();
            myC.update();
        }
	}
记得再试试改变各种参数,观察发生的变化。如果这些都没问题了,那就开始探索下一个行为:到达。
相关文章
|
容器
Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)
原文:Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)   Silverlight的基础动画包括偏移、旋转、缩放、倾斜和翻转动画,这些基础动画毫无疑问是在Silverlight中使用得最多的动画效果,其使用也是非常简单的。
1017 0
|
容器 数据可视化 内存技术
Silverlight & Blend动画设计系列一:偏移动画(TranslateTransform)
原文:Silverlight & Blend动画设计系列一:偏移动画(TranslateTransform)   用户界面组件、图像元素和多媒体功能可以让我们的界面生动活泼,除此之外,Silverlight还具备动画功能,它可以让应用程序“动起来”。
817 0
Silverlight & Blend动画设计系列四:倾斜动画(SkewTransform)
原文:Silverlight & Blend动画设计系列四:倾斜动画(SkewTransform)   Silverlight中的倾斜变化动画(SkewTransform)能够实现对象元素的水平、垂直方向的倾斜变化动画效果。
845 0
|
容器
Silverlight & Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)
原文:Silverlight & Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)   正如你所看到的,Blend是一个非常强大的节约时间的设计工具,在Blend下能够设计出很多满意的动画作品,或许他具体是怎么实现的,通过什么方式实现的我们还是一无所知。
944 0
Silverlight & Blend动画设计系列七:模糊效果(BlurEffect)与阴影效果(DropShadowEffect)
原文:Silverlight & Blend动画设计系列七:模糊效果(BlurEffect)与阴影效果(DropShadowEffect)   模糊效果(BlurEffect)与阴影效果(DropShadowEffect)是两个非常实用和常用的两个特效,比如在开发相册中,可以对照片的缩略图添加模糊效果,在放大照片的过程中动态改变照片的大小和模糊的透明度来达到一个放大透明的效果。
1086 0
Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效
原文:Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效   当我们在进行Silverlight & Blend进行动画设计的过程中,可能需要设计出很多效果不一的图形图像出来作为动画的基本组成元素。
1050 0
|
API
Silverlight & Blend动画设计系列十:Silverlight中的坐标系统(Coordinate System)与向量(Vector)运动
原文:Silverlight & Blend动画设计系列十:Silverlight中的坐标系统(Coordinate System)与向量(Vector)运动   如果我们习惯于数学坐标系,那么对于Silverlight中的坐标系可能会有些不习惯。
1262 0

热门文章

最新文章

下一篇
无影云桌面