2009-08-16 5 views
2

내 그림 상자가 배경 그림으로 설정된 레이더 그림이있는 내 양식의 그룹 상자 안에 있습니다. 내 의도는 동적으로 런타임에 레이더 영역 (겹쳐) 내의 작은 Jpeg 이미지를로드하는 것이지만이를 달성하는 가장 좋은 방법은 확실하지 않습니다. 모든 미친 아이디어는 환영합니다 (하지만 나는 쉬운 것을 선호합니다). 감사합니다.C#에서 레이더를 시뮬레이트하는 가장 좋은 방법은 무엇입니까?

답변

3

"레이더"가 어떻게 보이는지에 따라 많이 달라 지지만 Paint 이벤트 핸들러를 구현하고 레이더 디스플레이의 내용을 직접 그려야합니다. 그림 상자는 지금까지만 ("별로"는 아닙니다) 당신을 데려 갈 것입니다.

GDI +는 원, 선, 텍스트 및 이미지를 그리는 데 매우 사용하기 쉽고 디스플레이가 어떻게 보이는지 완벽하게 제어 할 수 있습니다.

0

가장 간단한 방법은 작은 JPEG를 작은 PictureBox에로드하고이를 런타임에 PictureBox의 Controls 컬렉션에 추가하는 것입니다 (즉 PictureBox에 배치).

깜박임이 생기기 때문에 약간 더 복잡한 방법은 주 그림과 작은 그림을 클래스 수준의 Bitmap 개체로 유지하는 것입니다. 주 그림 상자의 그림판 이벤트에서는 주 그림을 복사 한 다음 작은 그림 그림을 두 번째 수준의 비트 맵 (_doubleBuffer 또는 이와 비슷한 이름)에 DrawImage 메서드를 사용하여 복사 한 다음 PictureBox에 DrawImage를 사용하여 _doubleBuffer를 복사합니다. 디스플레이를 업데이트하고 모든 것을 다시 그려야 할 때마다 PictureBox의 Invalidate 메소드를 호출하면됩니다.

여기에는 이러한 방법을 사용하는 많은 예제가 있습니다. 행운을 빌어 요. 재미있게 들립니다. (고전 아케이드 게임 인 Submarine을 다시 쓰고 있다면, 저에게 그 게임을 좋아했습니다.) 실제 예로서

+0

젠장! 그게 미친 짓이 들리네. 위의 JW에서 제안한 초보자를위한 GDI +를 읽어 보도록하겠습니다. 그래도 고마워. 잠수함을하지 않았습니다. 나는 NES 버전의 "Red October 사냥"을 위해 더 많은 것을 할 것입니다. –

+0

그것은 복잡하지 않습니다. 사실 Jason의 답을 정교하게 표현한 것입니다. 또한 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#과 마감일이 어렴풋이 드러나지 않았습니다. (마감일 전에 <48에 내게 나타났습니다) 이것은 도움이 될 수 있습니다 .. –

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

코드에서 편집 할 수 있습니까? 오늘날의 표준은 단순한 외부 링크 이상의 기능을 요구합니다. –

+0

물론 컨트롤 초기화 및 레이아웃 등에 따라 코드를 게시하는 것이 현명하지는 않지만 – MusiGenesis

관련 문제