2012-06-01 5 views
0

대학용 과제로 간단한 멀티 스레드 Server \ Client 게임을 구현했습니다. 메인 스레드에 추가하여 클라이언트 측에서 내 양식이 깜박이는 이유

이 있습니다

플레이 그라운드 양식에 선수를 그리기의 책임이 1 스레드.

2 스레드가 서버와 통신하여 방향을 보내고 위치 및 기타 정보를 수신합니다.

처음에는 호출 기술을 사용했지만 폐기 한 후에 그래픽을 사용했기 때문에 작동하지 않았습니다. Draw on a form by a separate thread

때문에 도면 실을 것을 방지하고 정례화하기 위해, 난 그냥 플래그 '무효화'도면 스레드의 모든 특정 시간을 높여보고 메인 쓰레드에의 실제 처리를두고 :

public Form1() 
    { 
     SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 
     InitializeComponent(); 
    } 

    private void Draw() 
    { 
     while (true) 
     { 
      Thread.Sleep(200); 
      Invalidate(); 
     } 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     if (map.hasGraph) 
     { 
      map.Draw(e.Graphics); 
      if (this.Index != null) 
       e.Graphics.FillRectangle(Brush, Rectangle); 
      if (OpponentIndex != null) 
       e.Graphics.FillRectangle(OpponentBrush, OpponentRectangle); 
     } 
    } 

이중 버퍼링을 사용하고 있는데도 형식이 임의의 방식으로 깜박이고 도면 스레드의 절전 시간을 늘릴 때 깜박임이 줄어들지 만 200ms는 이미 너무 많다고 생각합니다. 어떤 조언이 필요합니까?

[편집]

내가 (이 바보 생각 될 수있다) 코드에서 문제를 만든 속성 편집기에서 이중 버퍼링 플래그를 설정하고있어 실현하지만 난 내 테스트를 반 시간을 보냈다 플래그 중 하나와 함께 코드와 함께 두 장소에서 두 번 버퍼링 플래그를 설정하면 문제가 제기, 내 문제가 해결되었지만 지금이 문제를 해결할 수 있을지 알고 싶습니다.

+2

가 표시 타이머 틱에 형성 이미지

  • 복사 이미지를 새로 고쳐집니다 whitch 타이머를 만들고 이미지
  • 에 그릴 것입니다 새 스레드 파크를 만들기위한 증거가 없다 그것의 발췌 문장. –

  • +0

    블랭크 된 이미지를 블랭크하고 그 위에 버퍼링 된 이미지를 그릴 경우 발생할 수 있습니다. 마지막 이미지를 버퍼링 한 이미지가 아닙니다. – Doomsknight

    +0

    winforms라고 가정 할 수 있습니까?페인팅, picturebox, 패널 .... 컨트롤 무엇입니까? –

    답변

    2

    오른쪽 실행 시간이 길어질수록 악화되고 악화됩니다.

    프로그램 페인트 할 때마다 무한 루프가있는 그리기를 시작합니다. 무한 루프는 페인트를 호출하며 다른 무한 루프에서 그리기를 호출합니다. 여기에 순환 참조가있는 것 같습니다. 내가 Map.Draw를 가정 할 수 있다면 Draw()

    훨씬 더 쉬운 해결책이있다. 비트 맵에 모든 것을 그려 넣고 onPaint 이벤트에서 비트 맵을 그려라.

    Bitmap buffer=new Bitmap(this.Width, this.Height); //make sure to resize the bitmap during the Form.Onresize event 
    Form1() 
    { 
        InitializeComponent(); 
        Timer timer=new Timer(); 
        timer.Interval= 100; 
        timer.Tick+=...... 
        timer.Start() 
    } 
    
    //the Timer tick event 
    private void timer_tick(.... 
    { 
        if (map.hasGraph) 
        { 
         using (Graphics g = Graphics.FromImage(buffer)) 
         { 
          //You might need to clear the Bitmap first, and apply a backfround color or image 
          //change color to whatever you want, or don't use this line at all, I don't know 
          g.Clear(Color.AliceBlue); 
    
          if (this.Index != null) 
           g.FillRectangle(Brush, Rectangle); 
          if (OpponentIndex != null) 
           g.FillRectangle(OpponentBrush, OpponentRectangle); 
         } 
        panel1.BackgroundImage=buffer; 
        } 
    } 
    

    참고 나는 문법의 정확성이 테스트를하지 않았다.

    +0

    원한다면이 점을 더 잘 설명 할 수 있습니다. 하지만 깜박이는 문제는 많이 없어야합니다. 초당 10 프레임의 빈도를 설정하고, 원하는 값으로 틱 값을 변경하고, 초당 5 프레임으로 타이머를 변경합니다. 간격 = (밀리 초 단위) –

    +0

    무승부 방법은 분리 된 스레드의 시작 메소드이므로 아무도 그것을 호출하지 않고 책임있는 thread.anyway 판을 참조하기 때문에 순환 참조가 없다는 것은 확실합니다. –

    0
    1. 마지막으로 렌더링 된 장면을 저장하는 데 사용할 이미지를 만듭니다.
    2. 당신이 이중 버퍼링을 사용하는 방법
    관련 문제