2009-08-16 2 views
2

У меня есть окно с картинками внутри группового ящика в моей форме с изображением радара, установленного в качестве фонового рисунка. Мое намерение состоит в том, чтобы динамически загружать крошечные изображения Jpeg в области радара (наложенные) во время выполнения, но я не уверен, как наилучшим образом достичь этого. Все сумасшедшие идеи приветствовали (но я предпочел бы, чтобы здравомыслящий легко их сделал). Спасибо всем.Что было бы лучшим способом имитации радара в C#?

ответ

3

Это зависит от того, как должен выглядеть ваш «радар», но почти наверняка вам понадобится реализовать обработчик события Paint, и сами рисуйте содержимое радарного дисплея. Коробка с картинками доставит вас до сих пор («не очень»).

GDI + очень прост в использовании для рисования кругов, линий, текста и изображений и даст вам полный контроль над тем, как выглядит ваш дисплей.

0

Самый простой способ - загрузить ваши крошечные JPEG-файлы в миниатюрные PictureBoxes и добавить их в основную коллекцию элементов управления PictureBox (т. Е. Разместить их на PictureBox) во время выполнения.

Так как это, вероятно, произведет мерцание, немного более сложным способом является сохранение основного изображения и крошечных изображений в объектах Bitmap на уровне класса, а в главном событии PaintBox Paint вы копируете основное изображение, за которым следуют каждый маленький изображение на второй битмап на уровне класса (с именем _doubleBuffer или что-то в этом роде) с использованием метода DrawImage, а затем скопируйте _doubleBuffer на свой PictureBox (также используя DrawImage). Всякий раз, когда вам нужно обновить свой экран и перерисовать все, вы просто вызываете метод Invalidate PictureBox.

Здесь много примеров, которые показывают, как использовать эти методы. Удачи, это звучит забавно (если вы переписываете классическую аркадную игру Submarine, дайте мне знать - мне понравилась эта игра).

+0

Блин !! Это звучит Сумасшедший сложный ... Думаю, я поеду на GDI + для начинающих, как это было предложено JW выше. Спасибо хоть. Не играл в «Подводную лодку»; Я больше собираюсь перейти к версии NES «The Hunt for the Red October». –

+0

Это не сумасшествие сложное, и на самом деле это просто разработка ответа Джейсона. Я также говорю о GDI + и обработке события Paint. – MusiGenesis

+0

Двойная буферная часть необходима для предотвращения мерцания. – MusiGenesis

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); 
     } 
    } 
    } 

Это, конечно, является очень простым, предполагает исходное изображение путь и не заботятся о многих сложных вещах, но это быстрая и грязная тэк из него, которые вам безусловно, можно опираться.

+0

Приветствия ..... Не сделали GDI + или любую графику pprogrammingin C#, и Deadline надвигался (это было на меня меньше <48 до истечения срока) Это могло бы помочь. –

2

Click here для запуска образца приложения, которое демонстрирует основы работы с радаром (или, по крайней мере, одним способом). Примечание. Это приложение не выполняет двойную буферизацию или прозрачность крошечного изображения.

Исходный код проекта: here.

Update Код:

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

Не могли бы вы изменить код? Сегодняшние стандарты требуют не только внешней связи. –

+0

Уверен, хотя это не очень удобно отправлять код, который зависит от инициализации и компоновки управления и т. Д. – MusiGenesis

Смежные вопросы