Handles ShowScorToolStripMenuItem.Click
Dim frm As Form2 = New Form2
frm.Show()
frm.drawTable()
End Sub
В меню Очки дважды щёлкаем по команде Рассчитать средние (для элемента управления MenuStrip). Появляется шаблон метода, который после записи нашего кода принимает следующий вид.
Листинг 21.7. Метод-обработчик щелчка по элементу.
Private Sub CalculateAvgToolStripMenuItem_Click( _
ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles CalculateAvgToolStripMenuItem.Click
Dim strnewL = Chr(13) + Chr(10)
Dim avg As Double = DDScore.number / DDTime.number
Dim s As String = FormatNumber(avg, 3)
Dim h As New System.IntPtr
MessageBox.Show("Очки : " + DDScore.number.ToString + _
" " + "(очков)" + strnewL _
+ "Время : " + DDTime.number.ToString + " " + "(сек)" + _
strnewL + "Среднее значение : " + s + " " + _
"(очков/сек)", "Среднее значение очков в секунду", _
MessageBoxButtons.OK, MessageBoxIcon.None)
End Sub
В меню Помощь дважды щёлкаем по команде О программе (для элемента управления MenuStrip). Появляется шаблон метода, который после записи нашего кода принимает следующий вид.
Листинг 21.8. Метод-обработчик выбора команды.
Private Sub AboutToolStripMenuItem_Click( _
ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles AboutToolStripMenuItem.Click
Dim frm As New Form3
frm.Show()
End Sub
Схема записи и вывода справочной информации, например, с правилами игры после выбора команды Справка (для элемента управления MenuStrip) и после выбора других команд уже приводилась в наших предыдущих работах.
Мы закончили написание программы в главный класс Form1 (для формы Form1 с пользовательским интерфейсом игры).
Теперь в наш проект добавляем новые файлы (для программирования соответствующих игровых действий). Добавить в проект файл можно по двум вариантам.
По первому варианту, добавляем в проект нужный файл по обычной схеме: в панели Solution Explorer выполняем правый щелчок по имени проекта, в контекстном меню выбираем Add, Existing Item, в панели Add Existing Item в окне Files of type выбираем All Files, в центральном окне находим (например, в папке компьютера файл, скопированный из Интернета), выделяем имя этого файла и щёлкаем кнопку Add (или дважды щёлкаем по имени этого файла).
По второму варианту, в панели Solution Explorer выполняем правый щелчок по имени проекта и в контекстном меню выбираем Add, New Item, в панели Add New Item выделяем шаблон Code File, в окне Name записываем имя DPaint.vb и щёлкаем кнопку Add. В проект (и в панель Solution Explorer) добавляется этот файл, открывается пустое окно редактирования кода, в которое записываем код со следующего листинга.
Листинг 21.9. Новый файл.
Public Class DPaint
Private _number As String
Private _position As Point
Private _color As Color
Private _pen As Pen
Private _thick As Integer
Private _width As Integer
Private _brush As SolidBrush
#Region "Property Declaration"
Public Sub New()
'_color = Color.Yellow
'Для большей чёткости задаём красный цвет цифр для очков
'и времени:
_color = Color.Red
_brush = New SolidBrush(_color)
_number = 0
End Sub
Public Sub New(ByVal number As Integer)
Me.number = number
_color = Color.Yellow
_brush = New SolidBrush(_color)
End Sub
Public Property number() As Double
Get
Return CDbl(_number)
End Get
Set(ByVal Value As Double)
_number = Value.ToString
_number = _number.PadLeft(8, "0")
End Set
End Property
Public Property position() As Point
Get
Return _position
End Get
Set(ByVal Value As Point)
_position = Value
End Set
End Property
Public Property thick() As Integer
Get
Return _thick
End Get
Set(ByVal Value As Integer)
_thick = Value
End Set
End Property
Public Property width() As Integer
Get
Return _width
End Get
Set(ByVal Value As Integer)
_width = Value
End Set
End Property
#End Region
#Region "Show digital Number"
Private Function conPol(ByVal i As Integer) As Point()
Dim c, h As Integer
Dim x As Integer = _position.X
Dim y As Integer = _position.Y
Dim poly(3) As Point
Select Case i
Case 1
c = x
h = y _width 2
poly(0).X = c
poly(0).Y = h
poly(1).X = c + _width
poly(1).Y = h
poly(2).X = c + _width _thick
poly(2).Y = h + _thick
poly(3).X = c + _thick
poly(3).Y = h + _thick
Return poly
Case 2
c = x + _width
h = y _width 1
poly(0).X = c
poly(0).Y = h
poly(1).X = c
poly(1).Y = h + _width
poly(2).X = c _thick
poly(2).Y = h + _width _thick / 2
poly(3).X = c _thick
poly(3).Y = h + _thick
Return poly
Case 3
c = x + _width
h = y + 1
poly(0).X = c
poly(0).Y = h
poly(1).X = c
poly(1).Y = h + _width
poly(2).X = c _thick
poly(2).Y = h + _width _thick
poly(3).X = c _thick
poly(3).Y = h + _thick / 2
Return poly
Case 4
c = x + _width
h = y + _width + 2
poly(0).X = c
poly(0).Y = h
poly(1).X = c _width
poly(1).Y = h
poly(2).X = c _width + _thick
poly(2).Y = h _thick
poly(3).X = c _thick
poly(3).Y = h _thick
Return poly
Case 5
c = x
h = y + _width + 1
poly(0).X = c
poly(0).Y = h
poly(1).X = c
poly(1).Y = h _width
poly(2).X = c + _thick
poly(2).Y = h _width + _thick / 2
poly(3).X = c + _thick
poly(3).Y = h _thick
Return poly
Case 6
c = x
h = y 1
poly(0).X = c
poly(0).Y = h
poly(1).X = c
poly(1).Y = h _width
poly(2).X = c + _thick
poly(2).Y = h _width + _thick
poly(3).X = c + _thick
poly(3).Y = h _thick / 2
Return poly
Case 7
ReDim poly(5)
c = x
h = y
poly(0).X = c
poly(0).Y = h
poly(1).X = c + _thick
poly(1).Y = h _thick / 2
poly(2).X = c + _width _thick
poly(2).Y = h _thick / 2
poly(3).X = c + _width
poly(3).Y = h
poly(4).X = c + _width _thick
poly(4).Y = h + _thick / 2
poly(5).X = c + _thick
poly(5).Y = h + _thick / 2
Return poly
End Select
End Function
Private Sub show(ByVal g As Graphics, ByVal led1 As Boolean, _
ByVal led2 As Boolean, ByVal led3 As Boolean, _
ByVal led4 As Boolean, ByVal led5 As Boolean, _
ByVal led6 As Boolean, ByVal led7 As Boolean)
led(g, 1, led1)
led(g, 2, led2)
led(g, 3, led3)
led(g, 4, led4)
led(g, 5, led5)
led(g, 6, led6)
led(g, 7, led7)
End Sub
Private Sub led(ByVal g As Graphics, ByVal led As Integer, _
ByVal sta As Boolean)
If (sta) Then
g.FillPolygon(_brush, conPol(led))
End If
End Sub
Private Sub showANum(ByVal g As Graphics, ByVal num As Integer)
Select Case num
Case 0
show(g, True, True, True, True, True, True, False)
Case 1
show(g, False, True, True, False, False, False, False)
Case 2
show(g, True, True, False, True, True, False, True)
Case 3
show(g, True, True, True, True, False, False, True)
Case 4
show(g, False, True, True, False, False, True, True)
Case 5
show(g, True, False, True, True, False, True, True)
Case 6
show(g, True, False, True, True, True, True, True)
Case 7
show(g, True, True, True, False, False, False, False)
Case 8
show(g, True, True, True, True, True, True, True)
Case 9
show(g, True, True, True, True, False, True, True)
End Select
End Sub
Public Sub showNumber(ByVal g As Graphics)
Dim tempnum As Integer
Dim tempPos As Point = _position
For i As Integer = 0 To _number.Length 1
tempnum = _number.Substring(i, 1)
showANum(g, CInt(tempnum))
_position.X += _width + 2
Next
_position = tempPos
End Sub
#End Region
#Region "Show Time"
Private Sub show2Points(ByVal g As Graphics)
Dim r1 As Integer = _position.Y + _width / 2 2
Dim r2 As Integer = _position.Y _width / 2 2
Dim c As Integer = _position.X + _width / 2 2
g.FillEllipse(_brush, c, r1, _width \ 3, _width \ 3)
g.FillEllipse(_brush, c, r2, _width \ 3, _width \ 3)
End Sub
Public Sub showTime(ByVal g As Graphics)
Dim num As Integer = CInt(_number)
Dim tempPos As Point = _position
Dim l As Integer = IIf(num = 3600, 8, 5)
Dim h As Integer = num \ 3600
Dim m As Integer = (num Mod 3600) \ 60
Dim s As Integer = num Mod 60
showANum(g, h \ 10)
_position.X += _width + 2
showANum(g, h Mod 10)
_position.X += _width + 2
show2Points(g)
_position.X += _width + 2
showANum(g, m \ 10)
_position.X += _width + 2
showANum(g, m Mod 10)
_position.X += _width + 2
show2Points(g)
_position.X += _width + 2
showANum(g, s \ 10)
_position.X += _width + 2
showANum(g, s Mod 10)
_position = tempPos
End Sub
#End Region
End Class
По второму варианту, в панели Solution Explorer выполняем правый щелчок по имени проекта и в контекстном меню выбираем Add, New Item, в панели Add New Item выделяем шаблон Code File, в окне Name записываем имя mModule.vb и щёлкаем кнопку Add. В проект (и в панель Solution Explorer) добавляется этот файл, открывается пустое окно редактирования кода, в которое записываем код со следующего листинга.
Листинг 21.10. Новый файл.
Public Module mModule
Private s As String = Application.StartupPath & "..\..\"
'Public ImgList() As String = {s & "BlackBall.png",
's & "M_BlackBall.png", s & "BlueBall.png" _
', s & "M_BlueBall.png", s & "GreenBall.png", s &
'"M_GreenBall.png", s & "LGreenBall.png" _
', s & "M_LGreenBall.png", s & "MagentaBall.png", s &
'"M_MagentaBall.png" _
', s & "RedBall.png", s & "M_RedBall.png"}
'Исправляем ошибку:
Public ImgList() As String = _
{"..\..\BlackBall.png", "..\..\M_BlackBall.png", _
"..\..\BlueBall.png", "..\..\M_BlueBall.png", _
"..\..\GreenBall.png", "..\..\M_GreenBall.png", _
"..\..\LGreenBall.png", "..\..\M_LGreenBall.png", _
"..\..\MagentaBall.png", "..\..\M_MagentaBall.png", _
"..\..\RedBall.png", "..\..\M_RedBall.png"}
Public Structure Player
Private _PlayerName As String
Private _PlayerScore As String
Public Sub New(ByVal PlayerName As String, _
ByVal PlayerScore As String)
_PlayerName = PlayerName
_PlayerScore = PlayerScore
End Sub
Public Property PlayerName() As String
Get
Return _PlayerName
End Get
Set(ByVal Value As String)
_PlayerName = Value
End Set
End Property
Public Property PlayerScore() As String
Get
Return _PlayerScore
End Get
Set(ByVal Value As String)
_PlayerScore = Value
End Set
End Property
End Structure
End Module
По второму варианту, в панели Solution Explorer выполняем правый щелчок по имени проекта и в контекстном меню выбираем Add, New Item, в панели Add New Item выделяем шаблон Code File, в окне Name записываем имя MotionPic.vb и щёлкаем кнопку Add. В проект (и в панель Solution Explorer) добавляется этот файл, открывается пустое окно редактирования кода, в которое записываем код со следующего листинга.
Листинг 21.11. Новый файл.
Option Strict On
Public Enum BallState
ZOOMING_BALL = -2
NO_BALL = -1
NORMAL_BALL = 0
JUMPING_BALL = 1
DESTROYING_BALL = 2
End Enum
Public Class MotionPic
Inherits System.Windows.Forms.PictureBox
Private myTimer As New System.Windows.Forms.Timer
Private picWidth As Integer
Private picHeight As Integer
Private picTop As Integer
Private picLeft As Integer
Private picState As Integer
Private picIndex As Integer
Private sign As Integer
#Region "Property Declaration"
Public Sub New(ByVal eSize As Size, ByVal eLocation As Point)
Me.Size = eSize
Me.Location = eLocation
picWidth = Me.Width
picHeight = Me.Height
picTop = Me.Top
picLeft = Me.Left
picState = BallState.NO_BALL
picIndex = -1
End Sub
Public ReadOnly Property MPState() As Integer
Get
Return picState
End Get
End Property
Public ReadOnly Property MPIndex() As Integer
Get
Return picIndex
End Get
End Property
Public Sub Init()
Me.Init(CInt(Rnd() * 12))
End Sub
#End Region
Public Sub Init(ByVal value As Integer)
picIndex = value
picState = BallState.ZOOMING_BALL
Dim i As Integer = ImgList(value).LastIndexOf("\")
Me.Tag = ImgList(value).Substring(i + 1, _
ImgList(value).Length i 5)
ZoomIn()
End Sub
Private Sub ZoomIn()
Me.Top = picTop + (picHeight 4) \ 2
Me.Left = picLeft + (picWidth 4) \ 2
Me.Width = 4
Me.Height = 4
Me.Image = Image.FromFile(ImgList(picIndex))
AddHandler myTimer.Tick, AddressOf TimerEventZoomIn
myTimer.Interval = 10
myTimer.Start()
End Sub
Private Sub TimerEventZoomIn(ByVal myObject As Object, _
ByVal myEventArgs As EventArgs)
If Me.Top > picTop And Me.Width < picWidth Then
Me.Top -= 2
Me.Left -= 2
Me.Width += 4
Me.Height += 4
Else
myTimer.Enabled = False
picState = BallState.NORMAL_BALL
RemoveHandler myTimer.Tick, AddressOf TimerEventZoomIn
End If
End Sub
Public Sub Jump()
If picState = BallState.NORMAL_BALL Then
sign = 1
picState = BallState.JUMPING_BALL
AddHandler myTimer.Tick, AddressOf TimerEventJump
myTimer.Interval = 20
myTimer.Start()
ElseIf picState = BallState.JUMPING_BALL Then
StopJump()
End If
End Sub
Public Sub StopJump()
If picState = BallState.JUMPING_BALL Then
picState = 0
myTimer.Enabled = False
RemoveHandler myTimer.Tick, AddressOf TimerEventJump
Me.Top = picTop
Me.Left = picLeft
Me.Height = picHeight
Me.Width = picWidth
End If
End Sub
Private Sub TimerEventJump(ByVal myObject As Object, _
ByVal myEventArgs As EventArgs)
Me.Height -= sign * 1
Me.Top = picTop + (Me.Height picHeight) \ 4
If Me.Height = picHeight Or Me.Height <= 3 * picHeight / 4 Then
sign *= -1
End If
End Sub
Public Sub Destroy()
If picState = BallState.JUMPING_BALL Then
StopJump()
End If
picState = BallState.DESTROYING_BALL
AddHandler myTimer.Tick, AddressOf TimerEventDestroy
Me.Top = picTop + 1
Me.Left = picLeft + 1
Me.Width = picWidth 2
Me.Height = picHeight 2
myTimer.Interval = 10
myTimer.Start()
End Sub
Private Sub TimerEventDestroy(ByVal myObject As Object, _
ByVal myEventArgs As EventArgs)
If Me.Top > picTop And Me.Width > 0 Then
Me.Top += 2
Me.Left += 2
Me.Width -= 4
Me.Height -= 4
Else
Me.Image = Nothing
Me.Top = picTop
Me.Left = picLeft
Me.Width = picWidth
Me.Height = picHeight
myTimer.Enabled = False
Me.picState = BallState.NO_BALL
Me.picIndex = -1
Me.Tag = ""
RemoveHandler myTimer.Tick, AddressOf TimerEventDestroy
End If
End Sub
Public Sub Reset()
While Me.picState = BallState.DESTROYING_BALL
Application.DoEvents()
End While
If Me.picState = BallState.JUMPING_BALL Then
StopJump()
End If
While Me.picState = BallState.ZOOMING_BALL
Application.DoEvents()
End While
Me.Image = Nothing
Me.picIndex = -1
Me.picState = BallState.NO_BALL
Me.Tag = ""
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As _
System.Windows.Forms.MouseEventArgs)
If picState = BallState.NORMAL_BALL Or _
picState = BallState.JUMPING_BALL Then
Me.Image = Image.FromFile(ImgList(picIndex + 1))
End If
End Sub
Protected Overrides Sub OnMouseLeave( _
ByVal e As System.EventArgs)
If picState = BallState.NORMAL_BALL Or picState = _
BallState.JUMPING_BALL Then
Me.Image = Image.FromFile(ImgList(picIndex))
End If
End Sub
End Class
После этих добавлений (DPaint.vb, mModule.vb, MotionPic.vb, open.ico, save.ico) в панели Solution Explorer должны быть файлы, показанные выше. Дважды щёлкая по имени файла, любой файл можно открыть, изучить и редактировать.
Теперь в наш проект добавляем переменные и методы, связанные с формой Form2 для вывода результатов игры.
Открываем файл Form2.vb (например, так: File, Open, File) и вверху записываем директивы для подключения требуемых пространств имен:
Imports System.Drawing.Drawing2D
Imports System.Drawing.Text
Imports System.IO
Теперь в классе Form2 нашего проекта записываем следующие переменные и методы.
Листинг 21.12. Переменные и методы.
Dim gr As Graphics
Dim lbrTitle As LinearGradientBrush
Dim lbrBoard As LinearGradientBrush
Dim midPoint As Point
Dim startPoint As PointF
Dim intGradiantStep As Integer = 5
Dim intCurrentGradientShift As Integer = 0
Const colW1 As Integer = 250
Const colW2 As Integer = 150
Const rowH As Integer = 30
Dim AddedPlayer As New Player("", "-1")
Dim ArrPlayer As New ArrayList
Dim intCurrentGradientRow As Integer = 110
Public WriteOnly Property AddPlayer() As Player
Set(ByVal Value As Player)
If Value.PlayerName.Length > 14 Then
Value.PlayerName = _
Value.PlayerName.Substring(0, 14)
End If
AddedPlayer = Value
End Set
End Property
Public Sub drawTable()
Me.BackgroundImage = Nothing
Me.BackColor = Color.Moccasin
Application.DoEvents()
Dim g As Graphics = CreateGraphics()
Dim tpen1 As New Pen(Color.Red, 1)
Dim tpen2 As New Pen(Color.Black, 1)
Dim P1 As New Point(2, 80)
Dim P2 As New Point(400, 80)
For i As Integer = 0 To 11
g.DrawLine(tpen1, P1, P2)
P1.Y += 1
P2.Y += 1
g.DrawLine(tpen2, P1, P2)
P1.Y += rowH 1
P2.Y += rowH 1
Next
P1.Y = 80
P2.X = P1.X
P2.Y -= rowH
g.DrawLine(tpen2, P1, P2)
P1.X += 1
P2.X += 1
g.DrawLine(tpen1, P1, P2)
P1.X += colW1
P2.X += colW1
g.DrawLine(tpen2, P1, P2)
P1.X += 1
P2.X += 1
g.DrawLine(tpen1, P1, P2)
P1.X += colW2 3
P2.X += colW2 3
g.DrawLine(tpen1, P1, P2)
P1.X += 1
P2.X += 1
g.DrawLine(tpen2, P1, P2)
SaveScore()
LoadScore()
Timer1.Enabled = True
Timer2.Enabled = True
End Sub
Public Sub LoadScore()
If Not File.Exists("Score.dat") Then
GoTo newScore
End If
Dim FSR As New StreamReader("Score.dat")
Dim s As String
s = FSR.ReadLine
If Trim(s) <> "#Assignment Line#" Then
FSR.Close()
GoTo newScore
End If
For i As Integer = 0 To 9
s = FSR.ReadLine