当单击某个按钮时,尝试更改标签中的图像
我正在为我的 Visual Basic 课程创建一个游戏.
到目前为止,我已经成功了,除了在我的标签网格上移动.我有一个用于主地图的 16, 21 标签网格.
I am creating a game for my Visual Basic class.
So far I have been successful, except for movement on my label grid. I have a 16, 21 Label grid that I am using for the main map.
X 轴是数字 1-21,Y 轴是字母 A-P.所以左上角的Label被命名为A1,右下角的Label被命名为P21.
玩家从标签 P11 开始,并有一个箭头图像指示他们的位置.
The X axis is numeric 1-21 and the Y axis is letters A-P. So the upper left Label is named A1 and the bottom right Label is named P21.
The player starts on Label P11 and has an image of an arrow indicating their location.
我也有向上、向下、向左、向右按钮.当我按下向上按钮时,我希望图像将自身移动到 O11,或上面的标签.
我有一个解决方案,但是代码量很大,单单向上按钮就有1600多行代码,我觉得有点过分了.
I also have an up, down, left, right buttons as well. When I press the up Button, I want the image to move itself to O11, or the above Label.
I have a solution, but it is very code extensive, and the up Button alone is 1600+ line of code, which I think is a little excessive.
我声明的变量和初始起始标签:
My variables that I declared and the initial starting Label:
Public Letters As New List(Of String)
Public Shared x = 15
Public Shared locationLetter As String
Public Shared locationNumber As Integer = 11
Public Shared locationPlayer As String
'Put player's ship in starting grid P11
P11.Image = My.Resources.Arrow
此代码循环遍历每个标签,然后找到具有图像的标签,然后将其 Image
属性设置为空.
它还会将玩家位置更改为应有的位置,在这种情况下,我希望图像从 P11 转到 O11.
This code loops through each Label and then finds the one that has the image and then sets its Image
property to nothing.
It also changes the players location to what it should be, in this case I want the image to go from P11 to O11.
Dim nextMove As String
Controls.Find(locationPlayer)
For Each lbl As Label In Controls.OfType(Of Label)
If lbl.Image IsNot Nothing And x >= 0 Then
x -= 1
lbl.Image = Nothing
locationLetter = Letters.Item(x)
locationPlayer = CStr(locationLetter & locationNumber)
If lbl.Name = locationPlayer Then
lbl.Image = My.Resources.Arrow
End If
End If
Next
这行代码将适当的字母添加到字母列表中,以便我可以调用它来连接以找到玩家应该在的当前位置:
This line of code adds the appropriate letters to the Letters list, so that I can call up it to concatenate to find the current position the player should be in:
Letters.Add("A") ' 0 position
Letters.Add("B") ' 1 position
Letters.Add("C") ' 2 position
Letters.Add("D") ' 3 position
Letters.Add("E") ' 4 position
Letters.Add("F") ' 5 position
Letters.Add("G") ' 6 position
Letters.Add("H") ' 7 position
Letters.Add("I") ' 8 position
Letters.Add("J") ' 9 position
Letters.Add("K") ' 10 position
Letters.Add("L") ' 11 position
Letters.Add("M") ' 12 position
Letters.Add("N") ' 13 position
Letters.Add("O") ' 14 position
Letters.Add("P") ' 15 position
locationLetter = Letters.Item(15)
我现在有的代码可以正常工作,但太过分了:
The code that I have now that is working, but is way excessive is:
If P1.Tag = "player" Then
O1.Tag = "player"
O1.Image = My.Resources.Arrow
P1.Tag = ""
P1.Image = Nothing
btnDOWN.Enabled = True
btnLEFT.Enabled = False
ElseIf P2.Tag = "player" Then
O2.Tag = "player"
O2.Image = My.Resources.Arrow
P2.Tag = ""
P2.Image = Nothing
btnDOWN.Enabled = True
ElseIf P3.Tag = "player" Then
O3.Tag = "player"
O3.Image = My.Resources.Arrow
P3.Tag = ""
P3.Image = Nothing
btnDOWN.Enabled = True
'[...]
End If
等等.我必须为每个按钮都这样做,所以这是 336 个块 x4 按钮,或者大约 6,720 行代码来将图像移动到另一个框.我的伪代码是:
And so on. I would have to do this for every single Button, so that's 336 blocks x4 Buttons, or roughly 6,720 lines of code to move an image to another box. My pseudo code for this is:
If playerlocation = (some grid number, like P11 for example)
Find the label with the name = to playerlocation and add image to label
i.e.
so if playerlocation = D4
find the label with the name D4 and add the image to the label
程序化编程很好!
一些半 OOP:
Procedural programming is good!
Some semi-OOP:
对您所说的需要的描述:
A description of what you said you need:
一块板
- 它有尺寸;
- 包含一个数组,比如说,单元格(它们有自己的属性);
- 必须允许虚拟玩家在其单元上移动;
A Board
- it has Dimensions;
- contains a array of, lets say, Cells (which have their own properties);
- has to allow the movement of a dummy player over its Cells;
玩家:
- 它有一个位置
- 图片是其位置的视觉表达;
- 一个动作范围:可以移动并且只能在单元格的范围内移动董事会定义
构建 Board 对象(当然):
A Player:
- It has a position
- a picture which is the visual expression of its position;
- an action range: can move and only inside the range of the Cells that
the Board defines
Building a Board object (of course):
Public Class GameBoard
Private _BoardSize As New Size 'Board size
Private _CellsArray As BoardCell(,) 'The Cells array
Private _PlayerDummy As PlayerDummy
Private _Cells As BoardCell
Private _cell As BoardCell
Private _Location As Point
Private _Container As Control
Private _PlayerPosition As Point 'Current or default position of the player
Private _PlayerImage As Image 'Player dummy Image
Private _Initialized As Boolean = False
'The BoardSize defaults to 21x15
Public Sub New()
Me.New(New Size(0, 0))
End Sub
Public Sub New(_size As Size)
Me._BoardSize = _size
Me._cell = New BoardCell
Me._cell.Size = New Size(50, 50)
Me._PlayerDummy = New PlayerDummy
End Sub
Friend Property BoardSize() As Size
Get
Return Me._BoardSize
End Get
Set(ByVal value As Size)
Me._BoardSize = value
End Set
End Property
Friend Property Cell() As BoardCell
Get
Return Me._cell
End Get
Set(ByVal value As BoardCell)
Me._cell = value
End Set
End Property
Friend ReadOnly Property Cells(_id As Point) As BoardCell
Get
Return Me._CellsArray(_id.X, _id.Y)
End Get
End Property
Public Property Container() As Control
Get
Return _Container
End Get
Set(ByVal value As Control)
_Container = value
Me._PlayerDummy.Parent = value
End Set
End Property
Public Property Location() As Point
Get
Return _Location
End Get
Set(ByVal value As Point)
_Location = value
End Set
End Property
Public Property PlayerPosition() As Point
Get
Return Me._PlayerPosition
End Get
Set(value As Point)
If Me._Initialized = True Then
'If a player position changes, move the dummy image in the new Cell
If Me._PlayerPosition <> value Then
Me._PlayerPosition = value
Me._PlayerDummy.Location = Me._CellsArray(value.X, value.Y).Location
End If
End If
End Set
End Property
Public Property PlayerImage() As Image
Get
Return Me._PlayerImage
End Get
Set(value As Image)
Me._PlayerImage = New Bitmap(value)
Me._PlayerDummy.Image = Me.PlayerImage
End Set
End Property
'Dimension (0, 0) is used to show Rows/Columns headers
Public Sub Initialize(_size As Size)
Me._BoardSize = _size
'Defines the number of Cells
Me._CellsArray = New BoardCell(_size.Width, _size.Height) {}
'Add Cells classes per dimensions(x, y)
Dim x As Integer = 0
While x <= _BoardSize.Width
Dim y As Integer = 0
While y <= _BoardSize.Height
Me._CellsArray(x, y) = CreateBoardCell()
y += 1
End While
x += 1
End While
'Paint the Board
For x = 0 To Me._BoardSize.Width
For y = 0 To Me._BoardSize.Height
Dim _position As Point = New Point(x, y)
If x > 0 And y = 0 Then
Me.Cells(_position).Text = x.ToString
Me.Cells(_position).BackColor = Color.FromArgb(32, 32, 32)
Me.Cells(_position).ForeColor = Color.White
End If
If y > 0 And x = 0 Then
Me.Cells(_position).Text = Chr(y + 64).ToString
Me.Cells(_position).BackColor = Color.FromArgb(32, 32, 32)
Me.Cells(_position).ForeColor = Color.White
End If
Me.Cells(_position).Location = New Point(Me._Location.X + x * Me.Cell.Size.Width, _
Me._Location.Y + y * Me.Cell.Size.Height)
Me.Cells(_position).Parent = Me.Container
Next
Next
Me.Cells(New Point(0, 0)).BorderStyle = BorderStyle.None
Me.Cells(New Point(0, 0)).BackColor = Me.Container.BackColor
Me._Initialized = True
End Sub
Private Function CreateBoardCell() As BoardCell
Dim _boardcell As BoardCell = New BoardCell
_boardcell.Size = Me._cell.Size
_boardcell.BackColor = Me._cell.BackColor
_boardcell.BorderStyle = Me._cell.BorderStyle
Me._PlayerDummy.Size = New Size(Me._cell.Size.Width - 1, Me._cell.Size.Height - 1)
Return _boardcell
End Function
'A class defining a Cell object. Inherits from Label.
'May be a Panel gives more options. Do not use PictureBoxes.
Public Class BoardCell
Inherits Label
Public Sub New()
'Setup default properties
Me.AutoSize = False
Me.TextAlign = ContentAlignment.MiddleCenter
Me.Visible = True
End Sub
End Class
Friend Class PlayerDummy
Inherits PictureBox
Private _Image As Image
Private _Parent As Control
Public Sub New()
Me.SizeMode = PictureBoxSizeMode.Zoom
Me.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
Me.Visible = True
End Sub
Public Shadows Property Image() As Image
Get
Return Me._Image
End Get
Set(ByVal value As Image)
MyBase.Image = value
Me._Image = value
End Set
End Property
Public Shadows Property Parent() As Control
Get
Return _Parent
End Get
Set(ByVal value As Control)
_Parent = value
MyBase.Parent = value
End Set
End Property
End Class
End Class
创建一个新的 Board,实例化它并定义它的属性
To create a new Board, instantiate it and definine its properties
MyGameBoard = New GameBoard
'Starting position to draw this GameBoard
MyGameBoard.Location = New Point(50, 50)
MyGameBoard.Cell.Size = New Size(50, 50)
MyGameBoard.Cell.BackColor = Color.Wheat
MyGameBoard.Cell.BorderStyle = BorderStyle.FixedSingle
'Define the container class (Form, Panel, PictureBox...) that will contain this Board
MyGameBoard.Container = Me
'Assign an Image to the new player object and Position it inside its Board Cell
MyGameBoard.PlayerImage = New Bitmap(My.Resources.horse2)
'Paint the Board giving it desired size
MyGameBoard.Initialize(New Size(10, 10))
现在,玩家
Public Class Player
Public Enum Direction 'Enumerates this player allowed directions
Up = 0 'Maybe it could also move diagonally
Down
Left
Right
End Enum
Private _Position As Point 'Player Position
Private _Boundaries As New Rectangle 'The Boundaries of its movements
Public Sub New()
Me.New(Nothing)
End Sub
Public Sub New(_boundaries As Rectangle)
Me._Boundaries = New Rectangle(1, 1, _boundaries.Width - 1, _boundaries.Height - 1)
End Sub
Public Property Position() As Point
Get
Return Me._Position
End Get
Set(value As Point)
'Evaluates whether the position being set violates the
'constraints imposed by the Boundaries
Me._Position.X = If(value.X > Me._Boundaries.Right, Me._Boundaries.Right, value.X)
Me._Position.X = If(value.X < Me._Boundaries.Left, Me._Boundaries.Left, value.X)
Me._Position.Y = If(value.Y > Me._Boundaries.Bottom, Me._Boundaries.Bottom, value.Y)
Me._Position.Y = If(value.Y < Me._Boundaries.Top, Me._Boundaries.Top, value.Y)
End Set
End Property
Public Property Boundaries() As Rectangle
Get
Return Me._Boundaries
End Get
Set(ByVal value As Rectangle)
Me._Boundaries = value
End Set
End Property
'Move of the Player. Evaluates if the requested action violates Boundaries
Public Function Move(_direction As Direction) As Point
Select Case _direction
Case Direction.Up
Me.Position = New Point(Me.Position.X, If(Me.Position.Y > Me._Boundaries.Top, Me.Position.Y - 1, Me.Position.Y))
Exit Select
Case Direction.Down
Me.Position = New Point(Me.Position.X, If(Me.Position.Y < Me._Boundaries.Bottom, Me.Position.Y + 1, Me.Position.Y))
Exit Select
Case Direction.Left
Me.Position = New Point(If(Me.Position.X > Me._Boundaries.Left, Me.Position.X - 1, Me.Position.X), Me.Position.Y)
Exit Select
Case Direction.Right
Me.Position = New Point(If(Me.Position.X < Me._Boundaries.Right, Me.Position.X + 1, Me.Position.X), Me.Position.Y)
Exit Select
End Select
Return Me._Position
End Function
End Class
创建一个移动边界 = 棋盘大小的新玩家
Create a new player with movement Boundaries = to the board Size
MyPlayer = New Player(New Rectangle(New Point(1, 1), MyGameBoard.BoardSize))
起始位置:
MyPlayer.Position = New Point(10, 10)
放置玩家假人
MyGameBoard.PlayerPosition = MyPlayer.Position
要移动它,只需使用 Move 方法并让董事会知道:
To move it just use the Move method and let the Board know about:
MyPlayer.Position = MyPlayer.Move(Player.Direction.Up)
MyGameBoard.PlayerPosition = MyPlayer.Position
放置一些控件,让实际的人类玩家移动假人.
Place some controls to let the actual human player move the dummy.