使用 C# 開發智能手機軟體:推箱子(二十二)

來源:互聯網
上載者:User

這是“使用 C# 開發智能手機軟體:推箱子”
系列文章的第二十二篇。在這篇文章中,介紹 Window/MainForm.Replay.cs 來源程式檔案。這個來源程式檔案是 MainForm
類的一部分,該類繼承自 System.Windows.Forms.Form 類,表示推箱子的主表單。而本篇文章講述的是推箱子“回放”過程,如所示:

我們先看看 MainForm.Designer.cs 來源程式檔案(該檔案是由 Visual Studio 2005 IDE 自動產生的)中和“回放”相關的部分:

namespace Skyiv.Ben.PushBox.Window
{
  partial class MainForm
  {
      // 注意:省略了很多代碼,僅保留和 miReplayOrLand 相關的部分。
    private void InitializeComponent()
    {
      this.miReplayOrLand = new System.Windows.Forms.MenuItem();
      this.mnuMain.MenuItems.Add(this.miReplayOrLand);
      this.miReplayOrLand.Text = "回放";
      this.miReplayOrLand.Click += new System.EventHandler(this.miReplayOrLand_Click);
    }
    private System.Windows.Forms.MenuItem miReplayOrLand;
  }
}

上述代碼片斷展示了在推箱子遊戲的主表單上點擊“回放”時發生的事件:

this.miReplayOrLand.Click += new System.EventHandler(this.miReplayOrLand_Click);

也就是說如果以前使用“錄影”功能儲存過通關步驟的話,可以通過“回放”功能將該通關步驟重新播放出來。這是由下面的 MainForm.Replay.cs 來源程式代碼實現的:

 1 using System;
 2 using System.Drawing;
 3 using System.Threading;
 4 using Skyiv.Ben.PushBox.Common;
 5 
 6 namespace Skyiv.Ben.PushBox.Window
 7 {
 8   partial class MainForm
 9   {
10     Rectangle workerThreadInvalidRectangle;
11     bool workerThreadIsStop;
12 
13     private void miReplayOrLand_Click(object sender, EventArgs e)
14     {
15       if (env.IsDesign)
16       {
17         env.Pen = Block.Land;
18         UpdateStatus();
19       }
20       else
21       {
22         env.IsReplay = true;
23         workerThreadIsStop = false;
24         UpdateStatus();
25         ThreadPool.QueueUserWorkItem(WorkerThreadReplay, env.GetSteps());
26       }
27     }
28 
29     /// <summary>
30     /// 回放通關步驟,使用後台背景工作執行緒
31     /// </summary>
32     /// <param name="steps">通關步驟</param>
33     private void WorkerThreadReplay(object steps)
34     {
35       try
36       {
37         foreach (char c in (string)steps)
38         {
39           if (workerThreadIsStop) break;
40           if (env.ReplayDelay > 0) Thread.Sleep(env.ReplayDelay);
41           Step step = c;
42           if (!env.StepIt(step.Direct, step.IsStop, out workerThreadInvalidRectangle)) break;
43           Invoke(new EventHandler(WorkerThreadUpdateStatus));
44         }
45       }
46       finally
47       {
48         env.IsReplay = false;
49         Invoke(new EventHandler(WorkerThreadUpdateStatus));
50       }
51     }
52 
53     /// <summary>
54     /// 更新主表單狀態
55     /// </summary>
56     /// <param name="sender">事件來源</param>
57     /// <param name="e">不包含任何事件數目據的事件參數</param>
58     void WorkerThreadUpdateStatus(object sender, EventArgs e)
59     {
60       Invalidate(workerThreadInvalidRectangle);
61       UpdateStatus();
62     }
63   }
64 }
65 
66 

幾點說明:

  • 因為“回放”是一個長時間的過程,為了防止使用者介面失去響應,所以使用了多線程技術,在後台背景工作執行緒進行回放。也說是將回放通關步驟的 WorkerThreadReplay 方法加入到線程池中去:ThreadPool.QueueUserWorkItem(WorkerThreadReplay, env.GetSteps());
  • workerThreadInvalidRectangle 欄位(Rectangle 類型)表明“回放”時主表單需要更新的矩形地區。該值是由 Env 類的 StepIt 方法設定。
  • workerThreadIsStop 欄位(bool 類型)指示是否停止回放,初始值為 false。當使用者按“停止”按鈕時,該欄位被設定為 true,從而停止回放。
  • miReplayOrLand_Click 方法響應使用者的“回放”請求,啟動後台“回放”線程。
  • WorkerThreadReplay 方法在後台線程執行實際的“回放”動作,她實際上是對已經儲存的通關步驟的每一步調用 Env 類的 StepIt 方法來進行“回放”,並通過 Invoke 調用  WorkerThreadUpdateStatus 方法更新主表單狀態。
  • WorkerThreadUpdateStatus 方法負責更新主表單狀態。
  • 如果在智能手機上進行“回放”,就是不使用後台線程,使用者介面也不會失去響應,不知是什麼原因。
上一篇:使用 C# 開發智能手機軟體:推箱子(二十一)
下一篇:使用 C# 開發智能手機軟體:推箱子(二十三)
返回目錄
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.