[Silverlight动画]转向行为 - 躲避行为
躲避就是追捕的反行为。就像追捕类似于寻找,躲避类似于避开。
本质上讲,是预测出机车将要去到的位置并远离它。在这里所有的原则都和追捕相同。实际上,就连实现都几乎一模一样,除了最后一行用避开代替寻找:
public void evade(Vehicle target) { double lookAheadTime = position.dist(target.position) / _maxSpeed; Vector2D predictedTarget = target.position.add(target.velocity.multiply(lookAheadTime)); flee(predictedTarget); }
直接把追捕和躲避放一起测试:
<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.PursueEvadeTest" d:DesignWidth="640" d:DesignHeight="480"> <Grid x:Name="LayoutRoot" Background="White"> <local:SteeredVehicle x:Name="myPursuer" 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="myEvader" HorizontalAlignment="Left" Height="40" VerticalAlignment="Top" Width="40" RenderTransformOrigin="0.5,0.5"> <ed:RegularPolygon Fill="#FFFD00FF" Height="40" InnerRadius="1" PointCount="5" Stretch="Fill" Stroke="Black" StrokeThickness="0" UseLayoutRounding="False" Width="40"/> </local:SteeredVehicle> </Grid> </UserControl>
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace Steer { public partial class PursueEvadeTest : UserControl { public PursueEvadeTest() { // Required to initialize variables InitializeComponent(); Loaded += new RoutedEventHandler(PursueEvadeTest_Loaded); } void PursueEvadeTest_Loaded(object sender, RoutedEventArgs e) { myPursuer.position = new Vector2D(200, 200); myPursuer.edgeBehavior = Vehicle.BOUNCE; myEvader.position = new Vector2D(400, 300); myEvader.edgeBehavior = Vehicle.BOUNCE; CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering); } void CompositionTarget_Rendering(object sender, EventArgs e) { myPursuer.pursue(myEvader); myEvader.evade(myPursuer); myPursuer.update(); myEvader.update(); } } }