2012-04-20 61 views
2

我在這個應用程序中使用了兩個線程,這是一個Tron遊戲。我有一個文本框,在每場比賽結束時顯示比分。每個「遊戲」都是在第二個drawThread線程中繪製的。文本框沒有刷新文本,但是messagebox確實是

事情是,我在MessageBox中顯示分數後,我改變了TextBox.Text和MessageBox顯示分數罰款,但是TextBox沒有。

enter image description here

任何想法?我確保使用線程安全調用(但是我正在更改它創建的線程中的文本)。有問題的代碼是在createGame()方法中,並且是

SetLabel(score);

public Form1() 
     { 
      InitializeComponent(); 
      canvas = game_panel.CreateGraphics(); 
      formCanvas = this.CreateGraphics(); 
      game_panel.Invalidate(true); 
      bikes = new List<LightBike>(); 
      bikes.Add(new LightBike(new Point(game_panel.Size.Width - 25, game_panel.Height/2), Color.Blue, "left", new DirectionKeys(Keys.Left, Keys.Down, Keys.Up, Keys.Right, Keys.Control))); 
      bikes.Add(new LightBike(new Point(25, game_panel.Height/2), Color.Red, "right", new DirectionKeys(Keys.A, Keys.S, Keys.W, Keys.D, Keys.Q))); 
      createGame(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      if (drawThread.ThreadState == ThreadState.Stopped) 
      { 
       InitializeComponent(); 
       createGame(); 
       drawThread.Start(); 
      } 
      else 
      { 
       if(drawThread.ThreadState != ThreadState.WaitSleepJoin) 
        drawThread.Start(); 
      } 
      button1.Text = "Play Again"; 

     } 
public void SetLabel(string message) 
     { 

      if (this.textBox1.InvokeRequired) 
       this.textBox1.Invoke((Action<string>)SetLabel, message); 
      else 
       this.textBox1.Text = message; 
      MessageBox.Show(message); 
     } 
public void createGame() 
     { 
      if (!firststart) 
      { 
       foreach (LightBike b in deleteBikes) 
       { 
        if(b.color == Color.Blue) 
         bikes.Insert(0,b); 
        if (b.color == Color.Red) 
         bikes.Insert(1, b); 
       } 
       bikes[0].Redraw(new Point(game_panel.Size.Width - 25, game_panel.Height/2), "left"); 
       bikes[1].Redraw(new Point(25, game_panel.Height/2), "right"); 
      } 
      drawThread = new Thread(drawBikes); 
      grid = new int[game_panel.Size.Width, game_panel.Size.Height]; //create the grid map 

      game_panel.Update(); 

      String score = ""; 
      foreach (LightBike b in bikes) 
      { 
       score += b.toColorString() + ": " + b.score + " "; 
      } 
      SetLabel(score); 
      textBox1.Refresh();   
     } 

public void drawBikes() 
     { 
      String gameStatus = "WIN"; 

      deleteBikes = new List<LightBike>(); 
      while (true) 
      { 
       int tieCount = 0; 

       foreach (LightBike b in bikes) //check collision 
       { 

        if (!isValidLocation(b.location)) 
        { 
         deleteBikes.Add(b); 
         tieCount++; 
        } 
       } 
        foreach (LightBike b in deleteBikes) 
        { 
         //MessageBox.Show("DELETED BIKES: " + b.color.ToString()); 
         bikes.Remove(b); 
        } 
        if (tieCount > bikes.Count) //if the deleteBikes contain more than the bikes 
        { 
         gameStatus = "TIE"; 
         break; 
        } 

       if (bikes.Count <= 1) //game over 
        break; 

       foreach (LightBike b in bikes) //draw bikes 
       { 

        //canvas.DrawLine(new Pen(b.color, BIKE_SIZE), b.getPreviousLocation(), b.location); 
        canvas.DrawLine(new Pen(b.color, BIKE_SIZE) { EndCap = System.Drawing.Drawing2D.LineCap.Square }, b.location, b.getNextLocation()); 
        //MessageBox.Show("Bike "+b.color.ToString()+": "+Form1.ActiveForm.GetPixelColor(b.location.X, b.location.Y).ToString()); 
        grid[b.location.X, b.location.Y] = (bikes.IndexOf(b) + 1); 
       } 

       foreach (LightBike b in bikes) //update positions 
       { 
        if(b.isBoosting && b.boostCounter > 0) //player is boosting 
        { 
         while(isValidLocation(b.getNextLocation())) 
         { 
          b.location = b.getNextLocation(); 
          b.boostCounter--; 
          if (b.boostCounter == 0) 
          { 
           b.isBoosting = false; 
           b.boostCounter = 20; 
          } 
         } 
        } 
        b.location = b.getNextLocation(); 

       } 

       Thread.Sleep(GAME_SPEED); 

      } 
      String endingString =""; 
      foreach (LightBike b in bikes) 
      { 
       endingString += b.toColorString() + " "; 
       if (gameStatus == "WIN") 
        b.score += 1;  
      } 


      endingString += gameStatus+"!"; 
      canvas.DrawString(endingString,new Font("Times New Roman",20),new SolidBrush(Color.White),new Point(150,200)); 


      firststart = false; 
      drawThread.Abort(); 

     } 
+0

嘗試調用應用.DoEvents()更改文本後。 – SimpleVar 2012-04-20 01:08:25

+0

無效,放在textBox1.Refresh()後面;並沒有任何變化 – 2012-04-20 01:11:29

+0

因爲消息框顯示在DoEvents之前......將它放在消息框之前的SetLabel方法中。 – SimpleVar 2012-04-20 01:13:37

回答

0

取而代之的是:

public void SetLabel(string message) 
{ 

    if (this.textBox1.InvokeRequired) 
     this.textBox1.Invoke((Action<string>)SetLabel, message); 
    else 
     this.textBox1.Text = message; 
    MessageBox.Show(message); 
} 

只是這樣做:

public void SetLabel(string message) 
{ 
    // processing things here 


    this.Invoke((MethodInvoker)delegate 
    { 
     // UI things here 

     this.textBox1.Text = message; 
    }); 


    MessageBox.Show(message); 
}  

這樣,你不需要不停地檢測InvokeRequired