如何在vb.net中动态添加和操纵多个唯一的图像框



我是一名高中生,为评估提供基本游戏。该游戏使棒球在玩家击打的球员屏幕上飞行。

所有棒球都包含在图片框中,我需要能够制作一个可以单独引用和移动的无限数量。

我目前正在添加并存储词典中的词典。但是,每当我创建一个新的picturebox并将其添加到表单中时,它都会覆盖以前创建的图片框。

我需要找到允许先前创建的picturebox在创建新的代码的代码。

对于上下文,我在下面添加了程序的逻辑流。

当前程序逻辑

随机确定球是否会在屏幕的左,右,北或南侧产卵。

基于上述结果,通过更改空白变量来设置新的"棒球"图片框。

sub将其添加为字典中的值,其键是一个称为ballnamenumber的变量。同时,将随机数设置为一个名为Ballnamenumber的词典的值。这乘以一个称为级别的变量,该变量随着游戏时间的增加而增加。

因此,在这一点上,已经创建了一个球,每个词典中都有相同的关键名称,每个词典都将其picturebox值和速度存储。

随机选择4个产卵位置中的1个,根据该值记录球的方向到称为Balldirection的字典,然后在此位置创建球。

所有这些subs都以每个订单的订单出现在一个名为tmrgameTime(Interval 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

结束类

我希望pictureboxes将以随机顺序出现在我的表单上,直到在不同点可见四个(因为将在上一个上方创建任何其他phiteboxes(。但是,在图片框上创建,然后在产卵位置之间跳跃。未收到错误消息。

您的问题是您仅在代码中使用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,方向,速度和图片(。使用枚举代替硬编码数字来方向。使用随机类代替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

最新更新