2016-08-22 20 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