Step 6: Add a Timer
接下来,你要向匹配游戏中添加**“Timer”**控件。计时器等待指定的毫秒数后,触发一个称为“Tick”的事件。这对于启动操作或定时重复操作很有用。在本例中,你将使用一个计时器,让玩家开始选择两个图标,而如果图标不匹配,则在短暂时间后再次隐藏这两个图标。
添加计时器
在 Windows 窗体设计器中的工具箱中,请选择**“Timer”(位于“组件”类别中),然后按 Enter 键,或双击该计时器,向窗体中添加一个计时器控件。该计时器的图标名为“Timer1”**,应显示在窗体下的空间中,如下图所示。
Timer
说明 如果工具箱是空的,请确保在打开工具箱前选择窗体设计器,而不是窗体的后台代码。
选择**“Timer1”图标以选中该计时器。在“属性”窗口中,从查看事件切换到查看属性。然后将计时器的“Interval”属性设置为 750,但保留“Enabled”属性的设置“False”。“Interval”**属性将通知计时器两个计时周期之间的等待时长,或何时触发 Tick 事件。值为 750 时,将通知计时器等待四分之三秒(750 毫秒)后触发 Tick 事件。只有在玩家选择第二个标签后,你才能调用 Start() 方法启动计时器。
选择 Windows 窗体设计器中的计时器控件,然后按 Enter 键或双击该计时器,以添加空的**“Tick”**事件处理程序。用下列代码替换该代码,或手动将下列代码输入到事件处理程序。
''' <summary> ''' This timer is started when the player clicks ''' two icons that don't match, ''' so it counts three quarters of a second ''' and then turns itself off and hides both icons ''' </summary> ''' <remarks></remarks> Private Sub Timer1_Tick() Handles Timer1.Tick ' Stop the timer Timer1.Stop() ' Hide both icons firstClicked.ForeColor = firstClicked.BackColor secondClicked.ForeColor = secondClicked.BackColor ' Reset firstClicked and secondClicked ' so the next time a label is ' clicked, the program knows it's the first click firstClicked = Nothing secondClicked = Nothing End Sub
/// <summary> /// This timer is started when the player clicks /// two icons that don't match, /// so it counts three quarters of a second /// and then turns itself off and hides both icons /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timer1_Tick(object sender, EventArgs e) { // Stop the timer timer1.Stop(); // Hide both icons firstClicked.ForeColor = firstClicked.BackColor; secondClicked.ForeColor = secondClicked.BackColor; // Reset firstClicked and secondClicked // so the next time a label is // clicked, the program knows it's the first click firstClicked = null; secondClicked = null; }
Tick 事件处理程序将执行三个操作:首先,通过调用 Stop() 方法确保计时器没有运行。然后,它使用两个引用变量 firstClicked 和 secondClicked,使得玩家选择的两个标签的图标再次不可见。最后,它将 firstClicked 和 secondClicked 引用变量重置为 null(Visual C# 中)或 Nothing(Visual Basic 中)。这一步很重要,因为程序本身就是这样重置的。现在,它不跟踪任何 Label 控件,并已准备好让玩家再次选择图标。
说明 Timer 对象具有 Start() 方法和 Stop() 方法,分别用以启动和停止计时器。如果你在“属性”窗口中将计时器的“Enabled”属性设置为“True”,则只要程序开始运行,计时器就会开始计时。但是,如果保留该属性的设置“False”,则计时器将在 Start() 方法调用之后开始计时。通常,计时器会使用“Interval”属性确定在计时周期之间等待的毫秒数,从而反复触发其 Tick 事件。你可能已经注意到在 Tick 事件中调用计时器的 Stop() 方法的方式。这会将计时器置于“单触发模式”,意味着 Start() 方法调用时,计时器会等待指定的间隔时间,触发单个 Tick 事件,然后停止。
若要查看正在使用的新计时器,请转至代码编辑器,将以下代码添加到 label_Click() 事件处理程序方法的顶部和底部。(你要将 if 语句添加到顶部,将三个语句添加到底部;该方法的其余部分保持相同。)
''' <summary> ''' Every label's Click event is handled by this event handler ''' </summary> ''' <param name="sender">The label that was clicked</param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub label_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label9.Click, Label8.Click, Label7.Click, Label6.Click, Label5.Click, Label4.Click, Label3.Click, Label2.Click, Label16.Click, Label15.Click, Label14.Click, Label13.Click, Label12.Click, Label11.Click, Label10.Click, Label1.Click ' The timer is only on after two non-matching ' icons have been shown to the player, ' so ignore any clicks if the timer is running If Timer1.Enabled Then Exit Sub Dim clickedLabel = TryCast(sender, Label) If clickedLabel IsNot Nothing Then ' If the clicked label is black, the player clicked ' an icon that's already been revealed -- ' ignore the click If clickedLabel.ForeColor = Color.Black Then Exit Sub ' If firstClicked is Nothing, this is the first icon ' in the pair that the player clicked, ' so set firstClicked to the label that the player ' clicked, change its color to black, and return If firstClicked Is Nothing Then firstClicked = clickedLabel firstClicked.ForeColor = Color.Black Exit Sub End If ' If the player gets this far, the timer isn't ' running and firstClicked isn't Nothing, ' so this must be the second icon the player clicked ' Set its color to black secondClicked = clickedLabel secondClicked.ForeColor = Color.Black ' If the player gets this far, the player ' clicked two different icons, so start the ' timer (which will wait three quarters of ' a second, and then hide the icons) Timer1.Start() End If End Sub
/// <summary> /// Every label's Click event is handled by this event handler /// </summary> /// <param name="sender">The label that was clicked</param> /// <param name="e"></param> private void label_Click(object sender, EventArgs e) { // The timer is only on after two non-matching // icons have been shown to the player, // so ignore any clicks if the timer is running if (timer1.Enabled == true) return; Label clickedLabel = sender as Label; if (clickedLabel != null) { // If the clicked label is black, the player clicked // an icon that's already been revealed -- // ignore the click if (clickedLabel.ForeColor == Color.Black) return; // If firstClicked is null, this is the first icon // in the pair that the player clicked, // so set firstClicked to the label that the player // clicked, change its color to black, and return if (firstClicked == null) { firstClicked = clickedLabel; firstClicked.ForeColor = Color.Black; return; } // If the player gets this far, the timer isn't // running and firstClicked isn't null, // so this must be the second icon the player clicked // Set its color to black secondClicked = clickedLabel; secondClicked.ForeColor = Color.Black; // If the player gets this far, the player // clicked two different icons, so start the // timer (which will wait three quarters of // a second, and then hide the icons) timer1.Start(); } }
该方法顶部的代码通过检查**“Enabled”**属性的值来检查计时器是否已启动。这样,如果玩家选择第一个和第二个 Label 控件,且计时器启动,则选择第三个控件将不会执行任何操作。
该方法底部的代码将 secondClicked 引用变量设置为跟踪玩家选择的第二个 Label 控件,然后将该标签的图标颜色设置为黑色以使其可见。然后,它在单触发模式下启动计时器,以便在等待 750 毫秒后触发单个 Tick 事件。计时器的 Tick 事件处理程序会隐藏这两个图标,并重置 firstClicked 和 secondClicked 引用变量,以便窗体准备就绪以供玩家选择另一对图标。
保存并运行程序。选择一个图标,它将显示出来。
选择另一个图标。它会短暂显示,然后两个图标都消失。多次重复此操作。窗体现在跟踪你选择的第一个和第二个图标,并使用计时器在使图标消失之前暂停。
继续或查看
若要转到下一个教程步骤,请参阅Step 7: Keep Pairs Visible。
若要返回上一个教程步骤,请参阅Step 5: Add Label References。