背景:我正试图用Visual Basic制作一款类似《Flappy bird》的游戏,以熟悉这门语言(我将在未来2年内使用它编写代码,我真的没有选择)。
问题在于管道的连续运动。管道每1200ms生成一次。游戏检查标记为"pipe"
和"score"
的每个控件,并基于另一个间隔为60ms的计时器移动它。gameloop
定时器代码:
Private Sub gameloop_Tick(sender As Object, e As EventArgs) Handles gameloop.Tick
' continuous movements
player.Top += 10
For Each c As Control In Controls
If c.Tag = "pipe" Or c.Tag = "score" Then
If c.Left < -40 Then ' checking if it's off screen, then removing it if so
Controls.Remove(c)
Else ' if it's on screen, move it towards the player
c.Left -= 10
End If
End If
If c.Tag = "collider" Or c.Tag = "pipe" Then ' checking for collision
If player.Bounds.IntersectsWith(c.Bounds) Then
resetgame()
End If
End If
If c.Tag = "score" Then ' scoring if player goes between
If player.Bounds.IntersectsWith(c.Bounds) Then
Controls.Remove(c)
score += 1
scorelabel.Text = "Score: " & score
End If
End If
Next
End Sub
底部管道和计分区都是同步移动的,但顶部管道似乎有点滞后(所有3个管道都应该一起移动),并且随着游戏的进行变得越来越糟糕。评分区用粉红色表示,以便清晰。
我不确定是什么导致了这个问题。我检查了gameloop
和pipegen
计时器的运行时间,它们的代码都在计时器间隔内执行得很好。我还尝试用case语句替换逻辑,但它仍然没有改变去同步。我个人在网上找不到任何与此相关的东西。这是一个问题与图片框,VB或我犯了一个愚蠢的错误(这是完全可能的,我是非常新的语言)。
这是pastebin的完整代码。
谢谢!
我在代码中犯的主要错误是从数组中删除,而循环遍历它。相反,我制作了一个要删除的控件列表,然后循环执行:
' game logic
Private Sub gameloop_Tick(sender As Object, e As EventArgs) Handles gameloop.Tick
' list of things to remove
Dim removethese As New List(Of Control)
' continuous movements
player.Top += 10
For Each c As Control In Controls
If c.Tag = "pipe" Or c.Tag = "score" Then
If c.Left < -40 Then ' checking if it's off screen, then removing it if so
removethese.Add(c)
Else ' if it's on screen, just move it towards the player
c.Left -= 10
End If
End If
If c.Tag = "collider" Or c.Tag = "pipe" Then ' checking for collision
If player.Bounds.IntersectsWith(c.Bounds) Then
resetgame()
End If
End If
If c.Tag = "score" Then ' scoring if player goes between
If player.Bounds.IntersectsWith(c.Bounds) Then
removethese.Add(c)
score += 1
scorelabel.Text = "Score: " & score
End If
End If
Next
For Each c As Control In removethese
Controls.Remove(c)
Next
End Sub
所有的管道现在都同步移动,所以我对destroy()
函数做了同样的事情,我不再需要调用它3次才能工作。
Public Sub destroy()
' list of things to remove
Dim temp As New List(Of Control)
' collecting controls to remove
For Each c As Control In Controls
If c.Tag = "pipe" Or c.Tag = "score" Then
temp.Add(c)
End If
Next
' removing controls
For Each c As Control In temp
Controls.Remove(c)
Next
End Sub