Как лучше всего симулировать радар в C #?

2

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

Теги:
winforms
graphics

4 ответа

3
Лучший ответ

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

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

2

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

Исходный код проекта здесь.

Обновить код:

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
    Конечно, хотя размещать код, который зависит от инициализации элемента управления, макета и т. Д., Не очень удобно.
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 + или каких-либо графических программ в C # и приближающемся Крайнем сроке (Это возникло у меня <48 до крайнего срока) Это может помочь ..
0

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

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

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

  • 0
    Черт!! Это звучит безумно сложно ... Думаю, я пойду читать GDI + для начинающих, как это было предложено JW выше. Спасибо хоть. Не играл в подводную лодку; Я больше собираюсь для NES-версии "Охоты на Красный Октябрь".
  • 0
    Это не безумно сложно, и на самом деле это просто проработка ответа Джейсона. Я также говорю о GDI + и обработке события Paint.
Показать ещё 10 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню