9 files added
1 files deleted
5 files renamed
28 files modified
| | |
| | | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
| | | xmlns:local="clr-namespace:RichCreator.Editor" |
| | | StartupUri="MainWindow.xaml"> |
| | | StartupUri="Tools/MapEditor.xaml"> |
| | | <Application.Resources> |
| | | |
| | | </Application.Resources> |
| | |
| | | <MenuItem Header="方块灰度" Click="BlockGray" /> |
| | | |
| | | <MenuItem Header="鼠标模式识别" Click="MenuItem_Click" /> |
| | | <MenuItem Header="AStar寻路工具" Click="AStarTools_Click" /> |
| | | <MenuItem Header="图最短路径寻路" Click="DijkstraTools_Click" /> |
| | | <!--<MenuItem Header="AStar寻路工具" Click="AStarTools_Click" />--> |
| | | <MenuItem Header="地图编辑..." Click="DijkstraTools_Click" /> |
| | | |
| | | </MenuItem> |
| | | <MenuItem Header="帮助(H)" > |
| | |
| | | mt.ShowDialog(); |
| | | } |
| | | |
| | | private void AStarTools_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | AStarTools window = new AStarTools(); |
| | | window.ShowDialog(); |
| | | } |
| | | //private void AStarTools_Click(object sender, RoutedEventArgs e) |
| | | //{ |
| | | // AStarTools window = new AStarTools(); |
| | | // window.ShowDialog(); |
| | | //} |
| | | |
| | | private void DijkstraTools_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | DijkstraTools window = new DijkstraTools(); |
| | | MapEditor window = new MapEditor(); |
| | | window.ShowDialog(); |
| | | } |
| | | |
| | |
| | | <Generator>MSBuild:Compile</Generator> |
| | | <SubType>Designer</SubType> |
| | | </ApplicationDefinition> |
| | | <Compile Include="Tools\DijkstraTools.xaml.cs"> |
| | | <DependentUpon>DijkstraTools.xaml</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="Tools\AStarTools.xaml.cs"> |
| | | <DependentUpon>AStarTools.xaml</DependentUpon> |
| | | <Compile Include="Tools\MapEditor.xaml.cs"> |
| | | <DependentUpon>MapEditor.xaml</DependentUpon> |
| | | </Compile> |
| | | <Compile Include="Tools\CV\MainCV.xaml.cs"> |
| | | <DependentUpon>MainCV.xaml</DependentUpon> |
| | |
| | | <Generator>MSBuild:Compile</Generator> |
| | | <SubType>Designer</SubType> |
| | | </Page> |
| | | <Page Include="Tools\DijkstraTools.xaml"> |
| | | <Page Include="Tools\MapEditor.xaml"> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | <SubType>Designer</SubType> |
| | | </Page> |
| | | <Page Include="Tools\AStarTools.xaml"> |
| | | <SubType>Designer</SubType> |
| | | <Generator>MSBuild:Compile</Generator> |
| | | </Page> |
| | | <Page Include="Tools\CV\MainCV.xaml"> |
| | | <Generator>MSBuild:Compile</Generator> |
| New file |
| | |
| | | <Window x:Class="RichCreator.Editor.Tools.MapEditor" |
| | | 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:RichCreator.Editor.Tools" |
| | | mc:Ignorable="d" |
| | | Loaded="Window_Loaded" |
| | | Title="地图编辑器" Height="720" Width="1280"> |
| | | <Grid> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition Height="Auto" /> |
| | | <RowDefinition Height="*" /> |
| | | </Grid.RowDefinitions> |
| | | |
| | | <Border Grid.Row="0" BorderThickness="1" BorderBrush="Gray"> |
| | | <Grid> |
| | | <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,4,0,0"> |
| | | |
| | | |
| | | |
| | | <TextBlock Text="参数:" Margin="22 0 0 0" VerticalAlignment="Center" /> |
| | | <TextBox Width="45" x:Name="tagNumber" Text="0" VerticalContentAlignment="Center"/> |
| | | |
| | | <ComboBox SelectedIndex="0" x:Name="slOperate"> |
| | | <ComboBoxItem>障碍</ComboBoxItem> |
| | | <ComboBoxItem>定位点</ComboBoxItem> |
| | | <ComboBoxItem>寻路点</ComboBoxItem> |
| | | <ComboBoxItem>巡逻线</ComboBoxItem> |
| | | <ComboBoxItem>寻路线</ComboBoxItem> |
| | | </ComboBox> |
| | | <Button Content="清空定位点" Margin="5 0" Click="ClearPosition_Click" /> |
| | | <TextBlock VerticalAlignment="Center">除定位点外,其它物体右键删除。</TextBlock> |
| | | </StackPanel> |
| | | |
| | | |
| | | <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="5 5"> |
| | | <Button Content="加载图片" Margin="5 0" Click="OpenFromFile_Click" /> |
| | | <Button Content="复制为JSON" Margin="5 0" Click="CopyJSON_Click" /> |
| | | <Button Content="加载JSON" Margin="5 0" Click="CreateFromJSON_Click" /> |
| | | </StackPanel> |
| | | |
| | | </Grid> |
| | | </Border> |
| | | |
| | | |
| | | <ScrollViewer x:Name="scrollViewer" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" > |
| | | <Canvas x:Name="mainContainer" HorizontalAlignment="Left" VerticalAlignment="Top" MouseMove="SourceImage_MouseMove" MouseDown="SourceImage_MouseDown" PreviewMouseUp="SourceImage_MouseUp" MouseUp="SourceImage_MouseUp"> |
| | | <Image x:Name="SourceImage" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Top" /> |
| | | <Canvas x:Name="HouseInfoLayer" /> |
| | | <Canvas x:Name="LocationPointLayer" IsHitTestVisible="False"/> |
| | | |
| | | <!--<Polyline StrokeThickness="1" Stroke="Black" Opacity="0.5"> |
| | | <Polyline.Points>10,50 180,50 180,150 </Polyline.Points> |
| | | </Polyline>--> |
| | | </Canvas> |
| | | </ScrollViewer> |
| | | </Grid> |
| | | </Window> |
| New file |
| | |
| | | using Emgu.CV; |
| | | using RichCreator.Utility; |
| | | using RichCreator.Utility.PathFindings; |
| | | using RichCreator.Utility.Structs; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using System.Windows.Data; |
| | | using System.Windows.Documents; |
| | | using System.Windows.Input; |
| | | using System.Windows.Media; |
| | | using System.Windows.Media.Imaging; |
| | | using System.Windows.Shapes; |
| | | using ZTImage; |
| | | |
| | | namespace RichCreator.Editor.Tools |
| | | { |
| | | /// <summary> |
| | | /// AStarTools.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class MapEditor : Window |
| | | { |
| | | public MapEditor() |
| | | { |
| | | InitializeComponent(); |
| | | } |
| | | |
| | | // 寻路信息 |
| | | private HousePathInfo housePathInfo = null; |
| | | private bool moveable = false;//可移动的 |
| | | private Line tempLine = null; |
| | | private Polyline tempPolyline = null; |
| | | |
| | | // 当前图像 |
| | | private System.Drawing.Image image; |
| | | |
| | | private void Window_Loaded(object sender, RoutedEventArgs e) |
| | | { |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 加载图片 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void OpenFromFile_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | string imagePath = string.Empty; |
| | | Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog(); |
| | | ofd.DefaultExt = ".jpg"; |
| | | ofd.Filter = "image file|*.jpg;*.png;"; |
| | | ofd.Multiselect = false; |
| | | if (ofd.ShowDialog() == true) |
| | | { |
| | | imagePath = ofd.FileName; |
| | | } |
| | | else |
| | | { |
| | | return; |
| | | } |
| | | |
| | | Mat source = CvInvoke.Imread(imagePath, Emgu.CV.CvEnum.ImreadModes.Color); |
| | | this.image = source.Bitmap; |
| | | SetImage(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 复制JSON |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void CopyJSON_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | string json = this.housePathInfo.ToJsonString(); |
| | | Clipboard.SetDataObject(json, true); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 从JSON创建 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void CreateFromJSON_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | //SerializeInput input = new SerializeInput(); |
| | | //if (input.ShowDialog() != true) |
| | | //{ |
| | | // return; |
| | | //} |
| | | |
| | | //FindPathInfo pi = FindPathInfo.FromJsonString(input.ColorString); |
| | | |
| | | |
| | | |
| | | ////生成网格 |
| | | //this.rectWidth.Text = pi.Width.ToString(); |
| | | //this.rectHeight.Text = pi.Height.ToString(); |
| | | //GenericRect(pi.Width, pi.Height, pi.RowCount, pi.ColCount); |
| | | |
| | | |
| | | ////生成顶点 |
| | | //for (int i = 0; i < pi.Vertexs.Count; i++) |
| | | //{ |
| | | // SetVertexUI(pi.Vertexs[i]); |
| | | //} |
| | | |
| | | ////生成连线 |
| | | //for (int i = 0; i < pi.Edges.Count; i++) |
| | | //{ |
| | | // GenericEdge(pi.Edges[i].StartIndex); |
| | | // SetEdge(pi.Edges[i].EndIndex); |
| | | //} |
| | | |
| | | |
| | | //this.PositionOverflowLayer.Children.Clear(); |
| | | |
| | | ////生成定位点 |
| | | //for (int i = 0; i < pi.Positions.Count; i++) |
| | | //{ |
| | | // AddLocationPoint(pi.Positions[i].X, pi.Positions[i].Y, pi.Positions[i].Parameter); |
| | | //} |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 清理定位点 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void ClearPosition_Click(object sender, RoutedEventArgs e) |
| | | { |
| | | this.LocationPointLayer.Children.Clear(); |
| | | this.housePathInfo.ClearLocationPosiltion(); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 鼠标按下 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void SourceImage_MouseDown(object sender, MouseButtonEventArgs e) |
| | | { |
| | | //是否添加障碍物 |
| | | OperateActionD op = (OperateActionD)(slOperate.SelectedIndex); |
| | | Int32 number = TypeConverter.StringToInt(this.tagNumber.Text, 0); |
| | | |
| | | if (e.LeftButton == MouseButtonState.Released) |
| | | { |
| | | return; |
| | | } |
| | | Point point = GetPosition(e); |
| | | |
| | | |
| | | if (op == OperateActionD.Obstacle) |
| | | { |
| | | //障碍物 |
| | | |
| | | } |
| | | else if (op == OperateActionD.LocationPoint) |
| | | { |
| | | //定位点 |
| | | ParametersPoint lp = new ParametersPoint(new ZTPoint((Int32)point.X, (Int32)point.Y), number); |
| | | if (this.housePathInfo.AddLocationPosition(lp)) |
| | | { |
| | | Canvas lpControl = CreateLocationPointUI(lp); |
| | | this.LocationPointLayer.Children.Add(lpControl); |
| | | } |
| | | } |
| | | else if (op == OperateActionD.FindPathPoint) |
| | | { |
| | | //寻路点 |
| | | ZTPoint fp = new ZTPoint((Int32)point.X, (Int32)point.Y); |
| | | if (this.housePathInfo.AddFindPathPoint(fp)) |
| | | { |
| | | Canvas fpControl = CreateFindPathPointUI(fp); |
| | | this.HouseInfoLayer.Children.Add(fpControl); |
| | | } |
| | | } |
| | | else if (op == OperateActionD.LoopLine) |
| | | { |
| | | //循环线 |
| | | ZTPoint llPoint = GetFindPathPoint(new ZTPoint((Int32)point.X,(Int32)point.Y)); |
| | | if (llPoint != ZTPoint.Empty) |
| | | { |
| | | tempLine = CreateTempLoopLineUI(llPoint); |
| | | this.HouseInfoLayer.Children.Add(tempLine); |
| | | moveable = true; |
| | | } |
| | | } |
| | | else if (op == OperateActionD.FindPathLine) |
| | | { |
| | | //寻路线 |
| | | ZTPoint fpPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y)); |
| | | if (fpPoint != ZTPoint.Empty) |
| | | { |
| | | tempLine = CreateTempFindPathLineUI(fpPoint); |
| | | this.HouseInfoLayer.Children.Add(tempLine); |
| | | moveable = true; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 鼠标移动 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void SourceImage_MouseMove(object sender, MouseEventArgs e) |
| | | { |
| | | OperateActionD op = (OperateActionD)(slOperate.SelectedIndex); |
| | | Point point = GetPosition(e); |
| | | if (op == OperateActionD.LoopLine) |
| | | { |
| | | //巡逻线 |
| | | if (!moveable) |
| | | { |
| | | return; |
| | | } |
| | | tempLine.X2 = point.X; |
| | | tempLine.Y2 = point.Y; |
| | | } |
| | | else if (op == OperateActionD.FindPathLine) |
| | | { |
| | | //寻路线 |
| | | if (!moveable) |
| | | { |
| | | return; |
| | | } |
| | | tempLine.X2 = point.X; |
| | | tempLine.Y2 = point.Y; |
| | | } |
| | | else if (op == OperateActionD.Obstacle) |
| | | { |
| | | //障碍物线 |
| | | if (!moveable) |
| | | { |
| | | return; |
| | | } |
| | | tempLine.X2 = point.X; |
| | | tempLine.Y2 = point.Y; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 鼠标提起 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void SourceImage_MouseUp(object sender, MouseButtonEventArgs e) |
| | | { |
| | | OperateActionD op = (OperateActionD)(slOperate.SelectedIndex); |
| | | Point point = GetPosition(e); |
| | | |
| | | if (op == OperateActionD.LoopLine) |
| | | { |
| | | //巡逻线 |
| | | if (!moveable) |
| | | { |
| | | return; |
| | | } |
| | | moveable = false; |
| | | if (tempLine == null) |
| | | { |
| | | return; |
| | | } |
| | | ZTPoint startPoint = (ZTPoint)tempLine.Tag; |
| | | ZTPoint centerPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y)); |
| | | if (centerPoint != ZTPoint.Empty) |
| | | { |
| | | ZTLinePoint ll = new ZTLinePoint(startPoint, centerPoint); |
| | | if (this.housePathInfo.AddLoopLine(ll)) |
| | | { |
| | | Line llline = CreateLoopLineUI(ll); |
| | | this.HouseInfoLayer.Children.Add(llline); |
| | | } |
| | | } |
| | | |
| | | this.HouseInfoLayer.Children.Remove(tempLine); |
| | | tempLine = null; |
| | | } |
| | | else if (op == OperateActionD.FindPathLine) |
| | | { |
| | | //寻路线 |
| | | if (!moveable) |
| | | { |
| | | return; |
| | | } |
| | | moveable = false; |
| | | if (tempLine == null) |
| | | { |
| | | return; |
| | | } |
| | | ZTPoint startPoint = (ZTPoint)tempLine.Tag; |
| | | ZTPoint centerPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y)); |
| | | if (centerPoint != ZTPoint.Empty) |
| | | { |
| | | ZTLinePoint fp = new ZTLinePoint(startPoint, centerPoint); |
| | | if (this.housePathInfo.AddFindPathLine(fp)) |
| | | { |
| | | Line fpline = CreateFindPathLineUI(fp); |
| | | this.HouseInfoLayer.Children.Add(fpline); |
| | | } |
| | | } |
| | | |
| | | this.HouseInfoLayer.Children.Remove(tempLine); |
| | | tempLine = null; |
| | | } |
| | | else if (op == OperateActionD.Obstacle) |
| | | { |
| | | //绘制障碍物 |
| | | //判断是否起点 |
| | | if (tempPolyline == null) |
| | | { |
| | | //首次画 |
| | | this.points.Add(point); |
| | | this.tempPolyline=CreateTempObstacleUI(point); |
| | | this.tempLine = CreateObstacleLineUI(new ZTPoint((Int32)point.X, (Int32)point.Y)); |
| | | |
| | | moveable = true; |
| | | this.HouseInfoLayer.Children.Add(this.tempPolyline); |
| | | this.HouseInfoLayer.Children.Add(this.tempLine); |
| | | } |
| | | else |
| | | { |
| | | if (IsLastPoint(point)) |
| | | { |
| | | //判断是否跟最后一个点重合,如果重合则不处理 |
| | | return; |
| | | } |
| | | |
| | | if (IsFirstPoint(point)) |
| | | { |
| | | //到起点,完成,画折线,向houseinfo里添加障碍物 |
| | | Polygon polygon = CreateObstacleUI(); |
| | | this.HouseInfoLayer.Children.Add(polygon); |
| | | |
| | | ZTPoint[] obstaclePoints = new ZTPoint[this.points.Count]; |
| | | for (int i = 0; i < this.points.Count; i++) |
| | | { |
| | | obstaclePoints[i] = new ZTPoint((Int32)this.points[i].X, (Int32)this.points[i].Y); |
| | | } |
| | | this.housePathInfo.AddObstacle(new ZTPolygon(obstaclePoints)); |
| | | |
| | | |
| | | this.HouseInfoLayer.Children.Remove(tempPolyline); |
| | | tempPolyline = null; |
| | | this.HouseInfoLayer.Children.Remove(tempLine); |
| | | tempLine = null; |
| | | this.points.Clear(); |
| | | moveable = false; |
| | | } |
| | | else |
| | | { |
| | | //向points里添加障碍点,画折线,更新tempLine, |
| | | this.points.Add(point); |
| | | //画折线 |
| | | this.tempPolyline.Points.Add(point); |
| | | //更新tempLine |
| | | tempLine.X1 = point.X; |
| | | tempLine.Y1 = point.Y; |
| | | tempLine.X2 = point.X; |
| | | tempLine.Y2 = point.Y; |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 计算当前鼠标位置和颜色 |
| | | /// </summary> |
| | | /// <param name="e"></param> |
| | | /// <param name="point"></param> |
| | | /// <param name="color"></param> |
| | | /// <returns></returns> |
| | | private Point GetPosition(MouseEventArgs e) |
| | | { |
| | | Point point = e.GetPosition(this.scrollViewer); |
| | | |
| | | Int32 x = (Int32)Math.Round(this.scrollViewer.HorizontalOffset + point.X); |
| | | Int32 y = (Int32)Math.Round(this.scrollViewer.VerticalOffset + point.Y); |
| | | |
| | | return new Point(x, y); |
| | | } |
| | | |
| | | |
| | | private List<Point> points = new List<Point>(); |
| | | /// <summary> |
| | | /// 是否第一个点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | private bool IsFirstPoint(Point point) |
| | | { |
| | | Point temp =this.points[0]; |
| | | if (Math.Abs(temp.X - point.X) <= 10 && Math.Abs(temp.Y - point.Y) <= 10) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否最后一个点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | private bool IsLastPoint(Point point) |
| | | { |
| | | Point temp = this.points[this.points.Count-1]; |
| | | if (Math.Abs(temp.X - point.X) <= 10 && Math.Abs(temp.Y - point.Y) <= 10) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 操作类型 |
| | | /// </summary> |
| | | public enum OperateActionD |
| | | { |
| | | Obstacle = 0,//障碍物 |
| | | LocationPoint,//定位点 |
| | | FindPathPoint,//寻路点 |
| | | LoopLine,//循环线 |
| | | FindPathLine,//寻路线 |
| | | } |
| | | |
| | | |
| | | #region createUI |
| | | |
| | | /// <summary> |
| | | /// 设置图像 |
| | | /// </summary> |
| | | /// <param name="control"></param> |
| | | /// <param name="image"></param> |
| | | private void SetImage() |
| | | { |
| | | BitmapImage t = ImageHelper.BitmapToImageSource(image); |
| | | this.SourceImage.Source = t; |
| | | mainContainer.Width = image.Width; |
| | | mainContainer.Height = image.Height; |
| | | this.housePathInfo = new HousePathInfo(); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 创建定位点UI |
| | | /// 外方内圆 |
| | | /// </summary> |
| | | private Canvas CreateLocationPointUI(ParametersPoint point) |
| | | { |
| | | //<Canvas Canvas.Left="point.x" Canvas.Top="point.y"> |
| | | // <Rectangle Canvas.Left="-10" Canvas.Top="-10" Width="20" Height="20" Stroke="Red" StrokeThickness="1" /> |
| | | // <Ellipse Canvas.Left="-2" Canvas.Top="-2" Width="4" Height="4" Fill="Red" StrokeThickness="1" /> |
| | | //</Canvas> |
| | | |
| | | Canvas main = new Canvas(); |
| | | main.Tag = point; |
| | | Canvas.SetLeft(main,point.Point.X); |
| | | Canvas.SetTop(main, point.Point.Y); |
| | | |
| | | Rectangle rect = new Rectangle(); |
| | | Canvas.SetLeft(rect, -10); |
| | | Canvas.SetTop(rect, -10); |
| | | rect.Width = 20; |
| | | rect.Height = 20; |
| | | rect.Stroke = new SolidColorBrush(Colors.Red); |
| | | rect.StrokeThickness = 1; |
| | | rect.Fill = new SolidColorBrush(Colors.Red); |
| | | rect.Opacity = 0.5f; |
| | | main.Children.Add(rect); |
| | | |
| | | Ellipse elli = new Ellipse(); |
| | | Canvas.SetLeft(elli, -2); |
| | | Canvas.SetTop(elli, -2); |
| | | elli.Width = 4; |
| | | elli.Height = 4; |
| | | elli.Stroke = new SolidColorBrush(Colors.Black); |
| | | elli.StrokeThickness = 1; |
| | | elli.Fill = new SolidColorBrush(Colors.Black); |
| | | main.Children.Add(elli); |
| | | |
| | | TextBlock tb = new TextBlock(); |
| | | tb.Text = point.Parameter.ToString(); |
| | | tb.FontSize = 9; |
| | | main.Children.Add(tb); |
| | | |
| | | |
| | | return main; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建寻路点UI |
| | | /// </summary> |
| | | private Canvas CreateFindPathPointUI(ZTPoint findPathPoint) |
| | | { |
| | | //<Canvas Canvas.Left="point.x" Canvas.Top="point.y"> |
| | | // <Ellipse Canvas.Left="-10" Canvas.Top="-10" Width="20" Height="20" Stroke="Red" StrokeThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" /> |
| | | // <Rectangle Canvas.Left="-2" Canvas.Top="-2" Width="4" Height="4" Fill="Red" StrokeThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" /> |
| | | //</Canvas> |
| | | |
| | | Canvas main = new Canvas(); |
| | | main.Tag = findPathPoint; |
| | | main.MouseRightButtonUp += FindPathPoint_MouseRightButtonUp; |
| | | Canvas.SetLeft(main, findPathPoint.X); |
| | | Canvas.SetTop(main, findPathPoint.Y); |
| | | |
| | | |
| | | Ellipse elli = new Ellipse(); |
| | | Canvas.SetLeft(elli, -10); |
| | | Canvas.SetTop(elli, -10); |
| | | elli.Width = 20; |
| | | elli.Height = 20; |
| | | elli.Stroke = new SolidColorBrush(Colors.Red); |
| | | elli.StrokeThickness = 1; |
| | | elli.Fill = new SolidColorBrush(Colors.Red); |
| | | elli.Opacity = 0.5f; |
| | | main.Children.Add(elli); |
| | | |
| | | |
| | | Rectangle rect = new Rectangle(); |
| | | Canvas.SetLeft(rect, -2); |
| | | Canvas.SetTop(rect, -2); |
| | | rect.Width = 4; |
| | | rect.Height = 4; |
| | | rect.Stroke = new SolidColorBrush(Colors.Black); |
| | | rect.StrokeThickness = 1; |
| | | rect.Fill = new SolidColorBrush(Colors.Black); |
| | | rect.StrokeThickness = 1; |
| | | main.Children.Add(rect); |
| | | |
| | | return main; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 寻路点右击 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void FindPathPoint_MouseRightButtonUp(object sender, MouseButtonEventArgs e) |
| | | { |
| | | Canvas c = sender as Canvas; |
| | | if (c == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | ZTPoint fp = default(ZTPoint); |
| | | try |
| | | { |
| | | fp = (ZTPoint)c.Tag; |
| | | } |
| | | catch |
| | | { |
| | | return; |
| | | } |
| | | if (this.housePathInfo.RemoveFindPathPoint(fp)) |
| | | { |
| | | this.HouseInfoLayer.Children.Remove(c); |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建巡逻线UI |
| | | /// </summary> |
| | | private Line CreateLoopLineUI(ZTLinePoint linePoint) |
| | | { |
| | | Line edgeLine = new Line(); |
| | | edgeLine.Tag = linePoint; |
| | | edgeLine.MouseRightButtonUp += LoopLine_MouseRightButtonUp; |
| | | edgeLine.Stroke = new SolidColorBrush(Colors.Red); |
| | | edgeLine.StrokeThickness = 6; |
| | | edgeLine.X1 = linePoint.X1; |
| | | edgeLine.Y1 = linePoint.Y1; |
| | | |
| | | edgeLine.X2 = linePoint.X2; |
| | | edgeLine.Y2 = linePoint.Y2; |
| | | |
| | | edgeLine.StrokeDashArray = new DoubleCollection() { 2, 3 }; |
| | | edgeLine.StrokeDashCap = PenLineCap.Triangle; |
| | | edgeLine.StrokeEndLineCap = PenLineCap.Square; |
| | | edgeLine.StrokeStartLineCap = PenLineCap.Round; |
| | | |
| | | |
| | | return edgeLine; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 巡逻线右击 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void LoopLine_MouseRightButtonUp(object sender, MouseButtonEventArgs e) |
| | | { |
| | | Line c = sender as Line; |
| | | if (c == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | ZTLinePoint fp = default(ZTLinePoint); |
| | | try |
| | | { |
| | | fp = (ZTLinePoint)c.Tag; |
| | | } |
| | | catch |
| | | { |
| | | return; |
| | | } |
| | | if (this.housePathInfo.RemoveLoopLine(fp)) |
| | | { |
| | | this.HouseInfoLayer.Children.Remove(c); |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建临时巡逻线UI |
| | | /// </summary> |
| | | /// <param name="linePoint"></param> |
| | | /// <returns></returns> |
| | | private Line CreateTempLoopLineUI(ZTPoint point) |
| | | { |
| | | Line edgeLine = new Line(); |
| | | edgeLine.Tag = point; |
| | | edgeLine.Stroke = new SolidColorBrush(Colors.Red); |
| | | edgeLine.StrokeThickness = 3; |
| | | edgeLine.X1 = point.X; |
| | | edgeLine.Y1 = point.Y; |
| | | |
| | | edgeLine.X2 = point.X; |
| | | edgeLine.Y2 = point.Y; |
| | | |
| | | edgeLine.StrokeDashArray = new DoubleCollection() { 2, 3 }; |
| | | edgeLine.StrokeDashCap = PenLineCap.Triangle; |
| | | edgeLine.StrokeEndLineCap = PenLineCap.Square; |
| | | edgeLine.StrokeStartLineCap = PenLineCap.Round; |
| | | |
| | | return edgeLine; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 创建寻路线UI |
| | | /// </summary> |
| | | private Line CreateFindPathLineUI(ZTLinePoint linePoint) |
| | | { |
| | | Line edgeLine = new Line(); |
| | | edgeLine.Tag = linePoint; |
| | | edgeLine.MouseRightButtonUp += FindPathLine_MouseRightButtonUp; ; |
| | | edgeLine.Stroke = new SolidColorBrush(Colors.Red); |
| | | edgeLine.StrokeThickness = 3; |
| | | edgeLine.X1 = linePoint.X1; |
| | | edgeLine.Y1 = linePoint.Y1; |
| | | |
| | | edgeLine.X2 = linePoint.X2; |
| | | edgeLine.Y2 = linePoint.Y2; |
| | | |
| | | |
| | | return edgeLine; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 寻路线右键 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void FindPathLine_MouseRightButtonUp(object sender, MouseButtonEventArgs e) |
| | | { |
| | | Line c = sender as Line; |
| | | if (c == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | ZTLinePoint fp = default(ZTLinePoint); |
| | | try |
| | | { |
| | | fp = (ZTLinePoint)c.Tag; |
| | | } |
| | | catch |
| | | { |
| | | return; |
| | | } |
| | | if (this.housePathInfo.RemoveFindPathLine(fp)) |
| | | { |
| | | this.HouseInfoLayer.Children.Remove(c); |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 创建临时寻路线UI |
| | | /// </summary> |
| | | /// <param name="linePoint"></param> |
| | | /// <returns></returns> |
| | | private Line CreateTempFindPathLineUI(ZTPoint point) |
| | | { |
| | | Line edgeLine = new Line(); |
| | | edgeLine.Tag = point; |
| | | edgeLine.Stroke = new SolidColorBrush(Colors.Red); |
| | | edgeLine.StrokeThickness = 3; |
| | | edgeLine.X1 = point.X; |
| | | edgeLine.Y1 = point.Y; |
| | | |
| | | edgeLine.X2 = point.X; |
| | | edgeLine.Y2 = point.Y; |
| | | |
| | | |
| | | return edgeLine; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建临时障碍物UI |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private Polyline CreateTempObstacleUI(Point point) |
| | | { |
| | | //<!--<Polygon StrokeThickness="1" Stroke="Black" Opacity="0.5"> |
| | | // <Polygon.Points>10,50 180,50 180,150 </Polygon.Points> |
| | | // </Polygon>--> |
| | | Polyline polyline = new Polyline(); |
| | | polyline.StrokeThickness = 1; |
| | | polyline.Stroke = new SolidColorBrush(Colors.Black); |
| | | polyline.Opacity = 0.5f; |
| | | polyline.Points.Add(point); |
| | | return polyline; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 创建障碍物UI |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private Polygon CreateObstacleUI() |
| | | { |
| | | //<!--<Polygon StrokeThickness="1" Stroke="Black" Opacity="0.5"> |
| | | // <Polygon.Points>10,50 180,50 180,150 </Polygon.Points> |
| | | // </Polygon>--> |
| | | Polygon polygon = new Polygon(); |
| | | polygon.StrokeThickness = 1; |
| | | polygon.Stroke = new SolidColorBrush(Colors.Black); |
| | | polygon.Fill= new SolidColorBrush(Colors.Black); |
| | | polygon.Opacity = 0.7f; |
| | | for (int i = 0; i < this.points.Count; i++) |
| | | { |
| | | polygon.Points.Add(this.points[i]); |
| | | } |
| | | |
| | | return polygon; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 创建临时障碍物线UI |
| | | /// </summary> |
| | | /// <param name="linePoint"></param> |
| | | /// <returns></returns> |
| | | private Line CreateObstacleLineUI(ZTPoint point) |
| | | { |
| | | Line edgeLine = new Line(); |
| | | edgeLine.Tag = point; |
| | | edgeLine.Stroke = new SolidColorBrush(Colors.Black); |
| | | edgeLine.StrokeThickness = 1; |
| | | edgeLine.X1 = point.X; |
| | | edgeLine.Y1 = point.Y; |
| | | |
| | | edgeLine.X2 = point.X; |
| | | edgeLine.Y2 = point.Y; |
| | | |
| | | |
| | | return edgeLine; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取当前位置点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | private ZTPoint GetFindPathPoint(ZTPoint point) |
| | | { |
| | | ZTPoint temp = ZTPoint.Empty; |
| | | for (int i = 0; i < this.housePathInfo.FindPathPoints.Count; i++) |
| | | { |
| | | temp = this.housePathInfo.FindPathPoints[i]; |
| | | if (Math.Abs(temp.X - point.X) <= 10 && Math.Abs(temp.Y - point.Y) <= 10) |
| | | { |
| | | return temp; |
| | | } |
| | | } |
| | | return default(ZTPoint); |
| | | } |
| | | #endregion |
| | | |
| | | |
| | | |
| | | |
| | | #region Tools |
| | | //private bool PointInRang(Point) |
| | | #endregion |
| | | } |
| | | } |
| File was renamed from src/RichCreator.Editor/Tools/DijkstraTools.xaml |
| | |
| | | <Window x:Class="RichCreator.Editor.Tools.DijkstraTools" |
| | | <Window x:Class="RichCreator.Editor.Tools.MapEditor" |
| | | 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:RichCreator.Editor.Tools" |
| | | mc:Ignorable="d" |
| | | |
| | | Title="AStarFindingTools" Height="720" Width="1280"> |
| | | Loaded="Window_Loaded" |
| | | Title="地图编辑器" Height="720" Width="1280"> |
| | | <Grid> |
| | | <Grid.RowDefinitions> |
| | | <RowDefinition Height="Auto" /> |
| | |
| | | <TextBlock Text="(128,334)" HorizontalAlignment="Left"/> |
| | | </StackPanel> |
| | | </Border>--> |
| | | |
| | | |
| | | |
| | | <!--<Polygon StrokeThickness="1" Stroke="Black" Fill="Red" > |
| | | <Polygon.Points>10,50 180,50 180,150 10,150</Polygon.Points> |
| | | </Polygon>--> |
| | | </Canvas> |
| | | </ScrollViewer> |
| | | </Grid> |
| File was renamed from src/RichCreator.Editor/Tools/DijkstraTools.xaml.cs |
| | |
| | | /// <summary> |
| | | /// AStarTools.xaml 的交互逻辑 |
| | | /// </summary> |
| | | public partial class DijkstraTools : Window |
| | | public partial class MapEditor : Window |
| | | { |
| | | public DijkstraTools() |
| | | public MapEditor() |
| | | { |
| | | InitializeComponent(); |
| | | } |
| | |
| | | this.image = source.Bitmap; |
| | | SetImage(this.SourceImage); |
| | | } |
| | | |
| | | |
| | | private Polygon myPolygon = null; |
| | | |
| | | private void Window_Loaded(object sender, RoutedEventArgs e) |
| | | { |
| | | Polygon p = new Polygon(); |
| | | p.Stroke = Brushes.Black; |
| | | p.Fill = Brushes.LightBlue; |
| | | p.StrokeThickness = 5; |
| | | p.HorizontalAlignment = HorizontalAlignment.Left; |
| | | p.VerticalAlignment = VerticalAlignment.Center; |
| | | p.Points = new System.Windows.Media.PointCollection() { new Point(10, 10), new Point(100, 100), new Point(200, 200) }; |
| | | this.mainContainer.Children.Add(p); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 设置图像 |
| | | /// </summary> |
| | |
| | | { |
| | | AddLocationPoint(pi.Positions[i].X, pi.Positions[i].Y, pi.Positions[i].Parameter); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | /// <param name="confirmButtonPoint"></param> |
| | | /// <param name="gameRect"></param> |
| | | /// <returns></returns> |
| | | public static bool HasConnectIsVaildWindow(out ZTPoint confirmButtonPoint, ZTRectangle gameRect) |
| | | public static bool HasConnectIsVaildWindow(out Structs.ZTPoint confirmButtonPoint, ZTRectangle gameRect) |
| | | { |
| | | confirmButtonPoint = ZTPoint.Empty; |
| | | confirmButtonPoint = Structs.ZTPoint.Empty; |
| | | ZTRectangle tempRect = ZTRectangle.Empty; |
| | | if (!CVHelper.RectExistsArray(out tempRect, gameRect, DisconnectionWhiteText)) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | confirmButtonPoint = new ZTPoint(tempRect.GetCenterPoint().X, tempRect.End.Y); |
| | | confirmButtonPoint = new Structs.ZTPoint(tempRect.GetCenterPoint().X, tempRect.End.Y); |
| | | return true; |
| | | } |
| | | } |
| | |
| | | public static bool IsInSaiLiYaHouse(ZTRectangle gameRect) |
| | | { |
| | | ZTRectangle mailText = ZTRectangle.Empty; |
| | | ZTPoint limitPoint = gameRect.GetRatioPoint(0.667f); |
| | | Structs.ZTPoint limitPoint = gameRect.GetRatioPoint(0.667f); |
| | | ZTRectangle limit = new ZTRectangle(limitPoint.X, gameRect.Start.Y, gameRect.End.X, gameRect.End.Y); |
| | | //截图 |
| | | System.Drawing.Bitmap bitmap = ScreenCapture.Instance.CaptureScreen(); |
| | |
| | | //min:(0,0.,0.0352941192686558),max:(0.,0.,0.0980392172932625) |
| | | private static ZTHsvFloatColor equipmentColorMin = new ZTHsvFloatColor(0,0, 0); |
| | | private static ZTHsvFloatColor equipmentColorMax = new ZTHsvFloatColor(1, 0.7827f, 0.1099f); |
| | | private static ZTPoint[] equipmentComparePositionss; |
| | | private static Structs.ZTPoint[] equipmentComparePositionss; |
| | | /// <summary> |
| | | /// 获取有装备的所有点,只便利前两行 |
| | | /// </summary> |
| | | /// <param name="startPoint"></param> |
| | | /// <returns></returns> |
| | | public static List<Int32> GetEquipmentIndexs(ZTPoint startPoint) |
| | | public static List<Int32> GetEquipmentIndexs(Structs.ZTPoint startPoint) |
| | | { |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | return GetEquipmentIndexs(image, startPoint); |
| | | } |
| | | |
| | | public static List<Int32> GetEquipmentIndexs(Image<Rgb, byte> image,ZTPoint startPoint) |
| | | public static List<Int32> GetEquipmentIndexs(Image<Rgb, byte> image, Structs.ZTPoint startPoint) |
| | | { |
| | | if (equipmentComparePositionss == null) |
| | | { |
| | | equipmentComparePositionss = new ZTPoint[15 * 15]; |
| | | equipmentComparePositionss = new Structs.ZTPoint[15 * 15]; |
| | | for (int y = 0; y < 15; y++) |
| | | { |
| | | for (int x = 0; x < 15; x++) |
| | | { |
| | | equipmentComparePositionss[y * 15 + x] = new ZTPoint(x, y); |
| | | equipmentComparePositionss[y * 15 + x] = new Structs.ZTPoint(x, y); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | if (rects.Count <= 0) |
| | | { |
| | | return ZTPoint.Empty; |
| | | return Structs.ZTPoint.Empty; |
| | | } |
| | | |
| | | //主角位置 |
| | | ZTPoint rolePosition = gameRect.Start + new ZTPoint(rects[0].Start.X + rolePositionOffset.Width, rects[0].Start.Y + rolePositionOffset.Height); |
| | | Structs.ZTPoint rolePosition = gameRect.Start + new Structs.ZTPoint(rects[0].Start.X + rolePositionOffset.Width, rects[0].Start.Y + rolePositionOffset.Height); |
| | | |
| | | return rolePosition; |
| | | } |
| | |
| | | /// <param name="image"></param> |
| | | /// <param name="gameRect"></param> |
| | | /// <returns></returns> |
| | | public static List<ZTPoint> GetThingItemPoints(Image<Rgb, byte> image, ZTRectangle gameRect) |
| | | public static List<Structs.ZTPoint> GetThingItemPoints(Image<Rgb, byte> image, ZTRectangle gameRect) |
| | | { |
| | | List<ZTLine> lines = CVHelper.FindLines(image, xLineMin,gameRect, Orientation.Horizontal, min, max); |
| | | List<ZTLine> filterLines = new List<ZTLine>(); |
| | | List<ZTPoint> points = new List<ZTPoint>(); |
| | | List<Structs.ZTPoint> points = new List<Structs.ZTPoint>(); |
| | | Func<ZTLine, bool> existsLines = (line) => |
| | | { |
| | | for (int i = 0; i < filterLines.Count; i++) |
| | |
| | | } |
| | | |
| | | filterLines.Add(line); |
| | | points.Add(new ZTPoint(line.X + line.Length / 2, line.Y + thingItemYOffset)); |
| | | points.Add(new Structs.ZTPoint(line.X + line.Length / 2, line.Y + thingItemYOffset)); |
| | | } |
| | | return points; |
| | | } |
| | |
| | | number = 0; |
| | | byte[,,] datas = rangeImage.Data; |
| | | bool one = false, two = false, four = false, eight = false; |
| | | ZTPoint center = locationPointRect.GetCenterPoint(); |
| | | Structs.ZTPoint center = locationPointRect.GetCenterPoint(); |
| | | |
| | | //格1 |
| | | ZTPoint lefttop = center.Add(-11); |
| | | Structs.ZTPoint lefttop = center.Add(-11); |
| | | if (!BlockOf6x6IsColor(datas, lefttop, black)) |
| | | { |
| | | if (!BlockOf6x6IsColor(datas, lefttop, white)) |
| | |
| | | one = true; |
| | | } |
| | | //格2 |
| | | ZTPoint righttop = center.Add(new ZTPoint(5,-11)); |
| | | Structs.ZTPoint righttop = center.Add(new Structs.ZTPoint(5,-11)); |
| | | if (!BlockOf6x6IsColor(datas, righttop, black)) |
| | | { |
| | | if (!BlockOf6x6IsColor(datas, righttop, white)) |
| | |
| | | } |
| | | |
| | | //格4 |
| | | ZTPoint leftbottom = center.Add(new ZTPoint(-11, 5)); |
| | | Structs.ZTPoint leftbottom = center.Add(new Structs.ZTPoint(-11, 5)); |
| | | if (!BlockOf6x6IsColor(datas, leftbottom, black)) |
| | | { |
| | | if (!BlockOf6x6IsColor(datas, leftbottom, white)) |
| | |
| | | } |
| | | |
| | | //格8 |
| | | ZTPoint rightbottom = center.Add(5); |
| | | Structs.ZTPoint rightbottom = center.Add(5); |
| | | if (!BlockOf6x6IsColor(datas, rightbottom, black)) |
| | | { |
| | | if (!BlockOf6x6IsColor(datas, rightbottom, white)) |
| | |
| | | /// <param name="starty"></param> |
| | | /// <param name="color"></param> |
| | | /// <returns></returns> |
| | | private static bool BlockOf6x6IsColor(byte[,,] datas,ZTPoint start, byte color) |
| | | private static bool BlockOf6x6IsColor(byte[,,] datas, Structs.ZTPoint start, byte color) |
| | | { |
| | | for (int y = start.Y; y < start.Y + 6; y++) |
| | | { |
| | |
| | | /// <param name="noPoint"></param> |
| | | /// <param name="limitRect"></param> |
| | | /// <returns></returns> |
| | | public static bool FindYaoqingZuduiWindow(out ZTPoint yesPoint,out ZTPoint noPoint, ZTRectangle limitRect) |
| | | public static bool FindYaoqingZuduiWindow(out Structs.ZTPoint yesPoint,out Structs.ZTPoint noPoint, ZTRectangle limitRect) |
| | | { |
| | | ZTRectangle textRect = ZTRectangle.Empty; |
| | | yesPoint = ZTPoint.Empty; |
| | | noPoint = ZTPoint.Empty; |
| | | yesPoint = Structs.ZTPoint.Empty; |
| | | noPoint = Structs.ZTPoint.Empty; |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | |
| | | if (!CVHelper.FindColorArray(out textRect, image, YaoqingZuduiWindowTitle, limitRect)) |
| | |
| | | return false; |
| | | } |
| | | |
| | | ZTPoint center = textRect.GetCenterPoint(); |
| | | yesPoint = new ZTPoint(center.X - 28, center.Y + 186); |
| | | noPoint = new ZTPoint(center.X + 28, center.Y + 186); |
| | | Structs.ZTPoint center = textRect.GetCenterPoint(); |
| | | yesPoint = new Structs.ZTPoint(center.X - 28, center.Y + 186); |
| | | noPoint = new Structs.ZTPoint(center.X + 28, center.Y + 186); |
| | | return true; |
| | | } |
| | | |
| | |
| | | /// <summary> |
| | | /// 小方格主角偏移 |
| | | /// </summary> |
| | | private static ZTPoint[] houseRoleBlockOffset = new ZTPoint[] { |
| | | new ZTPoint(0,0), |
| | | new ZTPoint(1,0), |
| | | new ZTPoint(0,1), |
| | | new ZTPoint(1,1) |
| | | private static Structs.ZTPoint[] houseRoleBlockOffset = new Structs.ZTPoint[] { |
| | | new Structs.ZTPoint(0,0), |
| | | new Structs.ZTPoint(1,0), |
| | | new Structs.ZTPoint(0,1), |
| | | new Structs.ZTPoint(1,1) |
| | | }; |
| | | |
| | | /// <summary> |
| | |
| | | /// <param name="minMapStart"></param> |
| | | /// <param name="offset"></param> |
| | | /// <returns></returns> |
| | | public static bool GetCurrentHouseIndex(out Int32 houseIndex, Image<Rgb, byte> image, ZTPoint minMapStart) |
| | | public static bool GetCurrentHouseIndex(out Int32 houseIndex, Image<Rgb, byte> image, Structs.ZTPoint minMapStart) |
| | | { |
| | | houseIndex = -1; |
| | | Int32 mainMonsterHouseIndex = -1; |
| | |
| | | Int32 x = minMapStart.X + col * 18; |
| | | Int32 y = minMapStart.Y + row * 18; |
| | | |
| | | ZTPoint position = ZTPoint.Empty; |
| | | Structs.ZTPoint position = Structs.ZTPoint.Empty; |
| | | ZTRectangle limit = new ZTRectangle(x, y, x + 17, y + 17); |
| | | if (CVHelper.FindColorBlock(out position, image, limit, minMinimapRoleColor, maxMinimapRoleColor, houseRoleBlockOffset)) |
| | | { |
| | |
| | | /// <summary> |
| | | /// 小方格色块偏移 |
| | | /// </summary> |
| | | private static ZTPoint[] houseColorBlockOffset = new ZTPoint[] { |
| | | new ZTPoint(2,2), |
| | | new ZTPoint(2,3), |
| | | new ZTPoint(15,14), |
| | | new ZTPoint(15,15), |
| | | private static Structs.ZTPoint[] houseColorBlockOffset = new Structs.ZTPoint[] { |
| | | new Structs.ZTPoint(2,2), |
| | | new Structs.ZTPoint(2,3), |
| | | new Structs.ZTPoint(15,14), |
| | | new Structs.ZTPoint(15,15), |
| | | }; |
| | | /// <summary> |
| | | /// 房间是否开放 |
| | | /// </summary> |
| | | /// <param name="houseIndex"></param> |
| | | /// <returns></returns> |
| | | public static bool HouseIsOpen(Image<Rgb, byte> image, ZTPoint minMapStart, Int32 houseIndex) |
| | | public static bool HouseIsOpen(Image<Rgb, byte> image, Structs.ZTPoint minMapStart, Int32 houseIndex) |
| | | { |
| | | //第一块距上边15px,距左边1px |
| | | Int32 row = houseIndex / 4; |
| | |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <returns></returns> |
| | | public static ZTPoint[] FindMonster(Image<Hsv, byte> image,ZTRectangle gameRect) |
| | | public static Structs.ZTPoint[] FindMonster(Image<Hsv, byte> image,ZTRectangle gameRect) |
| | | { |
| | | List<ZTRectangle> rects = CVHelper.FindBlocks(image, minMonsterHsv, maxMonsterHsv, monsterBlockSize); |
| | | ZTPoint[] monsterPoints = new ZTPoint[rects.Count]; |
| | | Structs.ZTPoint[] monsterPoints = new Structs.ZTPoint[rects.Count]; |
| | | for (int i = 0; i < rects.Count; i++) |
| | | { |
| | | monsterPoints[i] = rects[i].GetCenterPoint().Add(gameRect.Start); |
| | |
| | | { |
| | | continue; |
| | | } |
| | | ZTPoint doorPosition = ZTPoint.Empty; |
| | | Structs.ZTPoint doorPosition = Structs.ZTPoint.Empty; |
| | | for (int i = 0; i < doors.Count; i++) |
| | | { |
| | | doorPosition = new ZTPoint(doors[i].Start.X + (doors[i].End.X - doors[i].Start.X) / 2, doors[i].Start.Y + (doors[i].End.Y - doors[i].Start.Y) / 2); |
| | | doorPosition = new Structs.ZTPoint(doors[i].Start.X + (doors[i].End.X - doors[i].Start.X) / 2, doors[i].Start.Y + (doors[i].End.Y - doors[i].Start.Y) / 2); |
| | | if (doorPosition.X >= limitRect.Start.X && |
| | | doorPosition.X <= limitRect.End.X && |
| | | doorPosition.Y >= limitRect.Start.Y && |
| | |
| | | } |
| | | } |
| | | |
| | | return ZTPoint.Empty; |
| | | return Structs.ZTPoint.Empty; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | return true; |
| | | } |
| | | |
| | | private static ColorArray notificationText = ColorArray.FromHsvFloatString(0.002f, 0.002f, 0.002f, "661,316,255,255,255$658,306,255,255,255$658,308,255,255,255$657,309,255,255,255$657,310,255,255,255$660,311,255,255,255$660,310,255,255,255$659,313,255,255,255$659,312,255,255,255$656,316,255,255,255$657,316,255,255,255$658,316,255,255,255$659,316,255,255,255$660,316,255,255,255$664,316,255,255,255$668,316,255,255,255$668,317,255,255,255$668,313,255,255,255$676,313,255,255,255$676,317,255,255,255$676,311,255,255,255$672,311,255,255,255$668,311,255,255,255$668,309,255,255,255$669,308,255,255,255$672,306,255,255,255$672,308,255,255,255$672,310,255,255,255$673,308,255,255,255$675,308,255,255,255$676,308,255,255,255"); |
| | | /// <summary> |
| | | /// 公告文字 |
| | | /// </summary> |
| | | private static ColorArray notificationGrayText = ColorArray.FromHsvFloatString(0.002f, 0.002f, 0.002f, "645,296,170,170,170$630,291,0,0,0$631,291,170,170,170$632,291,0,0,0$634,291,0,0,0$635,291,170,170,170$636,291,0,0,0$641,291,0,0,0$644,291,0,0,0$645,291,170,170,170$646,291,0,0,0$651,296,0,0,0$650,296,170,170,170$640,296,170,170,170$639,296,0,0,0$638,296,0,0,0$637,296,170,170,170$636,296,0,0,0$634,296,0,0,0$633,296,170,170,170$632,296,0,0,0$630,296,0,0,0$629,296,170,170,170$628,296,0,0,0$628,301,0,0,0$629,301,170,170,170$633,301,170,170,170$637,301,170,170,170$638,301,0,0,0$640,301,0,0,0$641,301,170,170,170$646,301,170,170,170$648,301,170,170,170$649,301,170,170,170$650,301,0,0,0$645,301,170,170,170$645,300,0,0,0$645,299,0,0,0$645,298,170,170,170$645,297,0,0,0$645,296,170,170,170$645,293,170,170,170$645,291,170,170,170$645,290,0,0,0$633,294,0,0,0$633,295,170,170,170$633,296,170,170,170$633,297,0,0,0$633,300,0,0,0$633,302,0,0,0$633,301,170,170,170"); |
| | | private static ColorArray notificationWhiteText = ColorArray.FromHsvFloatString(0.002f, 0.002f, 0.002f, "645,296,255,255,255$630,291,0,0,0$631,291,255,255,255$632,291,0,0,0$634,291,0,0,0$635,291,255,255,255$636,291,0,0,0$641,291,0,0,0$644,291,0,0,0$645,291,255,255,255$646,291,0,0,0$651,296,0,0,0$650,296,255,255,255$640,296,255,255,255$639,296,0,0,0$638,296,0,0,0$637,296,255,255,255$636,296,0,0,0$634,296,0,0,0$633,296,255,255,255$632,296,0,0,0$630,296,0,0,0$629,296,255,255,255$628,296,0,0,0$628,301,0,0,0$629,301,255,255,255$634,301,255,255,255$637,301,255,255,255$638,301,0,0,0$640,301,0,0,0$641,301,255,255,255$647,301,255,255,255$649,301,255,255,255$650,301,0,0,0$645,302,0,0,0$645,301,255,255,255$645,300,0,0,0$645,299,0,0,0$645,298,255,255,255$645,297,0,0,0$645,296,255,255,255$645,293,255,255,255$645,291,255,255,255$645,290,0,0,0$633,294,0,0,0$633,295,255,255,255$633,296,255,255,255$633,300,0,0,0$633,301,255,255,255$633,302,0,0,0"); |
| | | |
| | | /// <summary> |
| | | /// 是否存在公告文本 |
| | |
| | | { |
| | | Image<Rgb, byte> image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | |
| | | if (!CVHelper.FindColorArray(out notificationRect, image, notificationText, gameRect)) |
| | | if (!CVHelper.FindColorArray(out notificationRect, image, notificationGrayText, gameRect)) |
| | | { |
| | | return false; |
| | | if (!CVHelper.FindColorArray(out notificationRect, image, notificationWhiteText, gameRect)) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 已学技能文字 |
| | | /// 技能栏后面的“已学”文字 |
| | | /// 白色 |
| | | /// 灰色 |
| | | /// </summary> |
| | | private static ColorArray[] studayedText = new ColorArray[] { |
| | | ColorArray.FromHsvFloatString(0.002f,0.002f,0.002f,"739,471,255,255,255$739,468,255,255,255$740,468,255,255,255$742,468,255,255,255$743,468,255,255,255$745,468,255,255,255$746,468,255,255,255$747,468,255,255,255$747,469,255,255,255$747,472,255,255,255$747,473,255,255,255$746,473,255,255,255$739,473,255,255,255$739,477,255,255,255$739,476,255,255,255$740,478,255,255,255$741,478,255,255,255$747,478,255,255,255$748,478,255,255,255$748,477,255,255,255$748,476,255,255,255$753,478,255,255,255$755,478,255,255,255$755,474,255,255,255$760,474,255,255,255$750,474,255,255,255$756,473,255,255,255$757,472,255,255,255$758,471,255,255,255$752,471,255,255,255$750,470,255,255,255$750,469,255,255,255$751,469,255,255,255$753,469,255,255,255$755,469,255,255,255$757,469,255,255,255$760,469,255,255,255$760,470,255,255,255"), |
| | | ColorArray.FromHsvFloatString(0.002f,0.002f,0.002f,"739,476,170,170,170$739,468,170,170,170$740,468,170,170,170$743,468,170,170,170$744,468,170,170,170$747,468,170,170,170$747,469,170,170,170$747,472,170,170,170$747,473,170,170,170$746,473,170,170,170$742,473,170,170,170$740,473,170,170,170$739,473,170,170,170$739,472,170,170,170$739,471,170,170,170$739,477,170,170,170$740,478,170,170,170$741,478,170,170,170$744,478,170,170,170$748,478,170,170,170$748,477,170,170,170$748,476,170,170,170$753,478,170,170,170$754,478,170,170,170$755,478,170,170,170$755,477,170,170,170$755,474,170,170,170$750,474,170,170,170$751,474,170,170,170$760,474,170,170,170$759,474,170,170,170$756,473,170,170,170$757,472,170,170,170$758,471,170,170,170$756,471,170,170,170$752,471,170,170,170$750,470,170,170,170$750,469,170,170,170$751,469,170,170,170$757,469,170,170,170$759,469,170,170,170$760,469,170,170,170$760,470,170,170,170"), |
| | | ColorArray.FromHsvFloatString(0.002f,0.002f,0.002f,"710,457,0,0,0$692,457,0,0,0$693,457,255,255,255$696,457,255,255,255$698,457,255,255,255$700,457,255,255,255$701,457,255,255,255$702,457,0,0,0$705,457,0,0,0$706,457,255,255,255$707,457,0,0,0$708,457,0,0,0$709,457,255,255,255$711,457,0,0,0$712,457,255,255,255$713,457,0,0,0$713,460,0,0,0$712,460,255,255,255$709,460,255,255,255$706,460,255,255,255$705,460,0,0,0$702,460,0,0,0$701,460,255,255,255$700,460,0,0,0$694,460,0,0,0$693,460,255,255,255$692,460,0,0,0$692,462,0,0,0$693,462,255,255,255$697,462,255,255,255$701,462,255,255,255$702,462,0,0,0$709,462,0,0,0$710,462,255,255,255$711,462,0,0,0$710,465,0,0,0$709,465,255,255,255$708,465,0,0,0$703,465,0,0,0$702,465,255,255,255$701,465,0,0,0$694,465,0,0,0$693,465,255,255,255$692,465,0,0,0"),//白色 |
| | | ColorArray.FromHsvFloatString(0.002f,0.002f,0.002f,"712,457,170,170,170$692,457,0,0,0$693,457,170,170,170$696,457,170,170,170$698,457,170,170,170$701,457,170,170,170$702,457,0,0,0$705,457,0,0,0$706,457,170,170,170$707,457,0,0,0$708,457,0,0,0$709,457,170,170,170$710,457,0,0,0$711,457,0,0,0$713,457,0,0,0$715,459,0,0,0$714,459,170,170,170$713,459,0,0,0$705,459,0,0,0$704,459,170,170,170$703,459,0,0,0$702,459,0,0,0$701,459,170,170,170$700,459,0,0,0$693,467,0,0,0$694,467,170,170,170$697,467,170,170,170$699,467,170,170,170$702,467,170,170,170$703,467,0,0,0$706,467,0,0,0$707,467,170,170,170$708,467,170,170,170$709,467,170,170,170$710,467,0,0,0$708,468,0,0,0$708,467,170,170,170$708,466,0,0,0$708,464,0,0,0$708,463,170,170,170$708,461,0,0,0$708,460,170,170,170$708,459,0,0,0$708,458,170,170,170$697,456,0,0,0$697,457,170,170,170$697,458,0,0,0$697,461,0,0,0$697,462,170,170,170$697,463,0,0,0$697,466,0,0,0$697,467,170,170,170$697,468,0,0,0"), |
| | | |
| | | }; |
| | | /// <summary> |
| | |
| | | /// <returns></returns> |
| | | private static Bitmap CaptureWindow(IntPtr handle,Int32 x,Int32 y,Int32 width,Int32 height) |
| | | { |
| | | //todo:只截取部分的图 |
| | | // get te hDC of the target window |
| | | IntPtr hdcSrc = Utils.GetWindowDC(handle); |
| | | // get the size |
| | |
| | | public void PressKey(bool pressLeftControl, bool pressRightControl, bool pressLeftShift, bool pressRightShift, bool pressLeftAlt, bool pressRightAlt, bool pressLeftGUI, bool pressRightGUI, params HIDCode[] keys) |
| | | { |
| | | PutDown(pressLeftControl, pressRightControl, pressLeftShift, pressRightShift, pressLeftAlt, pressRightAlt, pressLeftGUI, pressRightGUI, keys); |
| | | Thread.Sleep(100); |
| | | Thread.Sleep(RandomUtils.KeyPressDuration); |
| | | PutDown(false, false, false, false, false, false, false, false); |
| | | Thread.Sleep(100); |
| | | Thread.Sleep(RandomUtils.KeyPressDuration); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | |
| | | void MoveToAndClick(ZTPoint point); |
| | | |
| | | //todo:void DoubleClick() |
| | | |
| | | //todo:void Click(); |
| | | |
| | | //todo:void DragTo(); |
| | | |
| | | /// <summary> |
| | | /// 输入字符串 |
| | |
| | | <Compile Include="Structs\ColorArray.cs" /> |
| | | <Compile Include="Structs\ColorArrayItem.cs" /> |
| | | <Compile Include="Structs\Direction.cs" /> |
| | | <Compile Include="Structs\HousePathInfo.cs" /> |
| | | <Compile Include="Structs\ParametersPoint.cs" /> |
| | | <Compile Include="Structs\ZTLinePoint.cs" /> |
| | | <Compile Include="Structs\MoveQueueItem.cs" /> |
| | | <Compile Include="Structs\Orientation.cs" /> |
| | | <Compile Include="Structs\FindPathInfo.cs" /> |
| | | <Compile Include="Structs\ZTPolygon.cs" /> |
| | | <Compile Include="Structs\ZTColor.cs" /> |
| | | <Compile Include="Structs\ZTColorArrayItem.cs" /> |
| | | <Compile Include="Structs\ZTHsvColor.cs" /> |
| | |
| | | <Compile Include="Structs\ZTSize.cs" /> |
| | | <Compile Include="Structs\ZTSizeDouble.cs" /> |
| | | <Compile Include="Utilitys\ColorUtils.cs" /> |
| | | <Compile Include="Utilitys\GeometryHelper.cs" /> |
| | | <Compile Include="Utilitys\ProcessUtils.cs" /> |
| | | <Compile Include="Utilitys\RandomUtils.cs" /> |
| | | <Compile Include="Utilitys\WindowUtils.cs" /> |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Structs |
| | | { |
| | | /// <summary> |
| | | /// 路径信息 |
| | | /// </summary> |
| | | public class HousePathInfo |
| | | { |
| | | public HousePathInfo() |
| | | { |
| | | Obstacles = new List<ZTPolygon>(); |
| | | LocationPoints = new List<ParametersPoint>(); |
| | | FindPathPoints = new List<ZTPoint>(); |
| | | LoopLines = new List<ZTLinePoint>(); |
| | | FindPathLines = new List<ZTLinePoint>(); |
| | | |
| | | } |
| | | |
| | | public HousePathInfo(Int32 width,Int32 height):this() |
| | | { |
| | | this.Width = width; |
| | | this.Height = height; |
| | | } |
| | | |
| | | |
| | | #region Propertys |
| | | /// <summary> |
| | | /// 宽 |
| | | /// </summary> |
| | | public int Width { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 高 |
| | | /// </summary> |
| | | public int Height { get; set; } |
| | | |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 障碍物 |
| | | /// </summary> |
| | | public List<ZTPolygon> Obstacles { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 定位点 |
| | | /// </summary> |
| | | public List<ParametersPoint> LocationPoints { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 寻路点 |
| | | /// </summary> |
| | | public List<ZTPoint> FindPathPoints{ get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 循逻线 |
| | | /// </summary> |
| | | public List<ZTLinePoint> LoopLines { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 寻路线 |
| | | /// </summary> |
| | | public List<ZTLinePoint> FindPathLines { get; set; } |
| | | |
| | | #endregion |
| | | |
| | | |
| | | #region Editor |
| | | /// <summary> |
| | | /// 添加障碍物 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public bool AddObstacle(ZTPolygon obstacle) |
| | | { |
| | | Int32 index = 0; |
| | | if (ExistsObstacle(out index, obstacle)) |
| | | { |
| | | return false; |
| | | } |
| | | this.Obstacles.Add(obstacle); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 删除障碍物 |
| | | /// </summary> |
| | | /// <param name="obstacle"></param> |
| | | /// <returns></returns> |
| | | public void RemoveObstacle(ZTPolygon obstacle) |
| | | { |
| | | Int32 index = 0; |
| | | if (!ExistsObstacle(out index, obstacle)) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | this.Obstacles.RemoveAt(index); |
| | | return; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否存在障碍物 |
| | | /// </summary> |
| | | /// <param name="obstacle"></param> |
| | | /// <returns></returns> |
| | | private bool ExistsObstacle(out Int32 index,ZTPolygon obstacle) |
| | | { |
| | | index = 0; |
| | | for (int i = 0; i < Obstacles.Count; i++) |
| | | { |
| | | if (Obstacles[i] == obstacle) |
| | | { |
| | | index = i; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 添加定位点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <param name="parameters"></param> |
| | | /// <returns></returns> |
| | | public bool AddLocationPosition(ParametersPoint point) |
| | | { |
| | | if (this.LocationPoints.Exists((p) => { return point.Point == p.Point; })) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | this.LocationPoints.Add(point); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 清空定位点 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public void ClearLocationPosiltion() |
| | | { |
| | | this.LocationPoints.Clear(); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 添加寻路点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | public bool AddFindPathPoint(ZTPoint point) |
| | | { |
| | | Int32 index = 0; |
| | | if (ExistsFindPathPoint(out index, point)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | this.FindPathPoints.Add(point); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 删除寻路点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | public bool RemoveFindPathPoint(ZTPoint point) |
| | | { |
| | | Int32 index = 0; |
| | | if (!ExistsFindPathPoint(out index,point)) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | //查询巡逻线和寻路线是否有用到此点 |
| | | if (ExistsPointInAllLine(point)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | this.FindPathPoints.RemoveAt(index); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否存在指定寻路点 |
| | | /// </summary> |
| | | /// <param name="index"></param> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | private bool ExistsFindPathPoint(out Int32 index, ZTPoint point) |
| | | { |
| | | index = 0; |
| | | for (int i = 0; i < this.FindPathPoints.Count; i++) |
| | | { |
| | | if (this.FindPathPoints[i] == point) |
| | | { |
| | | index = i; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加巡逻线 |
| | | /// </summary> |
| | | /// <param name="line"></param> |
| | | /// <returns></returns> |
| | | public bool AddLoopLine(ZTLinePoint line) |
| | | { |
| | | Int32 index = 0; |
| | | if (ExistsLoopLine(out index, line)) |
| | | { |
| | | return false; |
| | | } |
| | | if (line.P1 == line.P2) |
| | | { |
| | | return false; |
| | | } |
| | | this.LoopLines.Add(line); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 删除巡逻线 |
| | | /// </summary> |
| | | /// <param name="line"></param> |
| | | /// <returns></returns> |
| | | public bool RemoveLoopLine(ZTLinePoint line) |
| | | { |
| | | Int32 index = 0; |
| | | if (!ExistsLoopLine(out index, line)) |
| | | { |
| | | return true; |
| | | } |
| | | this.LoopLines.RemoveAt(index); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否存在巡逻线 |
| | | /// </summary> |
| | | /// <param name="index"></param> |
| | | /// <param name="line"></param> |
| | | /// <returns></returns> |
| | | private bool ExistsLoopLine(out Int32 index, ZTLinePoint line) |
| | | { |
| | | index = 0; |
| | | for (int i = 0; i < this.LoopLines.Count; i++) |
| | | { |
| | | if (this.LoopLines[i] == line) |
| | | { |
| | | index = i; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 添加寻路线 |
| | | /// </summary> |
| | | /// <param name="line"></param> |
| | | /// <returns></returns> |
| | | public bool AddFindPathLine(ZTLinePoint line) |
| | | { |
| | | Int32 index = 0; |
| | | if (ExistsFindPathLine(out index, line)) |
| | | { |
| | | return false; |
| | | } |
| | | this.FindPathLines.Add(line); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 删除寻路线 |
| | | /// </summary> |
| | | /// <param name="line"></param> |
| | | /// <returns></returns> |
| | | public bool RemoveFindPathLine(ZTLinePoint line) |
| | | { |
| | | Int32 index = 0; |
| | | if (!ExistsFindPathLine(out index, line)) |
| | | { |
| | | return true; |
| | | } |
| | | this.FindPathLines.RemoveAt(index); |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否存在寻路线 |
| | | /// </summary> |
| | | /// <param name="index"></param> |
| | | /// <param name="line"></param> |
| | | /// <returns></returns> |
| | | private bool ExistsFindPathLine(out Int32 index, ZTLinePoint line) |
| | | { |
| | | index = 0; |
| | | for (int i = 0; i < this.FindPathLines.Count; i++) |
| | | { |
| | | if (this.FindPathLines[i] == line) |
| | | { |
| | | index = i; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 巡逻线或寻路线中是否存在某点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | private bool ExistsPointInAllLine(ZTPoint point) |
| | | { |
| | | for (int i = 0; i < this.LoopLines.Count; i++) |
| | | { |
| | | if (this.LoopLines[i].P1 == point || this.LoopLines[i].P2 == point) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | for (int i = 0; i < this.FindPathLines.Count; i++) |
| | | { |
| | | if (this.FindPathLines[i].P1 == point || this.FindPathLines[i].P2 == point) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | #endregion |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 获取json |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public string ToJsonString() |
| | | { |
| | | string json = ZTImage.Json.JsonBuilder.ToJsonString(this); |
| | | return json; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 从json字符串生成对象 |
| | | /// </summary> |
| | | /// <param name="json"></param> |
| | | /// <returns></returns> |
| | | public static HousePathInfo FromJsonString(string json) |
| | | { |
| | | return ZTImage.Json.JsonParser.ToObject<HousePathInfo>(json); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 寻找巡逻路线 |
| | | /// </summary> |
| | | /// <param name="rolePosition"></param> |
| | | public static void FindLoopPath(ZTPoint rolePosition) |
| | | { |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 两点之间寻路 |
| | | /// </summary> |
| | | /// <param name="start"></param> |
| | | /// <param name="end"></param> |
| | | public static void FindPath(ZTPoint start, ZTPoint end) |
| | | { |
| | | |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Structs |
| | | { |
| | | /// <summary> |
| | | /// 带参数的点 |
| | | /// </summary> |
| | | public class ParametersPoint |
| | | { |
| | | public ParametersPoint() |
| | | { } |
| | | |
| | | public ParametersPoint(ZTPoint point, Int32 number) |
| | | { |
| | | this.Point = point; |
| | | this.Parameter = number; |
| | | } |
| | | /// <summary> |
| | | /// 点 |
| | | /// </summary> |
| | | public ZTPoint Point { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 参数 |
| | | /// </summary> |
| | | public Int32 Parameter { get; set; } |
| | | |
| | | } |
| | | } |
| | |
| | | this.Y = y; |
| | | this.Length = length; |
| | | } |
| | | public Int32 X; |
| | | public Int32 X { get; set; } |
| | | |
| | | public Int32 Y; |
| | | public Int32 Y { get; set; } |
| | | |
| | | public Int32 Length; |
| | | public Int32 Length { get; set; } |
| | | |
| | | public static bool operator ==(ZTLine a, ZTLine b) |
| | | { |
| | | if (a.X == b.X && a.Y == b.Y && a.Length == b.Length) |
| | | if ((a.X == b.X && a.Y == b.Y && a.Length == b.Length)) |
| | | { |
| | | return true; |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Structs |
| | | { |
| | | /// <summary> |
| | | /// 线 |
| | | /// </summary> |
| | | public class ZTLinePoint |
| | | { |
| | | public static ZTLinePoint Empty; |
| | | |
| | | private ZTPoint p1; |
| | | private ZTPoint p2; |
| | | |
| | | public ZTLinePoint() |
| | | { |
| | | |
| | | } |
| | | |
| | | public ZTLinePoint(ZTPoint p1, ZTPoint p2) |
| | | { |
| | | this.p1 = p1; |
| | | this.p2 = p2; |
| | | } |
| | | |
| | | public ZTPoint P1 |
| | | { |
| | | get { return p1; } |
| | | set { p1 = value; } |
| | | } |
| | | |
| | | public ZTPoint P2 |
| | | { |
| | | get { return p2; } |
| | | set { p2 = value; } |
| | | } |
| | | |
| | | [ZTImage.Reflection.UnSerializedAttribute] |
| | | public Int32 X1 |
| | | { |
| | | get { return p1.X; } |
| | | set { p1.X = value; } |
| | | } |
| | | |
| | | [ZTImage.Reflection.UnSerializedAttribute] |
| | | public Int32 X2 |
| | | { |
| | | get { return p2.X; } |
| | | set { p2.X = value; } |
| | | } |
| | | |
| | | [ZTImage.Reflection.UnSerializedAttribute] |
| | | public Int32 Y1 |
| | | { |
| | | get { return p1.Y; } |
| | | set { p1.Y = value; } |
| | | } |
| | | |
| | | [ZTImage.Reflection.UnSerializedAttribute] |
| | | public Int32 Y2 |
| | | { |
| | | get { return p2.Y; } |
| | | set { p2.Y = value; } |
| | | } |
| | | |
| | | public static bool operator !=(ZTLinePoint a, ZTLinePoint b) |
| | | { |
| | | if (a == b) |
| | | { |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public static bool operator ==(ZTLinePoint a, ZTLinePoint b) |
| | | { |
| | | if ((a.p1 == b.p1 && a.p2 == b.p2) || (a.p1 == b.p2 && a.p2 == b.p1)) |
| | | { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | |
| | | /// <summary> |
| | | /// 点 |
| | | /// </summary> |
| | | public struct ZTPoint : IEquatable<ZTPoint> |
| | | public class ZTPoint : IEquatable<ZTPoint> |
| | | { |
| | | public static ZTPoint Empty = new ZTPoint(0, 0); |
| | | public static ZTPoint Empty = default(ZTPoint); |
| | | |
| | | public ZTPoint(Int32 x, Int32 y) |
| | | { |
| | | this.X = x; |
| | | this.Y = y; |
| | | } |
| | | public Int32 X; |
| | | |
| | | public Int32 Y; |
| | | |
| | | public Int32 X { get; set; } |
| | | |
| | | public Int32 Y { get; set; } |
| | | |
| | | |
| | | |
| | | public static bool operator ==(ZTPoint a, ZTPoint b) |
| New file |
| | |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Structs |
| | | { |
| | | /// <summary> |
| | | /// 多边形 |
| | | /// </summary> |
| | | public class ZTPolygon : IEnumerable<ZTPoint> |
| | | { |
| | | private ZTPoint[] points; |
| | | |
| | | public ZTPolygon(ZTPoint[] points) |
| | | { |
| | | this.points = points; |
| | | } |
| | | |
| | | public ZTPoint[] Points |
| | | { |
| | | get { return points; } |
| | | set { points = value; } |
| | | } |
| | | |
| | | public int Length |
| | | { |
| | | get { return points.Length; } |
| | | } |
| | | |
| | | public ZTPoint this[int index] |
| | | { |
| | | get { return points[index]; } |
| | | set { points[index] = value; } |
| | | } |
| | | |
| | | public static bool operator !=(ZTPolygon a, ZTPolygon b) |
| | | { |
| | | if (a == b) |
| | | { |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public static bool operator ==(ZTPolygon a, ZTPolygon b) |
| | | { |
| | | if (a.Length != b.Length) |
| | | { |
| | | return false; |
| | | } |
| | | for (int i = 0; i < a.Length; i++) |
| | | { |
| | | if (a[i] != b[i]) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public static implicit operator ZTPoint[] (ZTPolygon polygon) |
| | | { |
| | | return polygon.points; |
| | | } |
| | | |
| | | public static implicit operator ZTPolygon(ZTPoint[] points) |
| | | { |
| | | return new ZTPolygon(points); |
| | | } |
| | | |
| | | IEnumerator<ZTPoint> IEnumerable<ZTPoint>.GetEnumerator() |
| | | { |
| | | return (IEnumerator<ZTPoint>)points.GetEnumerator(); |
| | | } |
| | | |
| | | public IEnumerator GetEnumerator() |
| | | { |
| | | return points.GetEnumerator(); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using RichCreator.Utility.Structs; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace RichCreator.Utility.Utilitys |
| | | { |
| | | |
| | | /// <summary> |
| | | /// 几何体之间的关系类型 |
| | | /// </summary> |
| | | public enum Intersection |
| | | { |
| | | None,//没关系 |
| | | Tangent,//切线,正切 |
| | | Intersection,//相交,交叉 |
| | | Containment//包含 |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 与几何相关的辅助类 |
| | | /// </summary> |
| | | public static class GeometryHelper |
| | | { |
| | | /// <summary> |
| | | /// 获取点到点的距离 |
| | | /// </summary> |
| | | /// <param name="a"></param> |
| | | /// <param name="b"></param> |
| | | /// <returns></returns> |
| | | public static double GetPointDistance(ZTPoint a, ZTPoint b) |
| | | { |
| | | return Math.Sqrt((a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y)); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取点到直线的距离 |
| | | /// </summary> |
| | | /// <param name="line"></param> |
| | | /// <param name="point"></param> |
| | | /// <returns></returns> |
| | | public static double GetNearestDistance(ZTLinePoint line, ZTPoint point) |
| | | { |
| | | double a, b, c; |
| | | a = GetPointDistance(line.P2, point); |
| | | if (a <= 0.00001) |
| | | { |
| | | return 0.0f; |
| | | } |
| | | |
| | | b = GetPointDistance(line.P1, point); |
| | | if (b <= 0.00001) |
| | | { |
| | | return 0.0f; |
| | | } |
| | | |
| | | c = GetPointDistance(line.P1, line.P2); |
| | | if (c <= 0.00001) |
| | | { |
| | | //如果PA和PB坐标相同,则退出函数,并返回距离 |
| | | return a; |
| | | } |
| | | |
| | | if (a * a >= b * b + c * c) |
| | | { |
| | | return b; //如果是钝角返回b |
| | | } |
| | | |
| | | if (b * b >= a * a + c * c) |
| | | { |
| | | return a; //如果是钝角返回a |
| | | } |
| | | |
| | | double l = (a + b + c) / 2; //周长的一半 |
| | | double s = Math.Sqrt(Math.Abs(l * (l - a) * (l - b) * (l - c))); //海伦公式求面积,也可以用矢量求 |
| | | return 2 * s / c; |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 判断线段与多边形的关系 |
| | | /// </summary> |
| | | /// <param name="line"></param> |
| | | /// <param name="polygon"></param> |
| | | /// <returns></returns> |
| | | public static Intersection IntersectionOf(ZTLinePoint line, ZTPolygon polygon) |
| | | { |
| | | if (polygon.Length == 0) |
| | | { |
| | | return Intersection.None; |
| | | } |
| | | if (polygon.Length == 1) |
| | | { |
| | | return IntersectionOf(polygon[0], line); |
| | | } |
| | | bool tangent = false; |
| | | for (int index = 0; index < polygon.Length; index++) |
| | | { |
| | | int index2 = (index + 1) % polygon.Length; |
| | | Intersection intersection = IntersectionOf(line, new ZTLinePoint(polygon[index], polygon[index2])); |
| | | if (intersection == Intersection.Intersection) |
| | | { |
| | | return intersection; |
| | | } |
| | | if (intersection == Intersection.Tangent) |
| | | { |
| | | tangent = true; |
| | | } |
| | | } |
| | | return tangent ? Intersection.Tangent : IntersectionOf(line.P1, polygon); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 判断点与多边形的关系 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <param name="polygon"></param> |
| | | /// <returns></returns> |
| | | public static Intersection IntersectionOf(ZTPoint point, ZTPolygon polygon) |
| | | { |
| | | switch (polygon.Length) |
| | | { |
| | | case 0: |
| | | return Intersection.None; |
| | | case 1: |
| | | if (polygon[0].X == point.X && polygon[0].Y == point.Y) |
| | | { |
| | | return Intersection.Tangent; |
| | | } |
| | | else |
| | | { |
| | | return Intersection.None; |
| | | } |
| | | case 2: |
| | | return IntersectionOf(point, new ZTLinePoint(polygon[0], polygon[1])); |
| | | } |
| | | |
| | | int counter = 0; |
| | | int i; |
| | | ZTPoint p1; |
| | | int n = polygon.Length; |
| | | p1 = polygon[0]; |
| | | if (point == p1) |
| | | { |
| | | return Intersection.Tangent; |
| | | } |
| | | |
| | | for (i = 1; i <= n; i++) |
| | | { |
| | | ZTPoint p2 = polygon[i % n]; |
| | | if (point == p2) |
| | | { |
| | | return Intersection.Tangent; |
| | | } |
| | | if (point.Y > Math.Min(p1.Y, p2.Y)) |
| | | { |
| | | if (point.Y <= Math.Max(p1.Y, p2.Y)) |
| | | { |
| | | if (point.X <= Math.Max(p1.X, p2.X)) |
| | | { |
| | | if (p1.Y != p2.Y) |
| | | { |
| | | double xinters = (point.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X; |
| | | if (p1.X == p2.X || point.X <= xinters) |
| | | counter++; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | p1 = p2; |
| | | } |
| | | |
| | | return (counter % 2 == 1) ? Intersection.Containment : Intersection.None; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 判断点与直线的关系 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <param name="line"></param> |
| | | /// <returns></returns> |
| | | public static Intersection IntersectionOf(ZTPoint point, ZTLinePoint line) |
| | | { |
| | | float bottomY = Math.Min(line.Y1, line.Y2); |
| | | float topY = Math.Max(line.Y1, line.Y2); |
| | | bool heightIsRight = point.Y >= bottomY && |
| | | point.Y <= topY; |
| | | //Vertical line, slope is divideByZero error! |
| | | if (line.X1 == line.X2) |
| | | { |
| | | if (point.X == line.X1 && heightIsRight) |
| | | { |
| | | return Intersection.Tangent; |
| | | } |
| | | else |
| | | { |
| | | return Intersection.None; |
| | | } |
| | | } |
| | | float slope = (line.X2 - line.X1) / (line.Y2 - line.Y1); |
| | | bool onLine = (line.Y1 - point.Y) == (slope * (line.X1 - point.X)); |
| | | if (onLine && heightIsRight) |
| | | { |
| | | return Intersection.Tangent; |
| | | } |
| | | else |
| | | { |
| | | return Intersection.None; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 判断直线与直线的关系 |
| | | /// </summary> |
| | | /// <param name="line1"></param> |
| | | /// <param name="line2"></param> |
| | | /// <returns></returns> |
| | | public static Intersection IntersectionOf(ZTLinePoint line1, ZTLinePoint line2) |
| | | { |
| | | // Fail if either line segment is zero-length. |
| | | if (line1.X1 == line1.X2 && line1.Y1 == line1.Y2 || line2.X1 == line2.X2 && line2.Y1 == line2.Y2) |
| | | return Intersection.None; |
| | | |
| | | if (line1.X1 == line2.X1 && line1.Y1 == line2.Y1 || line1.X2 == line2.X1 && line1.Y2 == line2.Y1) |
| | | return Intersection.Intersection; |
| | | if (line1.X1 == line2.X2 && line1.Y1 == line2.Y2 || line1.X2 == line2.X2 && line1.Y2 == line2.Y2) |
| | | return Intersection.Intersection; |
| | | |
| | | // (1) Translate the system so that point A is on the origin. |
| | | line1.X2 -= line1.X1; line1.Y2 -= line1.Y1; |
| | | line2.X1 -= line1.X1; line2.Y1 -= line1.Y1; |
| | | line2.X2 -= line1.X1; line2.Y2 -= line1.Y1; |
| | | |
| | | // Discover the length of segment A-B. |
| | | double distAB = Math.Sqrt(line1.X2 * line1.X2 + line1.Y2 * line1.Y2); |
| | | |
| | | // (2) Rotate the system so that point B is on the positive X axis. |
| | | double theCos = line1.X2 / distAB; |
| | | double theSin = line1.Y2 / distAB; |
| | | double newX = line2.X1 * theCos + line2.Y1 * theSin; |
| | | line2.Y1 = (Int32)(line2.Y1 * theCos - line2.X1 * theSin); line2.X1 = (Int32)newX; |
| | | newX = line2.X2 * theCos + line2.Y2 * theSin; |
| | | line2.Y2 = (Int32)(line2.Y2 * theCos - line2.X2 * theSin); line2.X2 = (Int32)newX; |
| | | |
| | | // Fail if segment C-D doesn't cross line A-B. |
| | | if (line2.Y1 < 0 && line2.Y2 < 0 || line2.Y1 >= 0 && line2.Y2 >= 0) |
| | | return Intersection.None; |
| | | |
| | | // (3) Discover the position of the intersection point along line A-B. |
| | | double posAB = line2.X2 + (line2.X1 - line2.X2) * line2.Y2 / (line2.Y2 - line2.Y1); |
| | | |
| | | // Fail if segment C-D crosses line A-B outside of segment A-B. |
| | | if (posAB < 0 || posAB > distAB) |
| | | return Intersection.None; |
| | | |
| | | // (4) Apply the discovered position to line A-B in the original coordinate system. |
| | | return Intersection.Intersection; |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | /// <summary> |
| | | /// 选角色时的角色选择偏移 |
| | | /// </summary> |
| | | private static ZTPoint[] RoleOffset = new ZTPoint[] { |
| | | new ZTPoint (154,225), |
| | | new ZTPoint (300,225), |
| | | new ZTPoint (443,225), |
| | | new ZTPoint (593,225), |
| | | new ZTPoint (726,225), |
| | | new ZTPoint (883,225), |
| | | private static Utility.Structs.ZTPoint[] RoleOffset = new Utility.Structs.ZTPoint[] { |
| | | new Utility.Structs.ZTPoint (154,225), |
| | | new Utility.Structs.ZTPoint (300,225), |
| | | new Utility.Structs.ZTPoint (443,225), |
| | | new Utility.Structs.ZTPoint (593,225), |
| | | new Utility.Structs.ZTPoint (726,225), |
| | | new Utility.Structs.ZTPoint (883,225), |
| | | |
| | | new ZTPoint (154,455), |
| | | new ZTPoint (300,455), |
| | | new ZTPoint (443,455), |
| | | new ZTPoint (593,455), |
| | | new ZTPoint (726,455), |
| | | new ZTPoint (883,455) |
| | | new Utility.Structs.ZTPoint (154,455), |
| | | new Utility.Structs.ZTPoint (300,455), |
| | | new Utility.Structs.ZTPoint (443,455), |
| | | new Utility.Structs.ZTPoint (593,455), |
| | | new Utility.Structs.ZTPoint (726,455), |
| | | new Utility.Structs.ZTPoint (883,455) |
| | | }; |
| | | |
| | | /// <summary> |
| | |
| | | if (result) |
| | | { |
| | | //点击切换角色按钮624,502 |
| | | G.Instance.InputControl.MoveToAndClick(new ZTPoint(this.GameRect.Start.X + 624, this.GameRect.Start.Y + 502)); |
| | | G.Instance.InputControl.MoveToAndClick(new Utility.Structs.ZTPoint(this.GameRect.Start.X + 624, this.GameRect.Start.Y + 502)); |
| | | return true; |
| | | } |
| | | G.Instance.InfoWriter("退回选择角色界面失败"); |
| | |
| | | private bool LoginWeGame(CancellationToken cancelToken, Int64 timeoutSecond, ZTRectangle weGameRect, ZTRectangle changButtonRect) |
| | | { |
| | | |
| | | ZTPoint basePoint = changButtonRect.GetCenterPoint(); |
| | | Utility.Structs.ZTPoint basePoint = changButtonRect.GetCenterPoint(); |
| | | |
| | | ZTPoint userPoint = new ZTPoint(basePoint.X, basePoint.Y - 148); |
| | | ZTPoint pwdPoint = new ZTPoint(basePoint.X, basePoint.Y - 118); |
| | | ZTPoint loginPoint = new ZTPoint(basePoint.X, basePoint.Y - 42); |
| | | Utility.Structs.ZTPoint userPoint = new Utility.Structs.ZTPoint(basePoint.X, basePoint.Y - 148); |
| | | Utility.Structs.ZTPoint pwdPoint = new Utility.Structs.ZTPoint(basePoint.X, basePoint.Y - 118); |
| | | Utility.Structs.ZTPoint loginPoint = new Utility.Structs.ZTPoint(basePoint.X, basePoint.Y - 42); |
| | | |
| | | //输入用户名 |
| | | G.Instance.InputControl.MoveToAndClick(userPoint); |
| | |
| | | private bool TestHardware() |
| | | { |
| | | testTempVar = false; |
| | | ZTPoint btnPosition = ZTPoint.Empty; |
| | | ZTPoint txtPosition = ZTPoint.Empty; |
| | | Utility.Structs.ZTPoint btnPosition = Utility.Structs.ZTPoint.Empty; |
| | | Utility.Structs.ZTPoint txtPosition = Utility.Structs.ZTPoint.Empty; |
| | | using (ManualResetEvent mre = new ManualResetEvent(false)) |
| | | { |
| | | //等待读取位置成功 |
| | |
| | | private ZTPoint GetElementClickPosition(Control element) |
| | | { |
| | | Point t = element.PointToScreen(new Point(0, 0)); |
| | | ZTPoint t1 = new ZTPoint((Int32)(t.X + element.ActualWidth / 2), (Int32)(t.Y + element.ActualHeight / 2)); |
| | | Utility.Structs.ZTPoint t1 = new Utility.Structs.ZTPoint((Int32)(t.X + element.ActualWidth / 2), (Int32)(t.Y + element.ActualHeight / 2)); |
| | | return t1; |
| | | } |
| | | #endregion |
| File was renamed from src/RichCreator/Maps/MapHouse.cs |
| | |
| | | /// <summary> |
| | | /// 房间信息 |
| | | /// </summary> |
| | | public class MapHouse |
| | | public class HouseInfo |
| | | { |
| | | /// <summary> |
| | | /// 房间编号 |
| | |
| | | /// NextIndex=-1,完成 |
| | | /// NextIndex=-2,出错 |
| | | /// </summary> |
| | | internal static MapHouse[] Houses = new MapHouse[] { |
| | | new MapHouse (){ Index=0 ,NextIndex=1 , OpenStatusDetectIndex=1 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new MapHouse (){ Index=1 ,NextIndex=5 , OpenStatusDetectIndex=5 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, |
| | | new MapHouse (){ Index=2 ,NextIndex=1 , OpenStatusDetectIndex=1 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new MapHouse (){ Index=3 ,NextIndex=2 , OpenStatusDetectIndex=2 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new MapHouse (){ Index=4 ,NextIndex=8 , OpenStatusDetectIndex=8 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, |
| | | new MapHouse (){ Index=5 ,NextIndex=4 , OpenStatusDetectIndex=4 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new MapHouse (){ Index=6 ,NextIndex=5 , OpenStatusDetectIndex=5 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new MapHouse (){ Index=7 ,NextIndex=6 , OpenStatusDetectIndex=6 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new MapHouse (){ Index=8 ,NextIndex=12 ,OpenStatusDetectIndex=12, HouseCenterMoveLine=-148,IsEnd=false,DoorDirection=new[]{Direction.Right,Direction.Bottom } }, |
| | | new MapHouse (){ Index=9 ,NextIndex=10, OpenStatusDetectIndex=10, HouseCenterMoveLine=-300,IsEnd=false,DoorDirection=new[]{Direction.Right,Direction.Bottom } }, |
| | | new MapHouse (){ Index=10,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, |
| | | new MapHouse (){ Index=11,NextIndex=10, OpenStatusDetectIndex=10, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new MapHouse (){ Index=12,NextIndex=13, OpenStatusDetectIndex=12, HouseCenterMoveLine=-220,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new MapHouse (){ Index=13,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-320,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new MapHouse (){ Index=14,NextIndex=15, OpenStatusDetectIndex=-1, HouseCenterMoveLine=-320,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new MapHouse (){ Index=15,NextIndex=-1, OpenStatusDetectIndex=-1, HouseCenterMoveLine=-250,IsEnd=true, DoorDirection=new[]{Direction.Right } }, |
| | | new MapHouse (){ Index=16,NextIndex=12, OpenStatusDetectIndex=12, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, |
| | | new MapHouse (){ Index=17,NextIndex=13, OpenStatusDetectIndex=13, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, |
| | | new MapHouse (){ Index=18,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, |
| | | new MapHouse (){ Index=19,NextIndex=15, OpenStatusDetectIndex=15, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } } |
| | | internal static HouseInfo[] Houses = new HouseInfo[] { |
| | | new HouseInfo (){ Index=0 ,NextIndex=1 , OpenStatusDetectIndex=1 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (){ Index=1 ,NextIndex=5 , OpenStatusDetectIndex=5 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (){ Index=2 ,NextIndex=1 , OpenStatusDetectIndex=1 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=3 ,NextIndex=2 , OpenStatusDetectIndex=2 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=4 ,NextIndex=8 , OpenStatusDetectIndex=8 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (){ Index=5 ,NextIndex=4 , OpenStatusDetectIndex=4 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=6 ,NextIndex=5 , OpenStatusDetectIndex=5 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=7 ,NextIndex=6 , OpenStatusDetectIndex=6 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=8 ,NextIndex=12 ,OpenStatusDetectIndex=12, HouseCenterMoveLine=-148,IsEnd=false,DoorDirection=new[]{Direction.Right,Direction.Bottom } }, |
| | | new HouseInfo (){ Index=9 ,NextIndex=10, OpenStatusDetectIndex=10, HouseCenterMoveLine=-300,IsEnd=false,DoorDirection=new[]{Direction.Right,Direction.Bottom } }, |
| | | new HouseInfo (){ Index=10,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, |
| | | new HouseInfo (){ Index=11,NextIndex=10, OpenStatusDetectIndex=10, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, |
| | | new HouseInfo (){ Index=12,NextIndex=13, OpenStatusDetectIndex=12, HouseCenterMoveLine=-220,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (){ Index=13,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-320,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (){ Index=14,NextIndex=15, OpenStatusDetectIndex=-1, HouseCenterMoveLine=-320,IsEnd=false,DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (){ Index=15,NextIndex=-1, OpenStatusDetectIndex=-1, HouseCenterMoveLine=-250,IsEnd=true, DoorDirection=new[]{Direction.Right } }, |
| | | new HouseInfo (){ Index=16,NextIndex=12, OpenStatusDetectIndex=12, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, |
| | | new HouseInfo (){ Index=17,NextIndex=13, OpenStatusDetectIndex=13, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, |
| | | new HouseInfo (){ Index=18,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, |
| | | new HouseInfo (){ Index=19,NextIndex=15, OpenStatusDetectIndex=15, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } } |
| | | }; |
| | | |
| | | static LindongMap() |
| | |
| | | /// <summary> |
| | | /// 小地图区域 |
| | | /// </summary> |
| | | public ZTPoint MinimapPoint = ZTPoint.Empty; |
| | | public Utility.Structs.ZTPoint MinimapPoint = Utility.Structs.ZTPoint.Empty; |
| | | |
| | | //小地图距游戏区域的偏移 |
| | | private ZTPoint minimapPointOffset = new ZTPoint(1201, 47); |
| | | private Utility.Structs.ZTPoint minimapPointOffset = new Utility.Structs.ZTPoint(1201, 47); |
| | | |
| | | public CancellationToken cancellationToken { get; set; } |
| | | |
| | |
| | | private void ExitToTown() |
| | | { |
| | | G.Instance.DebugWriter("返回城镇"); |
| | | ZTPoint point = new ZTPoint(this.GameRect.End.X - 124, this.GameRect.Start.Y + 146); |
| | | Utility.Structs.ZTPoint point = new Utility.Structs.ZTPoint(this.GameRect.End.X - 124, this.GameRect.Start.Y + 146); |
| | | G.Instance.InputControl.MoveToAndClick(point); |
| | | Thread.Sleep(5000); |
| | | } |
| | |
| | | private void ReplayGame() |
| | | { |
| | | G.Instance.DebugWriter("重新挑战"); |
| | | ZTPoint point = new ZTPoint(this.GameRect.End.X - 132, this.GameRect.Start.Y + 90); |
| | | Utility.Structs.ZTPoint point = new Utility.Structs.ZTPoint(this.GameRect.End.X - 132, this.GameRect.Start.Y + 90); |
| | | G.Instance.InputControl.MoveToAndClick(point); |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | DateTime roomStartTime = DateTime.Now; |
| | | KillMonsterStateMachine kmsm = new KillMonsterStateMachine(Houses[houseIndex], this.MinimapPoint, this.GameRect, preHouseIndex,this.runningStep); |
| | | ZTResult smresult = kmsm.Work(cancellationToken, 5 * 60 * 1000); |
| | | KillMonsterStateMachine kmsm = new KillMonsterStateMachine(Houses[houseIndex], this.MinimapPoint, this.GameRect, preHouseIndex,this.runningStep, cancellationToken); |
| | | ZTResult smresult = kmsm.Work( 5 * 60 * 1000); |
| | | Int32 roomTotalSecond = (Int32)(DateTime.Now - roomStartTime).TotalSeconds; |
| | | G.Instance.InfoWriter("房间刷完,用时:" + (roomTotalSecond / 60) + "分" + (roomTotalSecond % 60) + "秒"); |
| | | runningStep = RunningStep.None; |
| | |
| | | bool result = FuncUtils.NoChangeRetryCallWrap( |
| | | () => |
| | | { |
| | | |
| | | WindowUtils.SetDnfToTop(); |
| | | CloseAllAlertWindow(this.cancellationToken, this.GameRect); |
| | | //向下走出赛丽亚的房间 ,走向素喃 |
| | | G.Instance.InputControl.PressKey(2000, HIDCode.DownArrow); |
| | |
| | | /// <returns></returns> |
| | | private bool MoveToShikongzhimen() |
| | | { |
| | | bool result=FuncUtils.NoChangeRetryCallWrap(() => |
| | | bool result= FuncUtils.NoChangeRetryCallWrap(() => |
| | | { |
| | | //打开地图 |
| | | ZTPoint mapButtonPosition = new ZTPoint(this.GameRect.End.X - 14, this.GameRect.Start.Y + 16); |
| | | Utility.Structs.ZTPoint mapButtonPosition = new Utility.Structs.ZTPoint(this.GameRect.End.X - 14, this.GameRect.Start.Y + 16); |
| | | G.Instance.InputControl.MoveToAndClick(mapButtonPosition); |
| | | Thread.Sleep(1000); |
| | | |
| | | |
| | | //点到副本之前的地图 |
| | | ZTPoint mapPrePosition = new ZTPoint(this.GameRect.Start.X + 382, this.GameRect.Start.Y + 252); |
| | | Utility.Structs.ZTPoint mapPrePosition = new Utility.Structs.ZTPoint(this.GameRect.Start.X + 382, this.GameRect.Start.Y + 252); |
| | | G.Instance.InputControl.MoveToAndClick(mapPrePosition); |
| | | |
| | | //关闭地图框 |
| | |
| | | return true; |
| | | } |
| | | |
| | | G.Instance.InputControl.MoveToAndClick(new ZTPoint(this.GameRect.Start.X + 508, this.GameRect.Start.Y + 552)); |
| | | G.Instance.InputControl.MoveToAndClick(new Utility.Structs.ZTPoint(this.GameRect.Start.X + 508, this.GameRect.Start.Y + 552)); |
| | | Thread.Sleep(5000); |
| | | image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | if (LindongCVHelper.GetChoiceLingdongNandu(out nandu, image, this.GameRect)) |
| | |
| | | |
| | | if (!result) |
| | | { |
| | | //todo:remove |
| | | G.Instance.InfoWriter("装备文字未取到"); |
| | | return false; |
| | | } |
| | |
| | | |
| | | |
| | | //开始点,每格步进30 |
| | | ZTPoint startPoint = new ZTPoint( equipmentTextRect.End.X-30,equipmentTextRect.End.Y+9); |
| | | Utility.Structs.ZTPoint startPoint = new Utility.Structs.ZTPoint( equipmentTextRect.End.X-30, equipmentTextRect.End.Y+9); |
| | | List<Int32> points = DnfCVHelper.GetEquipmentIndexs(startPoint); |
| | | |
| | | for (int i = 0; i < points.Count; i++) |
| | |
| | | int col = index % 8; |
| | | int x = col * 30+15; |
| | | int y = row * 30+15; |
| | | |
| | | |
| | | //点窗格 |
| | | G.Instance.InputControl.MoveToAndClick(new ZTPoint(startPoint.X+x,startPoint.Y+y)); |
| | | G.Instance.InputControl.MoveToAndClick(new Utility.Structs.ZTPoint(startPoint.X + x, startPoint.Y + y)); |
| | | Thread.Sleep(500); |
| | | //点确定 |
| | | G.Instance.InputControl.Move(0, 0, true, false, false); |
| | |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.Escape); |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | /// </summary> |
| | | public abstract class MapInfo |
| | | { |
| | | public MapInfo() |
| | | { |
| | | |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 地图名称 |
| | | /// </summary> |
| | |
| | | { |
| | | //如果当前选的是tp技能学习(tp技能学习的右侧滚动条跟sp右侧的不一样),则: |
| | | //选中sp技能学习 |
| | | ZTPoint spPoint = new ZTPoint(lvRect.End.X + 55, lvRect.Start.Y - 80); |
| | | Utility.Structs.ZTPoint spPoint = new Utility.Structs.ZTPoint(lvRect.End.X + 55, lvRect.Start.Y - 80); |
| | | G.Instance.InputControl.MoveToAndClick(spPoint); |
| | | |
| | | result = FuncUtils.TimeoutCancelableWrap(3000, this.cancellationToken, () => { |
| | |
| | | private bool InitSkills() |
| | | { |
| | | //点击初始化 |
| | | ZTPoint initButton = new ZTPoint(this.upKeyRect.Start.X - 37, this.upKeyRect.Start.Y - 86); |
| | | Utility.Structs.ZTPoint initButton = new Utility.Structs.ZTPoint(this.upKeyRect.Start.X - 37, this.upKeyRect.Start.Y - 86); |
| | | G.Instance.InputControl.MoveToAndClick(initButton); |
| | | |
| | | //是否已打开确认对话框 |
| | |
| | | G.Instance.DebugWriter("公告未找到"); |
| | | return false; |
| | | } |
| | | |
| | | //点击确认 |
| | | G.Instance.InputControl.Move(0, 0, true, false, false); |
| | | Thread.Sleep(RandomUtils.MouseClickDuration); |
| | | G.Instance.InputControl.Move(0, 0, false, false, false); |
| | | Thread.Sleep(1000); |
| | | |
| | | |
| | | //是否已打开完毕对话框 |
| | | result = FuncUtils.TimeoutCancelableWrap(3000, this.cancellationToken, () => { |
| | |
| | | return false; |
| | | } |
| | | //点击确认 |
| | | ZTPoint okPosition = new ZTPoint(notificationRect.GetCenterPoint().X, notificationRect.End.Y + 70); |
| | | Utility.Structs.ZTPoint okPosition = new Utility.Structs.ZTPoint(notificationRect.GetCenterPoint().X, notificationRect.End.Y + 60); |
| | | G.Instance.InputControl.MoveToAndClick(okPosition); |
| | | Thread.Sleep(RandomUtils.G(500,800)); |
| | | return true; |
| | |
| | | private bool SettingTopSkills() |
| | | { |
| | | //物理暴击 |
| | | ZTPoint skillPoint = new ZTPoint(lvRect.End.X + 200, lvRect.Start.Y - 42); |
| | | Utility.Structs.ZTPoint skillPoint = new Utility.Structs.ZTPoint(lvRect.End.X + 200, lvRect.Start.Y - 42); |
| | | SettingSkill(skillPoint); |
| | | |
| | | //物理背击 |
| | | skillPoint = new ZTPoint(lvRect.End.X + 280, lvRect.Start.Y - 42); |
| | | skillPoint = new Utility.Structs.ZTPoint(lvRect.End.X + 280, lvRect.Start.Y - 42); |
| | | SettingSkill(skillPoint); |
| | | return true; |
| | | } |
| | |
| | | /// 要点的技能列表 |
| | | /// 内部为每个节所相对于节的相对位置 |
| | | /// </summary> |
| | | private List<ZTPoint>[] toAddLevelSkills = new List<ZTPoint>[] { |
| | | new List<ZTPoint> (){ |
| | | new ZTPoint(762-346,450-237),//疾风之棍棒精通 |
| | | private List<Utility.Structs.ZTPoint>[] toAddLevelSkills = new List<Utility.Structs.ZTPoint>[] { |
| | | new List<Utility.Structs.ZTPoint> (){ |
| | | new Utility.Structs.ZTPoint(762-346,450-237),//疾风之棍棒精通 |
| | | }, |
| | | new List<ZTPoint> (){ |
| | | new ZTPoint(182,17),//朔风牵引 |
| | | new ZTPoint(274,17),//流风决 |
| | | new ZTPoint(481-251,342-262),//风鸣冲击 |
| | | new ZTPoint(323,82),//游离之风 |
| | | new ZTPoint(574-251,409-262),//双翼风刃 |
| | | new ZTPoint(574-251,477-262),//风暴之眼 |
| | | new ZTPoint(529-251,544-262),//真空旋风破 |
| | | new List<Utility.Structs.ZTPoint> (){ |
| | | new Utility.Structs.ZTPoint(182,17),//朔风牵引 |
| | | new Utility.Structs.ZTPoint(274,17),//流风决 |
| | | new Utility.Structs.ZTPoint(481-251,342-262),//风鸣冲击 |
| | | new Utility.Structs.ZTPoint(323,82),//游离之风 |
| | | new Utility.Structs.ZTPoint(574-251,409-262),//双翼风刃 |
| | | new Utility.Structs.ZTPoint(574-251,477-262),//风暴之眼 |
| | | new Utility.Structs.ZTPoint(529-251,544-262),//真空旋风破 |
| | | }, |
| | | new List<ZTPoint> (){ |
| | | new ZTPoint(432-251,275-329),//风暴之拳 |
| | | new ZTPoint(479-251,342-329),//万象风龙阵 |
| | | new ZTPoint(572-251,340-329),//御风之力 |
| | | new ZTPoint(433-251,478-329),//风神决 |
| | | new ZTPoint(526-251,475-329),//风卷残云 |
| | | new ZTPoint(574-251,476-329),//游龙惊风破 |
| | | new ZTPoint(431-251,542-329),//九霄风雷 |
| | | new ZTPoint(663-295,545-331),//无限风域 |
| | | new List<Utility.Structs.ZTPoint> (){ |
| | | new Utility.Structs.ZTPoint(432-251,275-329),//风暴之拳 |
| | | new Utility.Structs.ZTPoint(479-251,342-329),//万象风龙阵 |
| | | new Utility.Structs.ZTPoint(572-251,340-329),//御风之力 |
| | | new Utility.Structs.ZTPoint(433-251,478-329),//风神决 |
| | | new Utility.Structs.ZTPoint(526-251,475-329),//风卷残云 |
| | | new Utility.Structs.ZTPoint(574-251,476-329),//游龙惊风破 |
| | | new Utility.Structs.ZTPoint(431-251,542-329),//九霄风雷 |
| | | new Utility.Structs.ZTPoint(663-295,545-331),//无限风域 |
| | | } |
| | | }; |
| | | |
| | |
| | | private bool SettingSPSkills() |
| | | { |
| | | //选中sp技能学习 |
| | | ZTPoint spPoint = new ZTPoint(lvRect.End.X + 55, lvRect.Start.Y - 80); |
| | | Utility.Structs.ZTPoint spPoint = new Utility.Structs.ZTPoint(lvRect.End.X + 55, lvRect.Start.Y - 80); |
| | | G.Instance.InputControl.MoveToAndClick(spPoint); |
| | | |
| | | ZTRectangle numberLimitArea = new ZTRectangle(lvRect.Start.X-5,lvRect.End.Y,lvRect.End.X+21,lvRect.End.Y+340); |
| | |
| | | private bool SettingTPSkills() |
| | | { |
| | | //选中tp技能学习 |
| | | ZTPoint spPoint = new ZTPoint(lvRect.End.X + 253, lvRect.Start.Y - 80); |
| | | Utility.Structs.ZTPoint spPoint = new Utility.Structs.ZTPoint(lvRect.End.X + 253, lvRect.Start.Y - 80); |
| | | G.Instance.InputControl.MoveToAndClick(spPoint); |
| | | |
| | | ZTPoint[] skills = new ZTPoint[] { |
| | | Utility.Structs.ZTPoint[] skills = new Utility.Structs.ZTPoint[] { |
| | | |
| | | new ZTPoint(334-296,277-251),//1.第一行第一个 |
| | | new ZTPoint(381-296,545-251),//2.第三行第二个 |
| | | new ZTPoint(664-296,413-251),//3.第二行倒数第三个 |
| | | new ZTPoint(567-296,410-251),//4.第二行倒数第五个 |
| | | new ZTPoint(758-296,411-251),//5.第二行倒数第一个 |
| | | new Utility.Structs.ZTPoint(334-296,277-251),//1.第一行第一个 |
| | | new Utility.Structs.ZTPoint(381-296,545-251),//2.第三行第二个 |
| | | new Utility.Structs.ZTPoint(664-296,413-251),//3.第二行倒数第三个 |
| | | new Utility.Structs.ZTPoint(567-296,410-251),//4.第二行倒数第五个 |
| | | new Utility.Structs.ZTPoint(758-296,411-251),//5.第二行倒数第一个 |
| | | }; |
| | | |
| | | for (int i = 0; i < skills.Length; i++) |
| | |
| | | /// <returns></returns> |
| | | private bool Studay() |
| | | { |
| | | ZTPoint studayPoint = new ZTPoint(this.downKeyRect.Start.X-331,this.downKeyRect.End.Y+27); |
| | | Utility.Structs.ZTPoint studayPoint = new Utility.Structs.ZTPoint(this.downKeyRect.Start.X-331,this.downKeyRect.End.Y+27); |
| | | G.Instance.InputControl.MoveToAndClick(studayPoint); |
| | | Thread.Sleep(1000); |
| | | //点击确认 |
| | |
| | | /// </summary> |
| | | /// <param name="skillPoint"></param> |
| | | /// <returns></returns> |
| | | private bool SettingSkill(ZTPoint skillPoint) |
| | | private bool SettingSkill(Utility.Structs.ZTPoint skillPoint) |
| | | { |
| | | //84,71 |
| | | ZTRectangle limitRect = new ZTRectangle(skillPoint.X-84,skillPoint.Y-71,skillPoint.X+84,skillPoint.Y+71); |
| | |
| | | { |
| | | studayTextRect = ZTRectangle.Empty; |
| | | ZTRectangle innerstudyTextRect = ZTRectangle.Empty; |
| | | ZTPoint openwindowButton = new ZTPoint(this.titleRect.Start.X + 194, this.titleRect.Start.Y + 517); |
| | | Utility.Structs.ZTPoint openwindowButton = new Utility.Structs.ZTPoint(this.titleRect.Start.X + 194, this.titleRect.Start.Y + 517); |
| | | for (int i = 0; i < 2; i++) |
| | | { |
| | | if (this.cancellationToken.IsCancellationRequested) |
| | |
| | | return false; |
| | | } |
| | | //获取位置,并将鼠标移到位置,显示出技能名 |
| | | ZTPoint studayPoint = GetStudaySkillRect(studayTextRect, i).GetCenterPoint(); |
| | | Utility.Structs.ZTPoint studayPoint = GetStudaySkillRect(studayTextRect, i).GetCenterPoint(); |
| | | G.Instance.InputControl.MoveTo(studayPoint.X, studayPoint.Y, false, false, false); |
| | | Thread.Sleep(1000); |
| | | |
| | |
| | | if (skillToExpressMap.ContainsKey(skillIndex)) |
| | | { |
| | | //要放到技能栏的位置 |
| | | ZTPoint to = GetExpressSkillRect(skillToExpressMap[skillIndex]).GetCenterPoint(); |
| | | Utility.Structs.ZTPoint to = GetExpressSkillRect(skillToExpressMap[skillIndex]).GetCenterPoint(); |
| | | MoveSkill(studayPoint, to); |
| | | count--; |
| | | continue; |
| | |
| | | /// <param name="from"></param> |
| | | /// <param name="to"></param> |
| | | /// <returns></returns> |
| | | private bool MoveSkill(ZTPoint from, ZTPoint to) |
| | | private bool MoveSkill(Utility.Structs.ZTPoint from, Utility.Structs.ZTPoint to) |
| | | { |
| | | //移动指定位置 |
| | | G.Instance.InputControl.MoveTo(from.X, from.Y, false, false, false); |
| | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | ZTPoint windowCenter = createGroupWindowTextRect.GetCenterPoint(); |
| | | G.Instance.InputControl.MoveToAndClick(new ZTPoint(windowCenter.X + 50, windowCenter.Y + 80)); |
| | | |
| | | Utility.Structs.ZTPoint windowCenter = createGroupWindowTextRect.GetCenterPoint(); |
| | | G.Instance.InputControl.MoveToAndClick(new Utility.Structs.ZTPoint(windowCenter.X + 50, windowCenter.Y + 80)); |
| | | //清空文字 |
| | | for (int i = 0; i < 15; i++) |
| | | { |
| | |
| | | G.Instance.InfoWriter("create group ok"); |
| | | //点击组队“确定”按钮 |
| | | result = FuncUtils.TimeoutCancelableWrap(15 * 60 * 1000,this.cancellationToken, () => { |
| | | ZTPoint yes = ZTPoint.Empty; |
| | | ZTPoint no = ZTPoint.Empty; |
| | | Utility.Structs.ZTPoint yes = Utility.Structs.ZTPoint.Empty; |
| | | Utility.Structs.ZTPoint no = Utility.Structs.ZTPoint.Empty; |
| | | bool retFind = GroupCVHelper.FindYaoqingZuduiWindow(out yes, out no, this.GameRect); |
| | | if (retFind) |
| | | { |
| | | G.Instance.InputControl.MoveToAndClick(yes); |
| | | G.Instance.InfoWriter("other join group ok:"+yes); |
| | | G.Instance.InfoWriter("other join group ok:"+ yes); |
| | | } |
| | | return retFind; |
| | | }); |
| | |
| | | return true; |
| | | } |
| | | |
| | | ZTPoint searchButtonCenerPoint = searchButtonRect.GetCenterPoint(); |
| | | Utility.Structs.ZTPoint searchButtonCenerPoint = searchButtonRect.GetCenterPoint(); |
| | | //输入组名 |
| | | G.Instance.InputControl.MoveToAndClick(new ZTPoint (searchButtonCenerPoint.X-80,searchButtonCenerPoint.Y)); |
| | | G.Instance.InputControl.MoveToAndClick(new Utility.Structs.ZTPoint (searchButtonCenerPoint.X-80, searchButtonCenerPoint.Y)); |
| | | DeleteAllChar(groupName.Length + 3); |
| | | G.Instance.InputControl.InputString(groupName); |
| | | |
| | |
| | | <Compile Include="Models\RunningModel.cs" /> |
| | | <Compile Include="Models\RunningStep.cs" /> |
| | | <Compile Include="StateMachines\KillMonsterStateMachine.cs" /> |
| | | <Compile Include="StateMachines\KillMonsterStateResult.cs" /> |
| | | <Compile Include="StateMachines\MoveState.cs" /> |
| | | <Compile Include="StateMachines\SkillInfo.cs" /> |
| | | <Compile Include="StateMachines\SkillQueue.cs" /> |
| | | <Compile Include="Maps\MapHouse.cs" /> |
| | | <Compile Include="Maps\HouseInfo.cs" /> |
| | | <Compile Include="Maps\Lindong\LindongMap.cs" /> |
| | | <Compile Include="Maps\MapInfo.cs" /> |
| | | <Compile Include="Models\RichCreatorConfig.cs" /> |
| | |
| | | using RichCreator.StateMachines; |
| | | using RichCreator.Utilitys; |
| | | using static RichCreator.Utilitys.AttackRectangle; |
| | | using Utils= RichCreator.Utilitys.Utils; |
| | | using Utils = RichCreator.Utilitys.Utils; |
| | | using ZTImage.Collections; |
| | | |
| | | namespace RichCreator.Jobs.StateMachines |
| | | { |
| | | /// <summary> |
| | | /// 状态动作 |
| | | /// </summary> |
| | | /// <param name=""></param> |
| | | /// <param name=""></param> |
| | | /// <param name=""></param> |
| | | /// <returns></returns> |
| | | public delegate KillMonsterStateResult StateAction(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage); |
| | | |
| | | /// <summary> |
| | | /// 杀怪状态机 |
| | | /// </summary> |
| | | public class KillMonsterStateMachine:StateMachineBase |
| | | public class KillMonsterStateMachine : StateMachineBase |
| | | { |
| | | private const Int32 NoMoveMaxMillSecond = 2000;//最大未移动容忍毫秒数 |
| | | private StateAction[] states;//状态动作列表 |
| | | private MapHouse house;//当前房间 |
| | | |
| | | private HouseInfo house;//当前房间 |
| | | private ZTPoint miniMapStart;//小地图区域 |
| | | private ZTRectangle gameRect;//游戏区域 |
| | | private ZTRectangle GameRect;//游戏区域 |
| | | private Int32 preHouseIndex = 0;//上一房间编号 |
| | | private MoveState moveState;//移动状态 |
| | | private OutOfBounds outOfBounds;//是否在禁区 |
| | | private bool exitResult;//退出结果 |
| | | private OutOfBounds outOfBounds;//禁区 |
| | | private bool isSuccess;//退出结果 |
| | | |
| | | |
| | | private ZTPoint roleLastPosition=ZTPoint.Empty;//角色最后位置 |
| | | |
| | | private ZTPoint roleLastPosition = ZTPoint.Empty;//角色最后位置 |
| | | private Int32 runningStep = RunningStep.None;//是否恢复的状态 |
| | | |
| | | //当前状态 |
| | | private KillMonsterStates currentState = KillMonsterStates.Start; |
| | | //是否截图屏幕 |
| | | private bool captureScreen = false; |
| | | |
| | | //怪 |
| | | private ZTPoint[] stateMonsters; |
| | | |
| | | private System.Drawing.Bitmap bitmap = null; |
| | | //原图 |
| | | private Image<Rgb, byte> image = null; |
| | | |
| | | //图像是否改变 |
| | | private bool imageIsChange = false; |
| | | |
| | | //色彩hsv |
| | | private Image<Hsv, byte> hsvImage = null; |
| | | //取消令牌 |
| | | private CancellationToken cancellationToken = CancellationToken.None; |
| | | #region Find Door Info |
| | | //门坐标 |
| | | private ZTPoint stateDoorPosition; |
| | |
| | | private Direction stateDoorLevelDirect = Direction.None; |
| | | //定位点方框 |
| | | private MultiList<ZTRectangle, Int32> stateLocationRectangle = new MultiList<ZTRectangle, int>(); |
| | | //怪 |
| | | private ZTPoint[] stateMonsters; |
| | | |
| | | |
| | | |
| | | |
| | | #endregion |
| | | |
| | | |
| | | public KillMonsterStateMachine(MapHouse house, ZTPoint miniMapStart, ZTRectangle gameRect,Int32 preHouseIndex,Int32 runningStep) |
| | | public KillMonsterStateMachine(HouseInfo house, ZTPoint miniMapStart, ZTRectangle gameRect, Int32 preHouseIndex, Int32 runningStep, CancellationToken cancellationToken) |
| | | { |
| | | this.runningStep = runningStep; |
| | | this.house = house; |
| | | this.miniMapStart = miniMapStart; |
| | | this.gameRect = gameRect; |
| | | this.GameRect = gameRect; |
| | | this.preHouseIndex = preHouseIndex; |
| | | moveState = new MoveState(this.gameRect, this.house); |
| | | outOfBounds = new OutOfBounds(this.gameRect,moveState); |
| | | |
| | | InitStates(); |
| | | this.cancellationToken = cancellationToken; |
| | | moveState = new MoveState(this.GameRect, this.house); |
| | | outOfBounds = new OutOfBounds(this.GameRect, moveState); |
| | | hsvImage = new Image<Hsv, byte>(gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | private void SetState(KillMonsterStates current, bool capture) |
| | | { |
| | | currentState = current; |
| | | captureScreen = capture; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 状态机开始 |
| | | /// </summary> |
| | |
| | | /// <param name="cancellationToken"></param> |
| | | /// <param name="timeoutMillSecond"></param> |
| | | /// <returns></returns> |
| | | public ZTResult Work(CancellationToken cancellationToken, Int32 timeoutMillSecond) |
| | | public ZTResult Work(Int32 timeoutMillSecond) |
| | | { |
| | | DateTime expireTime = DateTime.Now.AddMilliseconds(timeoutMillSecond); |
| | | KillMonsterStateResult result = new KillMonsterStateResult(STATE_Start, false); |
| | | if (this.runningStep > RunningStep.None) |
| | | { |
| | | result = new KillMonsterStateResult(STATE_FindMonster, true); |
| | | SetState(KillMonsterStates.FindMonster, true); |
| | | } |
| | | System.Drawing.Bitmap bitmap; |
| | | //原图 |
| | | Image<Rgb, byte> image = null; |
| | | //色彩hsv |
| | | Image<Hsv, byte> hsvImage = new Image<Hsv, byte>(gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1); |
| | | |
| | | |
| | | while (true) |
| | | { |
| | | byte currentState = result.NextState; |
| | | if (cancellationToken.IsCancellationRequested) |
| | | { |
| | | G.Instance.DebugWriter("取消刷图"); |
| | |
| | | this.moveState.StopMove(); |
| | | return ZTResult.Timeout; |
| | | } |
| | | if (result.NextState == STATE_Exit) |
| | | { |
| | | G.Instance.DebugWriter("退出状态"); |
| | | this.moveState.StopMove(); |
| | | if (this.exitResult) |
| | | { |
| | | return ZTResult.Success; |
| | | } |
| | | return ZTResult.Failed; |
| | | |
| | | } |
| | | |
| | | bool refreshScreen = result.RefreshScreen; |
| | | if (refreshScreen) |
| | | if (captureScreen) |
| | | { |
| | | using (bitmap = ScreenCapture.Instance.CaptureScreen()) |
| | | { |
| | | image = new Image<Rgb, byte>(bitmap); |
| | | image = image.GetSubRect(new System.Drawing.Rectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1)); |
| | | CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | } |
| | | |
| | | if (this.house.Index != 15) |
| | | { |
| | | //计算是否进入其它房间 |
| | | Int32 houseIndex; |
| | | if (!LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart)) |
| | | if (image != null) |
| | | { |
| | | //得不到房间 |
| | | if (!FuncUtils.TimeoutCancelableWrap(30 * 1000, cancellationToken, () => { |
| | | using (bitmap = ScreenCapture.Instance.CaptureScreen()) |
| | | { |
| | | image = new Image<Rgb, byte>(bitmap); |
| | | image = image.GetSubRect(new System.Drawing.Rectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1)); |
| | | return LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart); |
| | | } |
| | | }, 50)) |
| | | { |
| | | return ZTResult.Failed; |
| | | } |
| | | image.Dispose(); |
| | | } |
| | | if (houseIndex != this.house.Index) |
| | | image = new Image<Rgb, byte>(bitmap); |
| | | image = image.GetSubRect(new System.Drawing.Rectangle(GameRect.Start.X, GameRect.Start.Y, GameRect.End.X - GameRect.Start.X + 1, GameRect.End.Y - GameRect.Start.Y + 1)); |
| | | imageIsChange = true; |
| | | } |
| | | } |
| | | |
| | | switch (currentState) |
| | | { |
| | | case KillMonsterStates.Start: |
| | | //开始 |
| | | SingleEntryHouseSkill.ReleaseSkill(this.house.Index, this.preHouseIndex, this.moveState); |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | break; |
| | | case KillMonsterStates.IsLastHouse: |
| | | //是否最后一个房间 |
| | | if (!imageIsChange) |
| | | { |
| | | this.moveState.StopMove(); |
| | | //图片没变,不用判断 |
| | | SetState(KillMonsterStates.FindRole, false); |
| | | break; |
| | | } |
| | | if (this.house.Index == 15) |
| | | { |
| | | SetState(KillMonsterStates.HasRewardWindow, false); |
| | | } |
| | | else |
| | | { |
| | | SetState(KillMonsterStates.IsOtherHouse, false); |
| | | } |
| | | break; |
| | | case KillMonsterStates.HasRewardWindow: |
| | | //是否有奖励界面 |
| | | if (DnfCVHelper.IsJiangli(image, this.GameRect)) |
| | | { |
| | | SetState(KillMonsterStates.TurnAroundCard, false); |
| | | } |
| | | else |
| | | { |
| | | SetState(KillMonsterStates.IsCompletePage, false); |
| | | } |
| | | break; |
| | | case KillMonsterStates.TurnAroundCard: |
| | | //翻牌 |
| | | Fanpai(); |
| | | Thread.Sleep(5000); |
| | | this.isSuccess = true; |
| | | SetState(KillMonsterStates.Exit, false); |
| | | break; |
| | | case KillMonsterStates.IsCompletePage: |
| | | //是否刷完界面 |
| | | if (DnfCVHelper.IsCompleteRoom(image, this.GameRect)) |
| | | { |
| | | this.isSuccess = true; |
| | | SetState(KillMonsterStates.Exit, false); |
| | | } |
| | | else |
| | | { |
| | | SetState(KillMonsterStates.FindRole, false); |
| | | } |
| | | break; |
| | | case KillMonsterStates.IsOtherHouse: |
| | | //是否进入其它房间 |
| | | if (HouseIsChange()) |
| | | { |
| | | this.isSuccess = true; |
| | | SetState(KillMonsterStates.Exit, false); |
| | | } |
| | | else |
| | | { |
| | | //是否需要截图 |
| | | SetState(KillMonsterStates.FindRole, false); |
| | | } |
| | | break; |
| | | case KillMonsterStates.FindRole: |
| | | //主角 |
| | | CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | |
| | | //定位点 |
| | | if (!DnfCVHelper.GetLocationPoint(out stateLocationRectangle, hsvImage, this.GameRect)) |
| | | { |
| | | //找不到定位点 |
| | | G.Instance.InfoWriter("找不到定位点"); |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | break; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | this.stateRolePosition = DnfCVHelper.FindRole(hsvImage, this.GameRect); |
| | | if (this.stateRolePosition == ZTPoint.Empty) |
| | | { |
| | | SetState(KillMonsterStates.FindRoleMove, false); |
| | | } |
| | | else |
| | | { |
| | | if (this.moveState.IsFindRoleMoving) |
| | | { |
| | | this.moveState.StopMove(); |
| | | } |
| | | SetState(KillMonsterStates.FindMonster, false); |
| | | } |
| | | break; |
| | | case KillMonsterStates.FindRoleMove: |
| | | //todo:让主角移动(原:有怪攻击一下,无怪移动一下) |
| | | FindRoleMove(); |
| | | break; |
| | | case KillMonsterStates.FindMonster: |
| | | //找怪 |
| | | this.stateMonsters = LindongCVHelper.FindMonster(hsvImage, this.GameRect); |
| | | |
| | | if (this.stateMonsters.Length > 0) |
| | | { |
| | | G.Instance.DebugWriter(string.Format("已找到{0}个怪", this.stateMonsters.Length)); |
| | | SetState(KillMonsterStates.CalcAttackDistance, false); |
| | | } |
| | | else |
| | | { |
| | | SetState(KillMonsterStates.PickupThing, false); |
| | | } |
| | | break; |
| | | case KillMonsterStates.PickupThing: |
| | | //拾取物品 |
| | | SetState(KillMonsterStates.FindDoor, false); |
| | | //todo: PickupThing(); |
| | | break; |
| | | case KillMonsterStates.FindDoor: |
| | | //查找门, 是否找到门 |
| | | FindDoor(); |
| | | break; |
| | | case KillMonsterStates.EntryDoor: |
| | | //向门移动, 进门 |
| | | EntryDoor(); |
| | | break; |
| | | case KillMonsterStates.FindDoorMove: |
| | | //todo:找门移动 |
| | | FindDoorMove(); |
| | | break; |
| | | case KillMonsterStates.CalcAttackDistance: |
| | | //判断使用何技能,计算攻击移动距离, 是否需要移动 |
| | | CalcAttackDistance(); |
| | | break; |
| | | case KillMonsterStates.ReleaseSkill: |
| | | //调整朝向, 释放技能, |
| | | ReleaseSkill(); |
| | | break; |
| | | case KillMonsterStates.AttackMove: |
| | | //todo:攻击移动 |
| | | AttackMove(); |
| | | break; |
| | | case KillMonsterStates.Exit: |
| | | //结束 |
| | | G.Instance.DebugWriter("退出状态"); |
| | | this.moveState.StopMove(); |
| | | if (this.isSuccess) |
| | | { |
| | | return ZTResult.Success; |
| | | } |
| | | } |
| | | return ZTResult.Failed; |
| | | |
| | | |
| | | } |
| | | |
| | | StateAction action = states[currentState]; |
| | | result =action(image, hsvImage); |
| | | if (refreshScreen) |
| | | { |
| | | image.Dispose(); |
| | | } |
| | | G.Instance.DebugWriter("next state:" + result.NextState.ToString()); |
| | | |
| | | G.Instance.DebugWriter("next state:" + currentState.ToString()); |
| | | } |
| | | } |
| | | |
| | | #region States |
| | | |
| | | private const byte STATE_FindMonster = 0;//找怪 |
| | | private const byte STATE_PrepareReleaseSkill = 1;//释放技能预处理,计算位置 |
| | | private const byte STATE_ReleaseSkill = 2;//释放技能 |
| | | private const byte STATE_DetectDoorIsOpen = 3;//查找进入下一房间的门是否开了 |
| | | private const byte STATE_MoveToDoor = 4;//移动进门 |
| | | |
| | | private const byte STATE_Start = 8;//开始状态 |
| | | private const byte STATE_Exit = 9;//完成状态 |
| | | |
| | | |
| | | #region States |
| | | /// <summary> |
| | | /// 初始化状态 |
| | | /// 让主角移动(原:有怪攻击一下,无怪移动一下) |
| | | /// </summary> |
| | | private void InitStates() |
| | | private void FindRoleMove() |
| | | { |
| | | //状态列表 |
| | | states = new StateAction[STATE_Exit+1]; |
| | | states[STATE_FindMonster] = FindMonster; |
| | | states[STATE_PrepareReleaseSkill] = PrepareReleaseSkill; |
| | | states[STATE_ReleaseSkill] = ReleaseSkill; |
| | | states[STATE_DetectDoorIsOpen] = DetectDoorIsOpen; |
| | | states[STATE_MoveToDoor] = MoveToDoor; |
| | | states[STATE_Start] = StartState; |
| | | } |
| | | this.moveState.FindRoleMove(); |
| | | SetState(KillMonsterStates.FindRole, true); |
| | | |
| | | |
| | | private KillMonsterStateResult StartState(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage) |
| | | { |
| | | SingleEntryHouseSkill.ReleaseSkill(this.house.Index, this.preHouseIndex,this.moveState); |
| | | return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 0.找怪 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="hsvImage"></param> |
| | | /// <returns></returns> |
| | | private KillMonsterStateResult FindMonster(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage) |
| | | { |
| | | #region coll |
| | | //while (true) |
| | | //if (this.stateMonsters.Length > 0) |
| | | //{ |
| | | // image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | // image = image.GetSubRect(new System.Drawing.Rectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1)); |
| | | // CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | // ZTPoint start=DnfCVHelper.FindRole(hsvImage, this.gameRect); |
| | | |
| | | // Int32 dur = RandomUtils.KeyPressDuration; |
| | | // G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false,HIDCode.LeftArrow); |
| | | // Thread.Sleep(dur); |
| | | // G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); |
| | | // Thread.Sleep(dur); |
| | | // G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, HIDCode.LeftArrow); |
| | | // Thread.Sleep(dur); |
| | | // G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); |
| | | |
| | | // image = ScreenCapture.Instance.CaptureScreenReturnImage(); |
| | | // image = image.GetSubRect(new System.Drawing.Rectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1)); |
| | | // CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | // ZTPoint end = DnfCVHelper.FindRole(hsvImage, this.gameRect); |
| | | // G.Instance.InfoWriter($"dur:{dur},start:{start},end{end},distance:{end.X - start.X}"); |
| | | // Thread.Sleep(2000); |
| | | |
| | | // this.moveState.StopMove(); |
| | | // G.Instance.DebugWriter("找不到角色,Send X"); |
| | | // G.Instance.InputControl.PressKey(1000, HIDCode.X); |
| | | // SetState(KillMonsterStates.FindMonster, true); |
| | | // return; |
| | | //} |
| | | #endregion |
| | | //怪 |
| | | this.stateMonsters = LindongCVHelper.FindMonster(hsvImage,this.gameRect); |
| | | //主角 |
| | | this.stateRolePosition = DnfCVHelper.FindRole(hsvImage, this.gameRect); |
| | | //定位点 |
| | | DnfCVHelper.GetLocationPoint(out stateLocationRectangle, hsvImage, this.gameRect); |
| | | //else |
| | | //{ |
| | | // this.moveState.FindRoleMove(); |
| | | // SetState(KillMonsterStates.IsLastHouse, true); |
| | | //} |
| | | } |
| | | |
| | | if (this.stateMonsters.Length > 0) |
| | | /// <summary> |
| | | /// 拾取物品 |
| | | /// </summary> |
| | | private void PickupThing() |
| | | { |
| | | //拾取物品,获取最近一个物品位置并步行过去 |
| | | ZTPoint thingItemPosition = GetNearlyThingItem(image, stateRolePosition); |
| | | if (thingItemPosition != ZTPoint.Empty) |
| | | { |
| | | G.Instance.DebugWriter(string.Format("已找到{0}个怪", this.stateMonsters.Length)); |
| | | //未找到主角 |
| | | if (stateRolePosition == ZTPoint.Empty) |
| | | if (this.moveState.IsMoving && !this.moveState.IsPickupMoving) |
| | | { |
| | | this.moveState.StopMove(); |
| | | G.Instance.DebugWriter("找不到角色,Send X"); |
| | | G.Instance.InputControl.PressKey(1000, HIDCode.X); |
| | | return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | } |
| | | |
| | | return new KillMonsterStateResult(STATE_PrepareReleaseSkill, false); |
| | | this.moveState.PickupMove(this.stateRolePosition, thingItemPosition); |
| | | //return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | } |
| | | |
| | | if (this.moveState.IsPickupMoving) |
| | | { |
| | | this.moveState.StopMove(); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查找门, 是否找到门 |
| | | /// </summary> |
| | | private void FindDoor() |
| | | { |
| | | //查找真实的门 |
| | | this.stateDoorPosition = LindongCVHelper.FindDoor(out stateDoorLevelDirect, hsvImage, this.house.DoorDirection, this.GameRect); |
| | | if (this.stateDoorPosition != ZTPoint.Empty) |
| | | { |
| | | //找到门,向门移动 |
| | | if (this.moveState.IsFindDoorMoving) |
| | | { |
| | | this.moveState.StopMove(); |
| | | } |
| | | G.Instance.InfoWriter("已找到门,位置:" + stateDoorPosition.ToString()); |
| | | SetState(KillMonsterStates.EntryDoor, false); |
| | | } |
| | | else |
| | | { |
| | | //未查找到主角 |
| | | |
| | | |
| | | if (stateRolePosition == ZTPoint.Empty) |
| | | { |
| | | if (this.moveState.IsMoving && !this.moveState.IsFindRoleMoving) |
| | | { |
| | | this.moveState.StopMove(); |
| | | } |
| | | |
| | | |
| | | //是否刷完 |
| | | if (IsComplete(image)) |
| | | { |
| | | return new KillMonsterStateResult(STATE_Exit, false); |
| | | } |
| | | |
| | | this.moveState.FindRoleMove(); |
| | | return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | } |
| | | return new KillMonsterStateResult(STATE_DetectDoorIsOpen, true); |
| | | //未找到门,循环移动 |
| | | SetState(KillMonsterStates.FindDoorMove, false); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 向门移动, 进门 |
| | | /// </summary> |
| | | private void EntryDoor() |
| | | { |
| | | const Int32 XLevelOffset = 200; |
| | | const Int32 YLevelOffset = 100; |
| | | Int32 limitLine = 0; |
| | | Int32 diff = 0; |
| | | //传过来人物坐标和门的坐标,根据门的朝向计算人物走向 |
| | | switch (stateDoorLevelDirect) |
| | | { |
| | | case Direction.Up: |
| | | //门在上方 |
| | | limitLine = stateDoorPosition.Y + YLevelOffset; |
| | | if (stateRolePosition.Y < limitLine) |
| | | { |
| | | //下移 |
| | | this.moveState.SyncMove(new ZTPoint(0, limitLine - stateRolePosition.Y)); |
| | | } |
| | | |
| | | //垂直对齐 |
| | | diff = stateDoorPosition.X - stateRolePosition.X; |
| | | this.moveState.SyncMove(new ZTPoint(diff, 0)); |
| | | |
| | | //移动y,进入 |
| | | this.moveState.SyncMove(new ZTPoint(0, this.GameRect.Start.Y - stateRolePosition.Y)); |
| | | break; |
| | | |
| | | case Direction.Right: |
| | | //门在右侧 |
| | | limitLine = stateDoorPosition.X - XLevelOffset; |
| | | if (stateRolePosition.X > limitLine) |
| | | { |
| | | //如果角色位于门右侧,先向左移 |
| | | this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0)); |
| | | } |
| | | |
| | | //水平对齐 |
| | | diff = stateDoorPosition.Y - stateRolePosition.Y; |
| | | this.moveState.SyncMove(new ZTPoint(0, diff)); |
| | | |
| | | //移动x,进入 |
| | | this.moveState.SyncMove(new ZTPoint(this.GameRect.End.X - stateRolePosition.X, 0)); |
| | | break; |
| | | |
| | | case Direction.Bottom: |
| | | //门在下方 |
| | | limitLine = stateDoorPosition.Y - YLevelOffset; |
| | | if (stateRolePosition.Y > limitLine) |
| | | { |
| | | //如果角色在门下方,先向上移 |
| | | this.moveState.SyncMove(new ZTPoint(0, limitLine - stateRolePosition.Y)); |
| | | } |
| | | |
| | | //垂直对齐 |
| | | diff = stateDoorPosition.X - stateRolePosition.X; |
| | | this.moveState.SyncMove(new ZTPoint(diff, 0)); |
| | | |
| | | //移动y,进入 |
| | | this.moveState.SyncMove(new ZTPoint(0, this.GameRect.End.Y - stateRolePosition.Y)); |
| | | break; |
| | | |
| | | case Direction.Left: |
| | | //门在左侧 |
| | | limitLine = stateDoorPosition.X + XLevelOffset; |
| | | if (stateRolePosition.X < limitLine) |
| | | { |
| | | //如果角色位于门左侧,先向右移 |
| | | this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0)); |
| | | } |
| | | |
| | | //水平对齐 |
| | | diff = stateDoorPosition.Y - stateRolePosition.Y; |
| | | this.moveState.SyncMove(new ZTPoint(0, diff)); |
| | | |
| | | //移动x,进入 |
| | | this.moveState.SyncMove(new ZTPoint(this.GameRect.Start.X - stateRolePosition.X, 0)); |
| | | break; |
| | | } |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | return; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 找门移动 |
| | | /// </summary> |
| | | private void FindDoorMove() |
| | | { |
| | | Int32 areaID = 0; |
| | | if (this.outOfBounds.InOutOfBound(this.house.Index, stateRolePosition, out areaID)) |
| | | { |
| | | this.outOfBounds.MoveToCommonBound(areaID); |
| | | } |
| | | else |
| | | { |
| | | this.moveState.FindDoorMove(stateRolePosition); |
| | | } |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | } |
| | | |
| | | |
| | | |
| | | private DateTime FindRoleLastNoMoveTime = DateTime.MaxValue;//最后没移动时间 |
| | | private bool FindRoleLastNoMoveStart = false;//没移动是否开始计时 |
| | | private ZTSize attackMoveDistance = ZTSize.Empty; |
| | | private HIDCode roleDirection = HIDCode.NoEvent; |
| | | /// <summary> |
| | | /// 1.释放技能预处理,计算位置 |
| | | /// 判断使用何技能,计算攻击移动距离, 是否需要移动 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="hsvImage"></param> |
| | | /// <returns></returns> |
| | | private KillMonsterStateResult PrepareReleaseSkill(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage) |
| | | private void CalcAttackDistance() |
| | | { |
| | | if (this.moveState.IsMoving&&!this.moveState.IsAttackMoving) |
| | | { |
| | | this.moveState.StopMove(); |
| | | } |
| | | SkillInfo skill = this.house.Skills.SyncPeek(); |
| | | |
| | | SkillInfo attackSkill = this.house.Skills.SyncPeek(); |
| | | |
| | | |
| | | //计算攻击移动距离 |
| | | HIDCode dir = HIDCode.RightArrow; |
| | | bool needMove = false; |
| | | ZTSize moveDistance = AttackRectangle.GetMoveDistance(this.gameRect, stateRolePosition, stateMonsters, skill, out dir, out needMove); |
| | | attackMoveDistance = AttackRectangle.GetMoveDistance(this.GameRect, stateRolePosition, stateMonsters, attackSkill, out roleDirection, out needMove); |
| | | if (!needMove) |
| | | { |
| | | this.roleLastPosition = ZTPoint.Empty; |
| | | //不需要移动 |
| | | if (dir != HIDCode.NoEvent) |
| | | { |
| | | G.Instance.InputControl.PressKey(100, dir); |
| | | } |
| | | this.moveState.StopMove(); |
| | | G.Instance.DebugWriter(string.Format("不需移动直接发技能,距离:{0}", moveDistance.ToString())); |
| | | return new KillMonsterStateResult(STATE_ReleaseSkill, false); |
| | | G.Instance.DebugWriter(string.Format("不需移动直接发技能,距离:{0}", attackMoveDistance.ToString())); |
| | | SetState(KillMonsterStates.ReleaseSkill, false); |
| | | } |
| | | else |
| | | { |
| | | SetState(KillMonsterStates.AttackMove, false); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 调整朝向, 释放技能 |
| | | /// </summary> |
| | | private void ReleaseSkill() |
| | | { |
| | | SkillInfo skill = this.house.Skills.SyncDeQueue(); |
| | | |
| | | |
| | | this.roleLastPosition = ZTPoint.Empty; |
| | | if (roleDirection != HIDCode.NoEvent) |
| | | { |
| | | G.Instance.InputControl.PressKey(100, roleDirection); |
| | | } |
| | | this.moveState.StopMove(); |
| | | |
| | | |
| | | |
| | | |
| | | if (skill.Key == HIDCode.X) |
| | | { |
| | | for (int i = 0; i < 5; i++) |
| | | { |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, skill.Key); |
| | | Thread.Sleep(200); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, skill.Key); |
| | | Thread.Sleep((Int32)skill.ReleaseTime); |
| | | } |
| | | |
| | | G.Instance.DebugWriter(string.Format("发完技能,技能按键:{0},技能名称:{1}", skill.Key, skill.SkillName)); |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 攻击移动 |
| | | /// </summary> |
| | | private void AttackMove() |
| | | { |
| | | SkillInfo attackSkill = this.house.Skills.SyncPeek(); |
| | | //没有移动,可能有障碍物 |
| | | if (stateRolePosition == this.roleLastPosition) |
| | | { |
| | |
| | | this.roleLastPosition = stateRolePosition; |
| | | FindRoleLastNoMoveStart = false; |
| | | } |
| | | |
| | | G.Instance.DebugWriter("attack move :"+moveDistance.ToString()+",role:"+stateRolePosition.ToString()+",monster1:"+stateMonsters[0].ToString()+",skill:"+skill.Key.ToString()); |
| | | this.moveState.AttackMove(moveDistance); |
| | | return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 2.释放技能 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="hsvImage"></param> |
| | | /// <returns></returns> |
| | | private KillMonsterStateResult ReleaseSkill(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage) |
| | | { |
| | | SkillInfo skill = this.house.Skills.SyncDeQueue(); |
| | | if (skill.Key == HIDCode.X) |
| | | { |
| | | for (int i = 0; i < 5; i++) |
| | | { |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, skill.Key); |
| | | Thread.Sleep(200); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, skill.Key); |
| | | Thread.Sleep((Int32)skill.ReleaseTime); |
| | | } |
| | | |
| | | G.Instance.DebugWriter(string.Format("发完技能,技能按键:{0},技能名称:{1}", skill.Key, skill.SkillName)); |
| | | return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 3.检测进入下一房间的门是否开了 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private KillMonsterStateResult DetectDoorIsOpen(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage) |
| | | { |
| | | if (this.moveState.IsAttackMoving|| this.moveState.IsFindRoleMoving) |
| | | { |
| | | this.moveState.StopMove(); |
| | | } |
| | | |
| | | ////查找当前房间编号,看是否进入其它房间 |
| | | //Int32 houseIndex; |
| | | //if (!LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart)) |
| | | //{ |
| | | if (IsComplete(image)) |
| | | { |
| | | return new KillMonsterStateResult(STATE_Exit, false); |
| | | } |
| | | |
| | | // G.Instance.DebugWriter("检测是否进入下一房间时,未发现小地图中有人物标记,id"+this.house.Index+",isend:"+this.house.IsEnd.ToString()); |
| | | // return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | //} |
| | | |
| | | //if (houseIndex != this.house.Index) |
| | | //{ |
| | | // //已进入其它房间 |
| | | // this.moveState.StopMove(); |
| | | // this.exitResult = true; |
| | | // return new KillMonsterStateResult(STATE_Exit, false); |
| | | //} |
| | | |
| | | ////拾取物品,获取最近一个物品位置并步行过去 |
| | | //ZTPoint thingItemPosition = GetNearlyThingItem(image, rolePosition); |
| | | //if (thingItemPosition != ZTPoint.Empty) |
| | | //{ |
| | | // if (this.moveState.IsMoving && !this.moveState.IsPickupMoving) |
| | | // { |
| | | // this.moveState.StopMove(); |
| | | // } |
| | | |
| | | // this.moveState.PickupMove(rolePosition, thingItemPosition); |
| | | // return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | //} |
| | | |
| | | //if (this.moveState.IsPickupMoving) |
| | | //{ |
| | | // this.moveState.StopMove(); |
| | | //} |
| | | |
| | | //查找真实的门 |
| | | ZTPoint doorPosition = LindongCVHelper.FindDoor(out stateDoorLevelDirect,hsvImage, this.house.DoorDirection,this.gameRect); |
| | | if (doorPosition != ZTPoint.Empty) |
| | | { |
| | | G.Instance.InfoWriter("door find:"+doorPosition.ToString()); |
| | | this.moveState.StopMove(); |
| | | this.stateDoorPosition = doorPosition; |
| | | |
| | | //找到门,向门移动 |
| | | return new KillMonsterStateResult(STATE_MoveToDoor, false); |
| | | } |
| | | else |
| | | { |
| | | //未找到门,循环移动 |
| | | Int32 areaID = 0; |
| | | if (this.outOfBounds.InOutOfBound(this.house.Index, stateRolePosition, out areaID)) |
| | | { |
| | | this.outOfBounds.MoveToCommonBound(areaID); |
| | | } |
| | | else |
| | | { |
| | | this.moveState.FindDoorMove(stateRolePosition); |
| | | } |
| | | } |
| | | |
| | | return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | } |
| | | |
| | | private const Int32 XDoorLevelOffset = 200; |
| | | private const Int32 YDoorLevelOffset = 100; |
| | | /// <summary> |
| | | /// 4.找门 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="hsvImage"></param> |
| | | /// <returns></returns> |
| | | private KillMonsterStateResult MoveToDoor(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage) |
| | | { |
| | | Int32 limitLine = 0; |
| | | Int32 diff = 0; |
| | | //传过来人物坐标和门的坐标,根据门的朝向计算人物走向 |
| | | switch (stateDoorLevelDirect) |
| | | { |
| | | case Direction.Up: |
| | | //门在上方 |
| | | limitLine = stateDoorPosition.Y + YDoorLevelOffset; |
| | | if (stateRolePosition.Y < limitLine) |
| | | { |
| | | //下移 |
| | | this.moveState.SyncMove(new ZTPoint(0, limitLine - stateRolePosition.Y)); |
| | | } |
| | | |
| | | //垂直对齐 |
| | | diff = stateDoorPosition.X - stateRolePosition.X; |
| | | this.moveState.SyncMove(new ZTPoint(diff, 0)); |
| | | |
| | | //移动y,进入 |
| | | this.moveState.SyncMove(new ZTPoint(0, this.gameRect.Start.Y - stateRolePosition.Y)); |
| | | break; |
| | | |
| | | case Direction.Right: |
| | | //门在右侧 |
| | | limitLine = stateDoorPosition.X - XDoorLevelOffset; |
| | | if (stateRolePosition.X > limitLine) |
| | | { |
| | | //如果角色位于门右侧,先向左移 |
| | | this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0)); |
| | | } |
| | | |
| | | //水平对齐 |
| | | diff = stateDoorPosition.Y - stateRolePosition.Y; |
| | | this.moveState.SyncMove(new ZTPoint(0, diff)); |
| | | |
| | | //移动x,进入 |
| | | this.moveState.SyncMove(new ZTPoint(this.gameRect.End.X - stateRolePosition.X, 0)); |
| | | break; |
| | | |
| | | case Direction.Bottom: |
| | | //门在下方 |
| | | limitLine = stateDoorPosition.Y - YDoorLevelOffset; |
| | | if (stateRolePosition.Y > limitLine) |
| | | { |
| | | //如果角色在门下方,先向上移 |
| | | this.moveState.SyncMove(new ZTPoint(0,limitLine- stateRolePosition.Y)); |
| | | } |
| | | |
| | | //垂直对齐 |
| | | diff = stateDoorPosition.X - stateRolePosition.X; |
| | | this.moveState.SyncMove(new ZTPoint(diff, 0)); |
| | | |
| | | //移动y,进入 |
| | | this.moveState.SyncMove(new ZTPoint(0, this.gameRect.End.Y - stateRolePosition.Y)); |
| | | break; |
| | | |
| | | case Direction.Left: |
| | | //门在左侧 |
| | | limitLine = stateDoorPosition.X + XDoorLevelOffset; |
| | | if (stateRolePosition.X < limitLine) |
| | | { |
| | | //如果角色位于门左侧,先向右移 |
| | | this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0)); |
| | | } |
| | | |
| | | //水平对齐 |
| | | diff = stateDoorPosition.Y - stateRolePosition.Y; |
| | | this.moveState.SyncMove(new ZTPoint(0, diff)); |
| | | |
| | | //移动x,进入 |
| | | this.moveState.SyncMove(new ZTPoint(this.gameRect.Start.X- stateRolePosition.X, 0)); |
| | | break; |
| | | } |
| | | |
| | | return new KillMonsterStateResult(STATE_DetectDoorIsOpen, true); |
| | | G.Instance.DebugWriter("attack move :" + attackMoveDistance.ToString() + ",role:" + stateRolePosition.ToString() + ",monster1:" + stateMonsters[0].ToString() + ",skill:" + attackSkill.Key.ToString()); |
| | | this.moveState.AttackMove(attackMoveDistance); |
| | | SetState(KillMonsterStates.FindRole, true); |
| | | } |
| | | #endregion |
| | | |
| | |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <returns></returns> |
| | | public ZTPoint GetNearlyThingItem(Image<Rgb, byte> image,ZTPoint rolePosition) |
| | | public ZTPoint GetNearlyThingItem(Image<Rgb, byte> image, ZTPoint rolePosition) |
| | | { |
| | | List<ZTPoint> points=DnfCVHelper.GetThingItemPoints(image, this.gameRect); |
| | | List<ZTPoint> points = DnfCVHelper.GetThingItemPoints(image, this.GameRect); |
| | | if (points.Count <= 0) |
| | | { |
| | | return ZTPoint.Empty; |
| | |
| | | { |
| | | return points[0]; |
| | | } |
| | | |
| | | |
| | | double distance = 0; |
| | | ZTPoint result = ZTPoint.Empty; |
| | | for (int i = 0; i < points.Count; i++) |
| | |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否完成 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <returns></returns> |
| | | public bool IsComplete(Image<Rgb,byte> image) |
| | | { |
| | | if (this.house.IsEnd) |
| | | { |
| | | |
| | | if (DnfCVHelper.IsJiangli(image, this.gameRect)) |
| | | { |
| | | //翻牌 |
| | | this.moveState.StopMove(); |
| | | Fanpai(); |
| | | Thread.Sleep(5000); |
| | | this.exitResult = true; |
| | | return true; |
| | | } |
| | | |
| | | if (DnfCVHelper.IsCompleteRoom(image, this.gameRect)) |
| | | { |
| | | //已经刷完 |
| | | this.moveState.StopMove(); |
| | | this.exitResult = true; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | #region 翻牌 |
| | | |
| | | |
| | | /// <summary> |
| | | /// 牌的位置 |
| | | /// </summary> |
| | |
| | | { |
| | | Thread.Sleep(2000); |
| | | Int32 number = RandomUtils.G(1, 4); |
| | | ZTPoint willPosition = this.gameRect.Start.Add(CardList[number - 1]); |
| | | G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition,10)); |
| | | ZTPoint willPosition = this.GameRect.Start.Add(CardList[number - 1]); |
| | | G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition, 10)); |
| | | |
| | | //判断黄金版是否可以翻 |
| | | if (DnfCVHelper.HasMowangqiyueCard(this.gameRect)) |
| | | if (DnfCVHelper.HasMowangqiyueCard(this.GameRect)) |
| | | { |
| | | number = RandomUtils.G(5, 8); |
| | | willPosition = this.gameRect.Start.Add(CardList[number - 1]); |
| | | willPosition = this.GameRect.Start.Add(CardList[number - 1]); |
| | | G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition, 10)); |
| | | } |
| | | |
| | | } |
| | | #endregion |
| | | |
| | | |
| | | /// <summary> |
| | | /// 是否改变房间 |
| | | /// </summary> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | private bool HouseIsChange() |
| | | { |
| | | Int32 houseIndex; |
| | | if (!LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart)) |
| | | { |
| | | //得不到房间 |
| | | if (!FuncUtils.TimeoutCancelableWrap(30 * 1000, cancellationToken, () => |
| | | { |
| | | using (bitmap = ScreenCapture.Instance.CaptureScreen()) |
| | | { |
| | | image = new Image<Rgb, byte>(bitmap); |
| | | image = image.GetSubRect(new System.Drawing.Rectangle(GameRect.Start.X, GameRect.Start.Y, GameRect.End.X - GameRect.Start.X + 1, GameRect.End.Y - GameRect.Start.Y + 1)); |
| | | return LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart); |
| | | } |
| | | }, 50)) |
| | | { |
| | | throw new Exception("找不到默认房间"); |
| | | } |
| | | } |
| | | if (houseIndex != this.house.Index) |
| | | { |
| | | this.moveState.StopMove(); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 杀怪状态 |
| | | /// </summary> |
| | | public enum KillMonsterStates:Int32 |
| | | public enum KillMonsterStates : Int32 |
| | | { |
| | | FindMonster = 0,//找怪 |
| | | PrepareReleaseSkill = 1,//释放技能预处理,计算位置 |
| | | ReleaseSkill = 2,//释放技能 |
| | | DetectDoorIsOpen = 3,//查找进入下一房间的门是否开了 |
| | | MoveToDoor = 4,//移动进门 |
| | | |
| | | Start = 8,//开始状态 |
| | | Exit = 9,//完成状态 |
| | | } |
| | | Start,//开始状态 |
| | | Exit,//完成状态 |
| | | IsLastHouse,//是否最后一个房间 |
| | | HasRewardWindow,//是否有奖励界面 |
| | | TurnAroundCard,//翻牌 |
| | | IsCompletePage,//是否刷完界面 |
| | | IsOtherHouse,//是否进入其它房间 |
| | | FindRole,//找主角 |
| | | FindRoleMove,//让主角移动(原:有怪攻击一下,无怪移动一下) |
| | | FindMonster,//找怪 |
| | | PickupThing,//拾取物品 |
| | | FindDoor,//查找门, 是否找到门 |
| | | EntryDoor,//向门移动, 进门 |
| | | FindDoorMove,//找门移动 |
| | | CalcAttackDistance,//判断使用何技能,计算攻击移动距离, 是否需要移动 |
| | | ReleaseSkill,//调整朝向, 释放技能, |
| | | AttackMove,//攻击移动 |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | using RichCreator.Utility; |
| | | using RichCreator.Utility.Captures; |
| | | using RichCreator.Utility.CV; |
| | | using RichCreator.Utility.InputControl; |
| | | using RichCreator.Utility.Structs; |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | using RichCreator.Maps; |
| | | using RichCreator.Maps.Lindong; |
| | | using RichCreator.StateMachines; |
| | | using RichCreator.Utilitys; |
| | | using static RichCreator.Utilitys.AttackRectangle; |
| | | using Utils= RichCreator.Utilitys.Utils; |
| | | using ZTImage.Collections; |
| | | |
| | | namespace RichCreator.Jobs.StateMachines |
| | | { |
| | | /// <summary> |
| | | /// 杀怪状态机 |
| | | /// </summary> |
| | | public class KillMonsterStateMachine_old:StateMachineBase |
| | | { |
| | | private const Int32 NoMoveMaxMillSecond = 2000;//最大未移动容忍毫秒数 |
| | | |
| | | private HouseInfo house;//当前房间 |
| | | private ZTPoint miniMapStart;//小地图区域 |
| | | private ZTRectangle gameRect;//游戏区域 |
| | | private Int32 preHouseIndex = 0;//上一房间编号 |
| | | private MoveState moveState;//移动状态 |
| | | private OutOfBounds outOfBounds;//禁区 |
| | | private bool isSuccess;//退出结果 |
| | | |
| | | |
| | | private ZTPoint roleLastPosition=ZTPoint.Empty;//角色最后位置 |
| | | private Int32 runningStep = RunningStep.None;//是否恢复的状态 |
| | | |
| | | //当前状态 |
| | | private KillMonsterStates currentState = KillMonsterStates.Start; |
| | | //是否截图屏幕 |
| | | private bool captureScreen = false; |
| | | |
| | | |
| | | #region Find Door Info |
| | | //门坐标 |
| | | private ZTPoint stateDoorPosition; |
| | | //角色位置 |
| | | private ZTPoint stateRolePosition; |
| | | //离开的门朝向 |
| | | private Direction stateDoorLevelDirect = Direction.None; |
| | | //定位点方框 |
| | | private MultiList<ZTRectangle, Int32> stateLocationRectangle = new MultiList<ZTRectangle, int>(); |
| | | //怪 |
| | | private ZTPoint[] stateMonsters; |
| | | |
| | | private System.Drawing.Bitmap bitmap = null; |
| | | //原图 |
| | | private Image<Rgb, byte> image = null; |
| | | //色彩hsv |
| | | private Image<Hsv, byte> hsvImage = null; |
| | | #endregion |
| | | |
| | | |
| | | public KillMonsterStateMachine(HouseInfo house, ZTPoint miniMapStart, ZTRectangle gameRect,Int32 preHouseIndex,Int32 runningStep) |
| | | { |
| | | this.runningStep = runningStep; |
| | | this.house = house; |
| | | this.miniMapStart = miniMapStart; |
| | | this.gameRect = gameRect; |
| | | this.preHouseIndex = preHouseIndex; |
| | | moveState = new MoveState(this.gameRect, this.house); |
| | | outOfBounds = new OutOfBounds(this.gameRect,moveState); |
| | | hsvImage = new Image<Hsv, byte>(gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1); |
| | | } |
| | | |
| | | |
| | | |
| | | private void SetState(KillMonsterStates current, bool capture) |
| | | { |
| | | currentState = current; |
| | | captureScreen = capture; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 状态机开始 |
| | | /// </summary> |
| | | /// <param name="gameRect"></param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <param name="timeoutMillSecond"></param> |
| | | /// <returns></returns> |
| | | public ZTResult Work(CancellationToken cancellationToken, Int32 timeoutMillSecond) |
| | | { |
| | | DateTime expireTime = DateTime.Now.AddMilliseconds(timeoutMillSecond); |
| | | if (this.runningStep > RunningStep.None) |
| | | { |
| | | SetState(KillMonsterStates.FindMonster, true); |
| | | } |
| | | |
| | | |
| | | while (true) |
| | | { |
| | | if (cancellationToken.IsCancellationRequested) |
| | | { |
| | | G.Instance.DebugWriter("取消刷图"); |
| | | this.moveState.StopMove(); |
| | | return ZTResult.Cancel; |
| | | } |
| | | |
| | | if (DateTime.Now > expireTime) |
| | | { |
| | | G.Instance.DebugWriter("刷图超时"); |
| | | this.moveState.StopMove(); |
| | | return ZTResult.Timeout; |
| | | } |
| | | |
| | | if (captureScreen) |
| | | { |
| | | using (bitmap = ScreenCapture.Instance.CaptureScreen()) |
| | | { |
| | | image = new Image<Rgb, byte>(bitmap); |
| | | image = image.GetSubRect(new System.Drawing.Rectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1)); |
| | | } |
| | | |
| | | if (this.house.Index != 15) |
| | | { |
| | | //计算是否进入其它房间 |
| | | if (HouseIsChange(cancellationToken)) |
| | | { |
| | | return ZTResult.Success; |
| | | } |
| | | } |
| | | } |
| | | |
| | | bool lastCaptureScreen = this.captureScreen; |
| | | switch (currentState) |
| | | { |
| | | case KillMonsterStates.Start: |
| | | StartState(); |
| | | //开始 |
| | | break; |
| | | case KillMonsterStates.FindMonster: |
| | | //找怪 |
| | | CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | FindMonster(image, hsvImage); |
| | | break; |
| | | case KillMonsterStates.DetectDoorIsOpen: |
| | | //查找进入下一房间的门是否开了 |
| | | CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | DetectDoorIsOpen(image, hsvImage); |
| | | break; |
| | | case KillMonsterStates.MoveToDoor: |
| | | //移动进门 |
| | | MoveToDoor(); |
| | | break; |
| | | case KillMonsterStates.PrepareReleaseSkill: |
| | | //释放技能预处理,计算位置 |
| | | PrepareReleaseSkill(); |
| | | break; |
| | | case KillMonsterStates.ReleaseSkill: |
| | | //释放技能 |
| | | ReleaseSkill(); |
| | | break; |
| | | case KillMonsterStates.Exit: |
| | | //结束 |
| | | G.Instance.DebugWriter("退出状态"); |
| | | this.moveState.StopMove(); |
| | | if (this.isSuccess) |
| | | { |
| | | return ZTResult.Success; |
| | | } |
| | | return ZTResult.Failed; |
| | | } |
| | | |
| | | if (lastCaptureScreen) |
| | | { |
| | | image.Dispose(); |
| | | } |
| | | G.Instance.DebugWriter("next state:" + currentState.ToString()); |
| | | } |
| | | } |
| | | |
| | | #region States |
| | | private void StartState() |
| | | { |
| | | SingleEntryHouseSkill.ReleaseSkill(this.house.Index, this.preHouseIndex,this.moveState); |
| | | SetState(KillMonsterStates.FindMonster, true); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 0.找怪 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <param name="hsvImage"></param> |
| | | /// <returns></returns> |
| | | private void FindMonster(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage) |
| | | { |
| | | //怪 |
| | | this.stateMonsters = LindongCVHelper.FindMonster(hsvImage,this.gameRect); |
| | | //主角 |
| | | this.stateRolePosition = DnfCVHelper.FindRole(hsvImage, this.gameRect); |
| | | //定位点 |
| | | DnfCVHelper.GetLocationPoint(out stateLocationRectangle, hsvImage, this.gameRect); |
| | | |
| | | if (this.stateMonsters.Length > 0) |
| | | { |
| | | G.Instance.DebugWriter(string.Format("已找到{0}个怪", this.stateMonsters.Length)); |
| | | //未找到主角 |
| | | if (stateRolePosition == ZTPoint.Empty) |
| | | { |
| | | this.moveState.StopMove(); |
| | | G.Instance.DebugWriter("找不到角色,Send X"); |
| | | G.Instance.InputControl.PressKey(1000, HIDCode.X); |
| | | SetState(KillMonsterStates.FindMonster, true); |
| | | return; |
| | | } |
| | | |
| | | SetState(KillMonsterStates.PrepareReleaseSkill, false); |
| | | return; |
| | | } |
| | | else |
| | | { |
| | | //未查找到主角 |
| | | |
| | | if (stateRolePosition == ZTPoint.Empty) |
| | | { |
| | | if (this.moveState.IsMoving && !this.moveState.IsFindRoleMoving) |
| | | { |
| | | this.moveState.StopMove(); |
| | | } |
| | | |
| | | |
| | | //是否刷完 |
| | | if (IsComplete(image)) |
| | | { |
| | | SetState(KillMonsterStates.Exit, false); |
| | | return; |
| | | } |
| | | |
| | | this.moveState.FindRoleMove(); |
| | | SetState(KillMonsterStates.FindMonster, true); |
| | | return; |
| | | } |
| | | SetState(KillMonsterStates.DetectDoorIsOpen, true); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | private DateTime FindRoleLastNoMoveTime = DateTime.MaxValue;//最后没移动时间 |
| | | private bool FindRoleLastNoMoveStart = false;//没移动是否开始计时 |
| | | /// <summary> |
| | | /// 1.释放技能预处理,计算位置 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private void PrepareReleaseSkill() |
| | | { |
| | | if (this.moveState.IsMoving&&!this.moveState.IsAttackMoving) |
| | | { |
| | | this.moveState.StopMove(); |
| | | } |
| | | SkillInfo skill = this.house.Skills.SyncPeek(); |
| | | |
| | | |
| | | //计算攻击移动距离 |
| | | HIDCode dir = HIDCode.RightArrow; |
| | | bool needMove = false; |
| | | ZTSize moveDistance = AttackRectangle.GetMoveDistance(this.gameRect, stateRolePosition, stateMonsters, skill, out dir, out needMove); |
| | | if (!needMove) |
| | | { |
| | | this.roleLastPosition = ZTPoint.Empty; |
| | | //不需要移动 |
| | | if (dir != HIDCode.NoEvent) |
| | | { |
| | | G.Instance.InputControl.PressKey(100, dir); |
| | | } |
| | | this.moveState.StopMove(); |
| | | G.Instance.DebugWriter(string.Format("不需移动直接发技能,距离:{0}", moveDistance.ToString())); |
| | | SetState(KillMonsterStates.ReleaseSkill, false); |
| | | return; |
| | | } |
| | | |
| | | //没有移动,可能有障碍物 |
| | | if (stateRolePosition == this.roleLastPosition) |
| | | { |
| | | if (FindRoleLastNoMoveStart && (DateTime.Now - FindRoleLastNoMoveTime).TotalMilliseconds > NoMoveMaxMillSecond) |
| | | { |
| | | //开始计时 并且 超过最大未移动容忍时间 |
| | | G.Instance.DebugWriter("find role no mvoe:" + stateRolePosition.ToString()); |
| | | this.moveState.StopMove(); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.X); |
| | | FindRoleLastNoMoveTime = DateTime.Now; |
| | | } |
| | | else if (!FindRoleLastNoMoveStart) |
| | | { |
| | | //没开始计时 则 开始计时 |
| | | FindRoleLastNoMoveStart = true; |
| | | FindRoleLastNoMoveTime = DateTime.Now; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | //移动了 取消计时 |
| | | this.roleLastPosition = stateRolePosition; |
| | | FindRoleLastNoMoveStart = false; |
| | | } |
| | | |
| | | G.Instance.DebugWriter("attack move :"+moveDistance.ToString()+",role:"+stateRolePosition.ToString()+",monster1:"+stateMonsters[0].ToString()+",skill:"+skill.Key.ToString()); |
| | | this.moveState.AttackMove(moveDistance); |
| | | SetState(KillMonsterStates.FindMonster, true); |
| | | return; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 2.释放技能 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private void ReleaseSkill() |
| | | { |
| | | SkillInfo skill = this.house.Skills.SyncDeQueue(); |
| | | if (skill.Key == HIDCode.X) |
| | | { |
| | | for (int i = 0; i < 5; i++) |
| | | { |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, skill.Key); |
| | | Thread.Sleep(200); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, skill.Key); |
| | | Thread.Sleep((Int32)skill.ReleaseTime); |
| | | } |
| | | |
| | | G.Instance.DebugWriter(string.Format("发完技能,技能按键:{0},技能名称:{1}", skill.Key, skill.SkillName)); |
| | | SetState(KillMonsterStates.FindMonster, true); |
| | | |
| | | return; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 3.检测进入下一房间的门是否开了 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private void DetectDoorIsOpen(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage) |
| | | { |
| | | if (this.moveState.IsAttackMoving|| this.moveState.IsFindRoleMoving) |
| | | { |
| | | this.moveState.StopMove(); |
| | | } |
| | | |
| | | ////查找当前房间编号,看是否进入其它房间 |
| | | //Int32 houseIndex; |
| | | //if (!LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart)) |
| | | //{ |
| | | if (IsComplete(image)) |
| | | { |
| | | SetState(KillMonsterStates.Exit, false); |
| | | return; |
| | | } |
| | | |
| | | // G.Instance.DebugWriter("检测是否进入下一房间时,未发现小地图中有人物标记,id"+this.house.Index+",isend:"+this.house.IsEnd.ToString()); |
| | | // return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | //} |
| | | |
| | | //if (houseIndex != this.house.Index) |
| | | //{ |
| | | // //已进入其它房间 |
| | | // this.moveState.StopMove(); |
| | | // this.exitResult = true; |
| | | // return new KillMonsterStateResult(STATE_Exit, false); |
| | | //} |
| | | |
| | | ////拾取物品,获取最近一个物品位置并步行过去 |
| | | //ZTPoint thingItemPosition = GetNearlyThingItem(image, rolePosition); |
| | | //if (thingItemPosition != ZTPoint.Empty) |
| | | //{ |
| | | // if (this.moveState.IsMoving && !this.moveState.IsPickupMoving) |
| | | // { |
| | | // this.moveState.StopMove(); |
| | | // } |
| | | |
| | | // this.moveState.PickupMove(rolePosition, thingItemPosition); |
| | | // return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | //} |
| | | |
| | | //if (this.moveState.IsPickupMoving) |
| | | //{ |
| | | // this.moveState.StopMove(); |
| | | //} |
| | | |
| | | //查找真实的门 |
| | | ZTPoint doorPosition = LindongCVHelper.FindDoor(out stateDoorLevelDirect,hsvImage, this.house.DoorDirection,this.gameRect); |
| | | if (doorPosition != ZTPoint.Empty) |
| | | { |
| | | G.Instance.InfoWriter("door find:"+doorPosition.ToString()); |
| | | this.moveState.StopMove(); |
| | | this.stateDoorPosition = doorPosition; |
| | | |
| | | //找到门,向门移动 |
| | | SetState(KillMonsterStates.MoveToDoor, false); |
| | | return; |
| | | } |
| | | else |
| | | { |
| | | //未找到门,循环移动 |
| | | Int32 areaID = 0; |
| | | if (this.outOfBounds.InOutOfBound(this.house.Index, stateRolePosition, out areaID)) |
| | | { |
| | | this.outOfBounds.MoveToCommonBound(areaID); |
| | | } |
| | | else |
| | | { |
| | | this.moveState.FindDoorMove(stateRolePosition); |
| | | } |
| | | } |
| | | SetState(KillMonsterStates.FindMonster, true); |
| | | return; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 4.找门 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | private void MoveToDoor() |
| | | { |
| | | const Int32 XLevelOffset = 200; |
| | | const Int32 YLevelOffset = 100; |
| | | Int32 limitLine = 0; |
| | | Int32 diff = 0; |
| | | //传过来人物坐标和门的坐标,根据门的朝向计算人物走向 |
| | | switch (stateDoorLevelDirect) |
| | | { |
| | | case Direction.Up: |
| | | //门在上方 |
| | | limitLine = stateDoorPosition.Y + YLevelOffset; |
| | | if (stateRolePosition.Y < limitLine) |
| | | { |
| | | //下移 |
| | | this.moveState.SyncMove(new ZTPoint(0, limitLine - stateRolePosition.Y)); |
| | | } |
| | | |
| | | //垂直对齐 |
| | | diff = stateDoorPosition.X - stateRolePosition.X; |
| | | this.moveState.SyncMove(new ZTPoint(diff, 0)); |
| | | |
| | | //移动y,进入 |
| | | this.moveState.SyncMove(new ZTPoint(0, this.gameRect.Start.Y - stateRolePosition.Y)); |
| | | break; |
| | | |
| | | case Direction.Right: |
| | | //门在右侧 |
| | | limitLine = stateDoorPosition.X - XLevelOffset; |
| | | if (stateRolePosition.X > limitLine) |
| | | { |
| | | //如果角色位于门右侧,先向左移 |
| | | this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0)); |
| | | } |
| | | |
| | | //水平对齐 |
| | | diff = stateDoorPosition.Y - stateRolePosition.Y; |
| | | this.moveState.SyncMove(new ZTPoint(0, diff)); |
| | | |
| | | //移动x,进入 |
| | | this.moveState.SyncMove(new ZTPoint(this.gameRect.End.X - stateRolePosition.X, 0)); |
| | | break; |
| | | |
| | | case Direction.Bottom: |
| | | //门在下方 |
| | | limitLine = stateDoorPosition.Y - YLevelOffset; |
| | | if (stateRolePosition.Y > limitLine) |
| | | { |
| | | //如果角色在门下方,先向上移 |
| | | this.moveState.SyncMove(new ZTPoint(0,limitLine- stateRolePosition.Y)); |
| | | } |
| | | |
| | | //垂直对齐 |
| | | diff = stateDoorPosition.X - stateRolePosition.X; |
| | | this.moveState.SyncMove(new ZTPoint(diff, 0)); |
| | | |
| | | //移动y,进入 |
| | | this.moveState.SyncMove(new ZTPoint(0, this.gameRect.End.Y - stateRolePosition.Y)); |
| | | break; |
| | | |
| | | case Direction.Left: |
| | | //门在左侧 |
| | | limitLine = stateDoorPosition.X + XLevelOffset; |
| | | if (stateRolePosition.X < limitLine) |
| | | { |
| | | //如果角色位于门左侧,先向右移 |
| | | this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0)); |
| | | } |
| | | |
| | | //水平对齐 |
| | | diff = stateDoorPosition.Y - stateRolePosition.Y; |
| | | this.moveState.SyncMove(new ZTPoint(0, diff)); |
| | | |
| | | //移动x,进入 |
| | | this.moveState.SyncMove(new ZTPoint(this.gameRect.Start.X- stateRolePosition.X, 0)); |
| | | break; |
| | | } |
| | | SetState(KillMonsterStates.DetectDoorIsOpen, true); |
| | | return; |
| | | } |
| | | #endregion |
| | | |
| | | /// <summary> |
| | | /// 得到最近的物品 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <returns></returns> |
| | | public ZTPoint GetNearlyThingItem(Image<Rgb, byte> image,ZTPoint rolePosition) |
| | | { |
| | | List<ZTPoint> points=DnfCVHelper.GetThingItemPoints(image, this.gameRect); |
| | | if (points.Count <= 0) |
| | | { |
| | | return ZTPoint.Empty; |
| | | } |
| | | |
| | | if (points.Count == 1) |
| | | { |
| | | return points[0]; |
| | | } |
| | | |
| | | double distance = 0; |
| | | ZTPoint result = ZTPoint.Empty; |
| | | for (int i = 0; i < points.Count; i++) |
| | | { |
| | | double temp = ZTImage.Utils.GetDistance(rolePosition.X, rolePosition.Y, points[i].X, points[i].Y); |
| | | if (i == 0) |
| | | { |
| | | distance = temp; |
| | | result = points[0]; |
| | | continue; |
| | | } |
| | | |
| | | if (temp < distance) |
| | | { |
| | | distance = temp; |
| | | result = points[i]; |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否完成 |
| | | /// </summary> |
| | | /// <param name="image"></param> |
| | | /// <returns></returns> |
| | | public bool IsComplete(Image<Rgb,byte> image) |
| | | { |
| | | if (this.house.IsEnd) |
| | | { |
| | | |
| | | if (DnfCVHelper.IsJiangli(image, this.gameRect)) |
| | | { |
| | | //翻牌 |
| | | this.moveState.StopMove(); |
| | | Fanpai(); |
| | | Thread.Sleep(5000); |
| | | this.isSuccess = true; |
| | | return true; |
| | | } |
| | | |
| | | if (DnfCVHelper.IsCompleteRoom(image, this.gameRect)) |
| | | { |
| | | //已经刷完 |
| | | this.moveState.StopMove(); |
| | | this.isSuccess = true; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | #region 翻牌 |
| | | /// <summary> |
| | | /// 牌的位置 |
| | | /// </summary> |
| | | private static readonly ZTPoint[] CardList = new ZTPoint[] { |
| | | new ZTPoint(364,231), |
| | | new ZTPoint(561,231), |
| | | new ZTPoint(744,231), |
| | | new ZTPoint(924,231), |
| | | |
| | | |
| | | new ZTPoint(364,570), |
| | | new ZTPoint(561,570), |
| | | new ZTPoint(744,570), |
| | | new ZTPoint(924,570), |
| | | |
| | | }; |
| | | /// <summary> |
| | | /// 翻牌 |
| | | /// 1-4 |
| | | /// 5-8 |
| | | /// </summary> |
| | | /// <param name="number"></param> |
| | | private void Fanpai() |
| | | { |
| | | Thread.Sleep(2000); |
| | | Int32 number = RandomUtils.G(1, 4); |
| | | ZTPoint willPosition = this.gameRect.Start.Add(CardList[number - 1]); |
| | | G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition,10)); |
| | | |
| | | //判断黄金版是否可以翻 |
| | | if (DnfCVHelper.HasMowangqiyueCard(this.gameRect)) |
| | | { |
| | | number = RandomUtils.G(5, 8); |
| | | willPosition = this.gameRect.Start.Add(CardList[number - 1]); |
| | | G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition, 10)); |
| | | } |
| | | |
| | | } |
| | | #endregion |
| | | |
| | | /// <summary> |
| | | /// 是否改变房间 |
| | | /// </summary> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | private bool HouseIsChange(CancellationToken cancellationToken) |
| | | { |
| | | Int32 houseIndex; |
| | | if (!LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart)) |
| | | { |
| | | //得不到房间 |
| | | if (!FuncUtils.TimeoutCancelableWrap(30 * 1000, cancellationToken, () => { |
| | | using (bitmap = ScreenCapture.Instance.CaptureScreen()) |
| | | { |
| | | image = new Image<Rgb, byte>(bitmap); |
| | | image = image.GetSubRect(new System.Drawing.Rectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1)); |
| | | return LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart); |
| | | } |
| | | }, 50)) |
| | | { |
| | | throw new Exception("找不到默认房间"); |
| | | } |
| | | } |
| | | if (houseIndex != this.house.Index) |
| | | { |
| | | this.moveState.StopMove(); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 杀怪状态 |
| | | /// </summary> |
| | | public enum KillMonsterStates:Int32 |
| | | { |
| | | FindMonster = 0,//找怪 |
| | | PrepareReleaseSkill = 1,//释放技能预处理,计算位置 |
| | | ReleaseSkill = 2,//释放技能 |
| | | DetectDoorIsOpen = 3,//查找进入下一房间的门是否开了 |
| | | MoveToDoor = 4,//移动进门 |
| | | |
| | | Start = 8,//开始状态 |
| | | Exit = 9,//完成状态 |
| | | } |
| | | } |
| | | } |
| | |
| | | private const Int32 PaddingLeft = 140;//左边框内边距 |
| | | private const Int32 PaddingRight = 140;//右边框内边距 |
| | | |
| | | public MoveState(ZTRectangle gameRect, MapHouse house) |
| | | public MoveState(ZTRectangle gameRect, HouseInfo house) |
| | | { |
| | | this.gameRect = gameRect; |
| | | this.house = house; |
| | |
| | | private Int32 maxCenterLineY; |
| | | private Int32 centerLineErrorRange = 35;//中间性可允许的误差 |
| | | |
| | | private MapHouse house; |
| | | private HouseInfo house; |
| | | private ZTRectangle gameRect = ZTRectangle.Empty; |
| | | |
| | | private HIDCode moveKey = HIDCode.NoEvent; |
| | | private MoveIntent movingIntent = MoveIntent.ToAttack;//移动意图 |
| | | private MoveIntent movingIntent = MoveIntent.AttackMove;//移动意图 |
| | | private MoveMethod movingMethod= MoveMethod.Vertical;//移动方式,默认垂直移动 |
| | | private ZTSize movingDistance;//移动距离 |
| | | |
| | |
| | | public enum MoveIntent |
| | | { |
| | | None,//没移动 |
| | | ToAttack,//去攻击 |
| | | ToFindDoor,//去找门 |
| | | ToFindRole,//找主角 |
| | | ToPickup//去拾取 |
| | | AttackMove,//去攻击 |
| | | FindDoorMove,//去找门 |
| | | FindRoleMove,//找主角 |
| | | PickupMove//去拾取 |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | { |
| | | get |
| | | { |
| | | if (IsMoving && movingIntent == MoveIntent.ToAttack) |
| | | if (IsMoving && movingIntent == MoveIntent.AttackMove) |
| | | { |
| | | return true; |
| | | } |
| | |
| | | { |
| | | get |
| | | { |
| | | if (IsMoving && movingIntent == MoveIntent.ToFindDoor) |
| | | if (IsMoving && movingIntent == MoveIntent.FindDoorMove) |
| | | { |
| | | return true; |
| | | } |
| | |
| | | { |
| | | get |
| | | { |
| | | if (IsMoving && movingIntent == MoveIntent.ToFindRole) |
| | | if (IsMoving && movingIntent == MoveIntent.FindRoleMove) |
| | | { |
| | | return true; |
| | | } |
| | |
| | | { |
| | | get |
| | | { |
| | | if (IsMoving && movingIntent == MoveIntent.ToPickup) |
| | | if (IsMoving && movingIntent == MoveIntent.PickupMove) |
| | | { |
| | | return true; |
| | | } |
| | |
| | | public void AttackMove(ZTSize moveDistance) |
| | | { |
| | | PutKey(moveDistance); |
| | | movingIntent = MoveIntent.ToAttack; |
| | | movingIntent = MoveIntent.AttackMove; |
| | | } |
| | | |
| | | private Int32 RandomDirRun = 0;//随机行走的方向 |
| | | private const Int32 FindRoleMaxDelayMillSecond = 1000;//找角色开始移动最大延迟 |
| | | private DateTime FindRoleMoveTimeout = DateTime.MinValue;//方向移动过期时间 |
| | | private DateTime FindRoleStartTimeout = DateTime.MinValue;//开始查找主角移动过期时间 |
| | | /// <summary> |
| | |
| | | /// <param name="moveDistance"></param> |
| | | public void FindRoleMove() |
| | | { |
| | | if (IsMoving && !IsFindRoleMoving) |
| | | { |
| | | StopMove(); |
| | | } |
| | | const Int32 FindRoleMaxDelayMillSecond = 1000;//找角色开始移动最大延迟 |
| | | bool recomputationTimeoutTime = false; |
| | | //延迟开始找角色 |
| | | if (!IsMoving) |
| | |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, dirKey); |
| | | moveKey = dirKey; |
| | | } |
| | | movingIntent = MoveIntent.ToFindRole; |
| | | movingIntent = MoveIntent.FindRoleMove; |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 拾起物品移动 |
| | | /// </summary> |
| | |
| | | |
| | | //G.Instance.DebugWriter("pickup distance:" + moveDistance.ToString()); |
| | | PutKey(moveDistance); |
| | | movingIntent = MoveIntent.ToPickup; |
| | | movingIntent = MoveIntent.PickupMove; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 找门找怪移动 |
| | | /// 找门移动 |
| | | /// </summary> |
| | | /// <param name="rolePosition"></param> |
| | | public void FindDoorMove(ZTPoint rolePosition) |
| | |
| | | } |
| | | |
| | | PutKey(movingDistance); |
| | | movingIntent = MoveIntent.ToFindDoor; |
| | | movingIntent = MoveIntent.FindDoorMove; |
| | | } |
| | | |
| | | |
| | |
| | | <NotificationWechat>true</NotificationWechat> |
| | | <UserName1>1258493488</UserName1> |
| | | <Password1>cc11111111</Password1> |
| | | <UserName2>2228607100</UserName2> |
| | | <Password2>a5m1nf0g00d</Password2> |
| | | <!--<UserName2>2228607100</UserName2> |
| | | <Password2>a5m1nf0g00d</Password2>--> |
| | | <UserName3></UserName3> |
| | | <Password3></Password3> |
| | | </RichCreatorConfig> |
| | |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using System.Threading; |
| | | using RichCreator.Utility.Structs; |
| | | using RichCreator.Utility; |
| | | using System.Drawing; |
| | | using RichCreator.Utility.Captures; |
| | | using static test.Graphics; |
| | | using RichCreator.Utility.PathFinding; |
| | | |
| | | namespace test |
| | | { |
| | | |
| | | public class person |
| | | { |
| | | public int age { get; set; } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | class Program |
| | | { |
| | | |
| | | static void GetN(person p) |
| | | { |
| | | p = new person(); |
| | | p.age = 2; |
| | | } |
| | | //static void GetN(person p) |
| | | //{ |
| | | // p = new person(); |
| | | // p.age = 2; |
| | | //} |
| | | |
| | | |
| | | static void Main(string[] args) |
| | | { |
| | | |
| | | |
| | | ZTPoint A = new ZTPoint(0, 1); |
| | | ZTPoint B = new ZTPoint(1, 0); |
| | | ZTPoint C = new ZTPoint(3, 0); |
| | | ZTPoint D = new ZTPoint(4, 1); |
| | | ZTPoint E = new ZTPoint(3, 2); |
| | | ZTPoint F = new ZTPoint(2, 1); |
| | | ZTPoint G = new ZTPoint(1, 2); |
| | | |
| | | var edges = new List<Tuple<ZTPoint, ZTPoint, double>>() |
| | | { |
| | | new Tuple<ZTPoint,ZTPoint,double>(A,B,12), |
| | | new Tuple<ZTPoint,ZTPoint,double>(A,F,16), |
| | | new Tuple<ZTPoint,ZTPoint,double>(A,G,14), |
| | | new Tuple<ZTPoint,ZTPoint,double>(B,F,7), |
| | | new Tuple<ZTPoint,ZTPoint,double>(B,C,10), |
| | | new Tuple<ZTPoint,ZTPoint,double>(G,F,9), |
| | | new Tuple<ZTPoint,ZTPoint,double>(G,E,8), |
| | | new Tuple<ZTPoint,ZTPoint,double>(F,C,6), |
| | | new Tuple<ZTPoint,ZTPoint,double>(F,E,2), |
| | | new Tuple<ZTPoint,ZTPoint,double>(C,D,3), |
| | | new Tuple<ZTPoint,ZTPoint,double>(C,E,5), |
| | | new Tuple<ZTPoint,ZTPoint,double>(E,D,4), |
| | | }; |
| | | |
| | | var dij = new Dijkstra(edges); |
| | | var path = dij.Find(D, G); |
| | | |
| | | for (int i = 0; i < path.Count; i++) |
| | | { |
| | | Console.WriteLine(path[i].ToString()); |
| | | } |
| | | |
| | | |
| | | //ZTPoint A = new ZTPoint(0, 1); |
| | | //ZTPoint B = new ZTPoint(1, 0); |
| | | //ZTPoint C = new ZTPoint(3, 0); |
| | | //ZTPoint D = new ZTPoint(4, 1); |
| | | //ZTPoint E = new ZTPoint(3, 2); |
| | | //ZTPoint F = new ZTPoint(2, 1); |
| | | //ZTPoint G = new ZTPoint(1, 2); |
| | | |
| | | //var edges = new List<Tuple<ZTPoint, ZTPoint, double>>() |
| | | //{ |
| | | // new Tuple<ZTPoint,ZTPoint,double>(A,B,12), |
| | | // new Tuple<ZTPoint,ZTPoint,double>(A,F,16), |
| | | // new Tuple<ZTPoint,ZTPoint,double>(A,G,14), |
| | | // new Tuple<ZTPoint,ZTPoint,double>(B,F,7), |
| | | // new Tuple<ZTPoint,ZTPoint,double>(B,C,10), |
| | | // new Tuple<ZTPoint,ZTPoint,double>(G,F,9), |
| | | // new Tuple<ZTPoint,ZTPoint,double>(G,E,8), |
| | | // new Tuple<ZTPoint,ZTPoint,double>(F,C,6), |
| | | // new Tuple<ZTPoint,ZTPoint,double>(F,E,2), |
| | | // new Tuple<ZTPoint,ZTPoint,double>(C,D,3), |
| | | // new Tuple<ZTPoint,ZTPoint,double>(C,E,5), |
| | | // new Tuple<ZTPoint,ZTPoint,double>(E,D,4), |
| | | //}; |
| | | |
| | | //var dij = new Dijkstra(edges); |
| | | //var path = dij.Find(D, G); |
| | | |
| | | //for (int i = 0; i < path.Count; i++) |
| | | //{ |
| | | // Console.WriteLine(path[i].ToString()); |
| | | //} |
| | | |
| | | |
| | | Console.WriteLine("finish!~"); |
| | |
| | | <None Include="App.config" /> |
| | | <None Include="packages.config" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ProjectReference Include="..\RichCreator.Utility\RichCreator.Utility.csproj"> |
| | | <Project>{ceeff4d3-cc6f-4afe-85fe-e590c87a9972}</Project> |
| | | <Name>RichCreator.Utility</Name> |
| | | </ProjectReference> |
| | | </ItemGroup> |
| | | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
| | | <Import Project="..\packages\EMGU.CV.4.1.0.3420\build\EMGU.CV.targets" Condition="Exists('..\packages\EMGU.CV.4.1.0.3420\build\EMGU.CV.targets')" /> |
| | | <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> |