我是一名高中生,正在做评估的基本游戏。 该游戏使棒球在玩家的屏幕上飞过,然后球员将其击退。
所有棒球都包含在图片框中,我需要能够制作无数个可以在运行时单独引用和移动的棒球。
我目前正在将图片框添加并存储在字典中。但是,每当我创建一个新的图片框并将其添加到表单中时,它就会覆盖该表单上以前创建的所有图片框。
我需要找到允许以前创建的图片框在创建新图片框时保留在窗体上的代码。
对于上下文,我在下面添加了程序的逻辑流程。
Sub,它随机确定球是在屏幕的左侧,右侧,北侧还是南侧生成。
基于上述结果,可以通过更改空白变量来设置新的“棒球”图片框。
Sub,它将其作为“值”添加到字典中,而“键”具有一个名为ballNameNumber的变量。 同时,使用key ballNameNumber将随机数设置为名为ballVelocity的字典的Value。乘以一个称为关卡的变量,该变量随游戏时间的增加而增加。
因此,在这一点上,已经创建了一个球,在3个字典中具有相同的键名,每个字典都存储其图片框值和速度。
从4个生成位置中随机选择一个的子对象,根据该值将球的方向记录到名为ballDirection的字典中,然后在该位置创建球。
所有这些子项在名为tmrGameTime(间隔500)的计时器的每次计时中按此顺序发生,格式为frmGame(大小700,700)
'Dictionaries used to log and describe the movement of the balls onscreen.
Dim spawnedBalls As Dictionary(Of Integer, PictureBox) = New Dictionary(Of Integer, PictureBox)
Dim ballVelocity As Dictionary(Of Integer, Integer) = New Dictionary(Of Integer, Integer)
Dim ballDirection As Dictionary(Of Integer, String) = New Dictionary(Of Integer, String)
'Variables used in the composition of dictionaries.
Dim ballNameNumber As Integer = 1
Dim numberOfBalls As Integer = 0
Dim level As Integer = 1
Dim ball As New Picturebox
'Turns on the game timer
Private Sub frmGame_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
tmrGameTime.Enabled = True
tmrGameTime.Start()
End Sub
'Sets values to the ball variable (must be done within a sub otherwise an error is dispayed)
Public Sub ballSetUpLeft(ByRef ballTemplate)
ballTemplate.SizeMode = PictureBoxSizeMode.StretchImage
ballTemplate.Width = 34
ballTemplate.Height = 29
ballTemplate.Top = 325
ballTemplate.Left = 55
ballTemplate.Image = My.Resources.Baseball_Sprite
End Sub
Public Sub ballSetUpRight(ByRef ballTemplate)
ballTemplate.SizeMode = PictureBoxSizeMode.StretchImage
ballTemplate.Width = 34
ballTemplate.Height = 29
ballTemplate.Top = 325
ballTemplate.Left = 593
ballTemplate.Image = My.Resources.Baseball_Sprite
End Sub
Public Sub ballSetUpTop(ByRef ballTemplate)
ballTemplate.SizeMode = PictureBoxSizeMode.StretchImage
ballTemplate.Width = 34
ballTemplate.Height = 29
ballTemplate.Top = 59
ballTemplate.Left = 333
ballTemplate.Image = My.Resources.Baseball_Sprite
End Sub
Public Sub ballSetUpBottom(ByRef ballTemplate)
ballTemplate.SizeMode = PictureBoxSizeMode.StretchImage
ballTemplate.Width = 34
ballTemplate.Height = 29
ballTemplate.Top = 574
ballTemplate.Left = 333
ballTemplate.Image = My.Resources.Baseball_Sprite
End Sub
'Generates a random speed for a spawned ball based on the level value.
Public Function generateBallSpeed(ByVal level) As Integer
Randomize()
Dim ans As Integer = (((Rnd() * 10) * level) + 1)
Return ans
End Function
'Logs the ball data into dictionaries
Public Sub createBall(ByRef spawnedBalls, ByRef ballVelocity, ByRef ballNameNumber, ByRef numberOfBalls, ByRef ballTemplate)
'Adds a new ball with name and ballTemplate values to the dictionary.
spawnedBalls.Add(ballNameNumber, ballTemplate)
Dim v As Integer = generateBallSpeed(level)
'Using the matching name, adds a velocity value to the ball
ballVelocity.Add(ballNameNumber, v)
End Sub
'Spawns ball at a specific location on the form.
Public Sub spawnBallAtPitcher()
Randomize()
Dim pitcher As Integer = Int((4 - 1 + 1) * Rnd() + 1)
Select Case pitcher
Case 1
Call ballSetUpLeft(ballTemplate)
Call createBall(spawnedBalls, ballVelocity, ballNameNumber, numberOfBalls, ballTemplate)
ballDirection.Add(ballNameNumber, "Left")
ballNameNumber += 1
Me.Controls.Add(spawnedBalls.Item(ballNameNumber - 1))
Case 2
Call ballSetUpRight(ballTemplate)
Call createBall(spawnedBalls, ballVelocity, ballNameNumber, numberOfBalls, ballTemplate)
ballDirection.Add(ballNameNumber, "Right")
ballNameNumber += 1
Me.Controls.Add(spawnedBalls.Item(ballNameNumber - 1))
Case 3
Call ballSetUpTop(ballTemplate)
Call createBall(spawnedBalls, ballVelocity, ballNameNumber, numberOfBalls, ballTemplate)
ballDirection.Add(ballNameNumber, "Top")
ballNameNumber += 1
Me.Controls.Add(spawnedBalls.Item(ballNameNumber - 1))
Case 4
Call ballSetUpBottom(ballTemplate)
Call createBall(spawnedBalls, ballVelocity, ballNameNumber, numberOfBalls, ballTemplate)
ballDirection.Add(ballNameNumber, "Down")
ballNameNumber += 1
Me.Controls.Add(spawnedBalls.Item(ballNameNumber - 1))
End Select
End Sub
'Repeatedly spawns balls
Private Sub tmrGameTime_Tick_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrGameTime.Tick
Call spawnBallAtPitcher()
End Sub
结束班级
我希望这些图片框会以随机顺序出现在我的窗体上,直到四个在不同点可见(因为其他图片框会在前一个顶部创建)。但是,将创建on picturebox,然后在生成位置之间跳转。没有收到错误消息。
答案 0 :(得分:0)
您的问题是您在代码中仅使用1个参考球。因此,每次要创建另一个球时,都可以使用新球替换前一个球。将4个过程中的代码更改为函数,然后返回新球。
'Sets values to the ball variable (must be done within a sub otherwise an error is dispayed)
Public Function ballSetUpLeft() As PictureBox
Dim newBall As New PictureBox
newBall.SizeMode = PictureBoxSizeMode.StretchImage
newBall.Width = 34
newBall.Height = 29
newBall.Top = 325
newBall.Left = 55
newBall.Image = My.Resources.Baseball_Sprite
Return newBall
End Function
Public Function ballSetUpRight() As PictureBox
Dim newBall As New PictureBox
newBall.SizeMode = PictureBoxSizeMode.StretchImage
newBall.Width = 34
newBall.Height = 29
newBall.Top = 325
newBall.Left = 593
newBall.Image = My.Resources.Baseball_Sprite
Return newBall
End Function
Public Function ballSetUpTop() As PictureBox
Dim newBall As New PictureBox
newBall.SizeMode = PictureBoxSizeMode.StretchImage
newBall.Width = 34
newBall.Height = 29
newBall.Top = 59
newBall.Left = 333
newBall.Image = My.Resources.Baseball_Sprite
Return newBall
End Function
Public Function ballSetUpBottom() As PictureBox
Dim newBall As New PictureBox
newBall.SizeMode = PictureBoxSizeMode.StretchImage
newBall.Width = 34
newBall.Height = 29
newBall.Top = 574
newBall.Left = 333
newBall.Image = My.Resources.Baseball_Sprite
Return newBall
End Function
然后更改调用函数的方式(以前是过程),如下所示:
Select Case pitcher
Case 1
Dim newBall = ballSetUpLeft()
Call createBall(spawnedBalls, ballVelocity, ballNameNumber, numberOfBalls, newBall)
ballDirection.Add(ballNameNumber, "Left")
ballNameNumber += 1
Me.Controls.Add(spawnedBalls.Item(ballNameNumber - 1))
Case 2
Dim newBall = ballSetUpRight()
Call createBall(spawnedBalls, ballVelocity, ballNameNumber, numberOfBalls, newBall)
ballDirection.Add(ballNameNumber, "Right")
ballNameNumber += 1
Me.Controls.Add(spawnedBalls.Item(ballNameNumber - 1))
Case 3
Dim newBall = ballSetUpTop()
Call createBall(spawnedBalls, ballVelocity, ballNameNumber, numberOfBalls, newBall)
ballDirection.Add(ballNameNumber, "Top")
ballNameNumber += 1
Me.Controls.Add(spawnedBalls.Item(ballNameNumber - 1))
Case 4
Dim newBall = ballSetUpBottom()
Call createBall(spawnedBalls, ballVelocity, ballNameNumber, numberOfBalls, newBall)
ballDirection.Add(ballNameNumber, "Down")
ballNameNumber += 1
Me.Controls.Add(spawnedBalls.Item(ballNameNumber - 1))
End Select
现在,您每次要创建另一个球都不会替换您的球。我离开了要给球设置动画并在投手击中球时移走球的任务。
我试图减少您代码中的冗余。这3个词典由一个单独的词典代替,该词典保存了球的信息(id,方向,速度和图片)。使用枚举而不是硬编码的数字作为方向。使用Random类而不是Randomize()和Rnd()函数。
Public Class frmGame
'Dictionaries used to log and describe the movement of the balls onscreen.
Private balls = New Dictionary(Of Integer, Ball)
'Variables used in the composition of dictionaries.
Private random As New Random
Private lastBallID As Integer
Private Const level As Integer = 1
Private Sub frmGame_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Turns on the game timer
tmrGameTime.Enabled = True
tmrGameTime.Start()
End Sub
Private Sub tmrGameTime_Tick_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrGameTime.Tick
'Repeatedly spawns balls
spawnBallAtPitcher()
End Sub
'Spawns ball at a specific location on the form.
Private Sub spawnBallAtPitcher()
lastBallID += 1
Dim pitcher As Direction = random.Next(4) + 1
Dim newBall = createBall(lastBallID, pitcher, random)
Controls.Add(newBall.Picture)
'Logs the ball data into dictionaries
balls.Add(lastBallID, newBall)
End Sub
'Create new ball, set its ID, direction, velocity and picture
Private Function createBall(ballID As Integer, direction As Direction, rnd As Random) As Ball
Return New Ball With {
.BallID = ballID,
.Direction = direction,
.Velocity = generateBallSpeed(level, rnd),
.Picture = generateBallPicture(direction)
}
End Function
'Generates a random speed for a spawned ball based on the level value.
Private Function generateBallSpeed(ByVal level As Integer, ByVal rnd As Random) As Integer
Return (rnd.Next(10) + 1) * level
End Function
'Generates a new picture of ball
Private Function generateBallPicture(direction As Direction) As PictureBox
Dim location = generatePictureLocation(direction)
Return New PictureBox With {
.SizeMode = PictureBoxSizeMode.StretchImage,
.Width = 34,
.Height = 29,
.Top = location.Y,
.Left = location.X,
.Image = My.Resources.Baseball_Sprite
}
End Function
'Generates a location for new picture of ball
Private Function generatePictureLocation(direction As Direction) As Point
Select Case direction
Case Direction.Left
Return New Point(55, 325)
Case Direction.Right
Return New Point(593, 325)
Case Direction.Top
Return New Point(333, 59)
Case Direction.Bottom
Return New Point(333, 574)
End Select
End Function
End Class
Public Enum Direction
Left = 1
Right
Top
Bottom
End Enum
Public Class Ball
Public Property BallID As Integer
Public Property Velocity As Integer
Public Property Direction As Integer
Public Property Picture As PictureBox
End Class