2009-08-16 79 views
2

我的表单中有一个Groupbox里面的图片框,里面有雷达图片作为背景图片。我的意图是在运行时动态加载雷达区域内的微小Jpeg图像(叠加),但我不确定实现此目的的最佳方式。 欢迎所有疯狂的想法(但我宁愿容易做一些)。 谢谢大家。在C#中模拟雷达的最佳方法是什么?

回答

3

这很大程度上取决于你的“雷达”需要的样子,但几乎可以肯定你需要实现Paint事件处理程序,并自己绘制雷达显示的内容。一个图片框只会让你到目前为止(“不太”)。

GDI +非常易于使用来绘制圆圈,线条,文本和图像,并且可以完全控制显示器的外观。

0

最简单的方法是将您的微型JPEG加载到微小的PictureBox中,并在运行时将它们添加到主PictureBox的Controls集合中(即将它们放置在PictureBox上)。

由于这可能会产生闪烁,稍微复杂一点的方法是将主图片和微小图片保存在类级别的Bitmap对象中,并在主PictureBox的Paint事件中复制主图片,然后再复制每个小图片图片添加到使用DrawImage方法的第二个类级别的位图(名为_doubleBuffer或类似的东西),然后将_doubleBuffer复制到您的PictureBox(也使用DrawImage)。无论何时需要更新显示并重新绘制所有内容,只需调用PictureBox的Invalidate方法即可。

这里有很多关于SO的例子展示了如何使用这些方法。祝你好运,这听起来很有趣(如果你正在重写经典的街机游戏Submarine,请告诉我 - 我喜欢那款游戏)。

+0

该死!这听起来很疯狂......想想我会按照上面JW的建议去阅读GDI +的初学者。谢谢。没玩过潜艇;我更喜欢NES版的“寻找红十月”。 – 2009-08-16 17:29:12

+0

这并不复杂,它实际上只是Jason的回答。我也在谈论GDI +和处理Paint事件。 – MusiGenesis 2009-08-16 17:37:00

+0

双缓冲部分对于避免闪烁是必不可少的。 – MusiGenesis 2009-08-16 17:37:35

2

至于实际的例子:

// Among others 
    using System.Collections.Generic; 
    using System.Drawing; 
    using System.IO; 

    class TinyPic { 
    public readonly Image Picture; 
    public readonly Rectangle Bounds; 

    public TinyPic(Image picture, int x, int y) { 
     Picture = picture; 
     Bounds = new Rectangle(x, y, picture.Width, picture.Height); 
    } 
    } 

    class MyForm : Form { 

    Dictionary<String, TinyPic> tinyPics = new Dictionary<String, TinyPic>(); 

    public MyForm(){ 
     InitializeComponent(); // assuming Panel myRadarBox 
          // with your background is there somewhere; 
     myRadarBox.Paint += new PaintEventHandler(OnPaintRadar); 
    } 

    void OnPaintRadar(Object sender, PaintEventArgs e){ 
     foreach(var item in tinyPics){ 
     TinyPic tp = item.Value; 
     e.Graphics.DrawImageUnscaled(tp.Picture, tp.Bounds.Location); 
     } 
    } 

    void AddPic(String path, int x, int y){ 
     if (File.Exists(path)){ 
     var tp = new TinyPic(Image.FromFile(path), x, y); 
     tinyPics[path] = tp; 
     myRadarBox.Invalidate(tp.Bounds); 
     } 
    } 

    void RemovePic(String path){ 
     TinyPic tp; 
     if (tinyPics.TryGetValue(path, out tp)){ 
     tinyPics.Remove(path); 
     tp.Picture.Dispose(); 
     myRadarBox.Invalidate(tp.Bounds); 
     } 
    } 
    } 

当然这是很基本的,假定图像源的路径,并没有考虑许多复杂的东西照顾,但这是它的快速和肮脏的JIST你当然可以继续发展。

+0

干杯.....没有完成GDI +或任何图形pprogrammingin C#和迫近的最后期限(这是在我截止日期前在我<48前突然出现)这可以帮助.. – 2009-08-17 00:59:39

2

Click here运行一个示例应用程序,演示如何做雷达(或单向,至少)的基础知识。注意:此应用程序不会执行双缓冲或微小图像的透明度。

该项目的源代码是here

更新代码:

public partial class Form1 : Form 
{ 
    private Bitmap _canvas; 
    private float _sweepStartAngle = -90; 
    private float _sweepAngle = 15; 
    private SolidBrush _sweepBrush = new SolidBrush(Color.Red); 
    private Rectangle _sweepRect; 
    private Timer _sweepTimer = new Timer(); 
    private Bitmap _submarine; 
    private Point _submarinePosition = new Point(0, 0); 
    private Random rnd = new Random(); 

    public Form1() 
    { 
     InitializeComponent(); 

     _canvas = new Bitmap(pbScope.Width, pbScope.Height); 
     pbScope.Image = _canvas; 
     _sweepRect = new Rectangle(0, 0, pbScope.Width, pbScope.Height); 

     _submarine = (Bitmap)pbSubmarine.Image; 

     RedrawScope(); 

     _sweepTimer.Interval = 100; 
     _sweepTimer.Tick += new EventHandler(_sweepTimer_Tick); 
     _sweepTimer.Start(); 
    } 

    void _sweepTimer_Tick(object sender, EventArgs e) 
    { 
     _sweepStartAngle += _sweepAngle; 
     RedrawScope(); 
    } 

    private void RedrawScope() 
    { 
     using (Graphics g = Graphics.FromImage(_canvas)) 
     { 
      // draw the background 
      g.DrawImage(pbBackground.Image, 0, 0); 

      // draw the "sweep" 
      GraphicsPath piepath = new GraphicsPath(); 
      piepath.AddPie(_sweepRect, _sweepStartAngle, _sweepAngle); 
      g.FillPath(_sweepBrush, piepath); 
      //g.FillPie(_sweepBrush, _sweepRect, _sweepStartAngle, _sweepAngle); 

      // move the submarine and draw it 
      _submarinePosition.X += rnd.Next(3); 
      _submarinePosition.Y += rnd.Next(3); 
      // check if submarine intersects with piepath 
      Rectangle rect = new Rectangle(_submarinePosition, _submarine.Size); 
      Region region = new Region(piepath); 
      region.Intersect(rect); 
      if (!region.IsEmpty(g)) 
      { 
       g.DrawImage(_submarine, _submarinePosition); 
      } 
     } 
     pbScope.Image = _canvas; 
    } 

    private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     _sweepTimer.Stop(); 
     _sweepTimer.Dispose(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     //GraphicsPath piepath = new GraphicsPath(); 
     //piepath.AddPie(

    } 

} 

    private void InitializeComponent() 
    { 
     System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); 
     this.pbScope = new System.Windows.Forms.PictureBox(); 
     this.pbBackground = new System.Windows.Forms.PictureBox(); 
     this.pbSubmarine = new System.Windows.Forms.PictureBox(); 
     ((System.ComponentModel.ISupportInitialize)(this.pbScope)).BeginInit(); 
     ((System.ComponentModel.ISupportInitialize)(this.pbBackground)).BeginInit(); 
     ((System.ComponentModel.ISupportInitialize)(this.pbSubmarine)).BeginInit(); 
     this.SuspendLayout(); 
     // 
     // pbScope 
     // 
     this.pbScope.Location = new System.Drawing.Point(12, 12); 
     this.pbScope.Name = "pbScope"; 
     this.pbScope.Size = new System.Drawing.Size(300, 300); 
     this.pbScope.TabIndex = 0; 
     this.pbScope.TabStop = false; 
     // 
     // pbBackground 
     // 
     this.pbBackground.Image = ((System.Drawing.Image)(resources.GetObject("pbBackground.Image"))); 
     this.pbBackground.Location = new System.Drawing.Point(341, 12); 
     this.pbBackground.Name = "pbBackground"; 
     this.pbBackground.Size = new System.Drawing.Size(300, 300); 
     this.pbBackground.TabIndex = 1; 
     this.pbBackground.TabStop = false; 
     this.pbBackground.Visible = false; 
     // 
     // pbSubmarine 
     // 
     this.pbSubmarine.Image = ((System.Drawing.Image)(resources.GetObject("pbSubmarine.Image"))); 
     this.pbSubmarine.Location = new System.Drawing.Point(658, 45); 
     this.pbSubmarine.Name = "pbSubmarine"; 
     this.pbSubmarine.Size = new System.Drawing.Size(48, 48); 
     this.pbSubmarine.TabIndex = 2; 
     this.pbSubmarine.TabStop = false; 
     this.pbSubmarine.Visible = false; 
     // 
     // Form1 
     // 
     this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
     this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
     this.ClientSize = new System.Drawing.Size(326, 328); 
     this.Controls.Add(this.pbSubmarine); 
     this.Controls.Add(this.pbBackground); 
     this.Controls.Add(this.pbScope); 
     this.Name = "Form1"; 
     this.Text = "Radar"; 
     this.Load += new System.EventHandler(this.Form1_Load); 
     this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); 
     ((System.ComponentModel.ISupportInitialize)(this.pbScope)).EndInit(); 
     ((System.ComponentModel.ISupportInitialize)(this.pbBackground)).EndInit(); 
     ((System.ComponentModel.ISupportInitialize)(this.pbSubmarine)).EndInit(); 
     this.ResumeLayout(false); 

    } 
+0

你可以在代码中编辑?今天的标准不仅仅需要外部链接。 – 2014-03-05 12:00:42

+0

当然,虽然发布依赖于控件初始化和布局等的代码并不是非常实用 – MusiGenesis 2014-03-05 17:15:13

相关问题