2016-08-22 22 views
2

我想做一个小测试,如何在WPF-C#应用程序中将“星星”绘制到名为image1的Imagebox中。有一个计时器,当它过去时调用函数来创建和绘制starset。整个方法可能有点谦虚,因为我对数学非常不好,对于那些擅长数学的人来说,这似乎有点深奥。问题在于,当我创建一个新的星形图时,新星的新坐标将完美打印出新图像。 (注释掉DrawTimer_Elapsed中的!starList.Any()子句和updateStars()调用 - 只剩下createStarSet()in),但是当updateStars执行时,星星的X和Y值似乎会增加(因为它们应该和与他们我希望绘图点),但图片保持不变,即使它应该由draw()更新。希望它至少有点可以理解在Image-Box中绘制明星

由于已经

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.Navigation; 
using System.Windows.Shapes; 
using System.Diagnostics; 
using System.Windows.Media; 
using System.Drawing; 

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DrawTimer.Interval = 100; 
      DrawTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.DrawTimer_Elapsed); 
      DrawTimer.Enabled = true; 
     } 

     public System.Timers.Timer DrawTimer = new System.Timers.Timer(); 
     public Random rndGen = new Random(); 
     public bool drawable = true; 

     public void DrawTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
     {   
      DrawTimer.Stop(); 
     if (!starList.Any()) 
     { 
      image1.Dispatcher.Invoke(new Action(() => this.createStarSet()), System.Windows.Threading.DispatcherPriority.Background); 
     } 
     else 
     { 
      image1.Dispatcher.Invoke(new Action(() => this.updateStars()), System.Windows.Threading.DispatcherPriority.Background); 
     } 
      image1.Dispatcher.Invoke(new Action(() => this.draw()), System.Windows.Threading.DispatcherPriority.Background); 
      DrawTimer.Start(); 
     } 

     public void updateStars() 
     { 
      foreach (Star myStar in starList) 
      { 
       myStar._X += 1; 
       myStar._Y += 1; 
      } 
     } 

     private void canvas1_Loaded(object sender, RoutedEventArgs e) 
     { 
      DrawTimer.Enabled = true; 
     } 

     public List<Star> starList = new List<Star>(); 

     public const int MAX_STARS = 100; 

     public void draw() 
     { 
      drawable = false; 
      GeometryGroup allMyStars = new GeometryGroup(); 
      foreach (Star myStar in starList) 
      { 
       allMyStars.Children.Add(new EllipseGeometry(new Point(myStar._X, myStar._Y), 2, 2)); 
      } 
      GeometryDrawing drawing = new GeometryDrawing(); 
      drawing.Geometry = allMyStars; 
      drawing.Pen = new Pen(Brushes.Black, 2); 
      DrawingImage finishedImage = new DrawingImage(); 
      finishedImage.Drawing = drawing; 
      image1.Source = finishedImage; 
      image1.Stretch = Stretch.None; 
      drawable = true; 
     } 

     public void createStarSet() 
     { 
      starList = new List<Star>(); 
      for (int i = 0; i < MAX_STARS; i++) 
      { 
       starList.Add(new Star(rndGen,this)); 
      } 
     } 

     public class Star 
     { 
      public int _X = 0; 
      public int _Y = 0; 
      public double _Speed = 0.0f; 
      public Star(Random rndGen, Window wdw) 
      { 
       _X = rndGen.Next(-(int)Math.Floor((wdw.Width/8)), (int)Math.Floor((wdw.Width/8))); 
       _Y = rndGen.Next(-(int)Math.Floor((wdw.Height/8)), (int)Math.Floor((wdw.Height/8))); 
       _Speed = rndGen.Next(1, 100)/100; 
      } 
     } 
    } 
} 

XAML

<Window x:Name="asca" x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="399.875" Width="806" MouseMove="asca_MouseMove"> 
    <Image x:Name="image1" Margin="0"/> 
</Window> 
+0

我们可以看到你的XAML代码吗? – Delosdos

+0

哦,是的,我现在将它附上! – prizm1

回答

1

Ok..this一个是一个棘手的,并已得到了我要一个小时左右。你的代码的问题在于你一直在将所有星星移动到同一个步骤,所以它们之间的“相对位置”是相同的。我从来没有使用过GeometryGroupGeometryDrawing,但它似乎会自动调整图像大小并将其集中在一起,这就是为什么在你看来没有任何动作。

我认为你有一些选择。一个人会绘制自己的位图,在那里你可以为你的星星设置绝对位置(我认为这样可以很好地工作)。其他可能使用wpf动画。

无论如何,如果你分配一个diferent方向每颗恒星,从而改变它们之间的相对位置,你的代码的工作,是这样的:

星类

public class Star 
    { 
     public int _X = 0; 
     public int _Y = 0; 
     public double _Speed = 0.0f; 
     public int _Direction; 

     public Star(int x, int y, double speed) 
     { 
      _X = x; 
      _Y = y; 
      _Speed = speed; 
     } 

     public Star(Random rndGen, Window wdw) 
     { 
      _X = rndGen.Next(-(int)Math.Floor((wdw.Width/8)), (int)Math.Floor((wdw.Width/8))); 
      _Y = rndGen.Next(-(int)Math.Floor((wdw.Height/8)), (int)Math.Floor((wdw.Height/8))); 
      _Speed = rndGen.Next(1, 100)/100; 
      _Direction = rndGen.Next(0, 4); 
     } 
    } 

UpdateStars方法

public void updateStars() 
    { 

     foreach (Star myStar in starList) 
     { 

      switch (myStar._Direction) 
      { 
       case 1: 
        myStar._X += 1; 
        break; 
       case 2: 
        myStar._Y += 1; 
        break; 
       case 3: 
        myStar._X -= 1; 
        break; 
       case 4: 
        myStar._Y -= 1; 
        break; 
      } 

     } 

    } 

你可以用这种方式看到你真的是即“星星”在移动。希望这可以帮助

+0

这确实有帮助:)有道理,我没有对GeometryDrawing如何在内部进行深入查找。我试图找出一个解决方案,并把它放在这里。感谢您的输入。 – prizm1