蛇游戏...添加蛇体功能失灵

时间:2017-06-10 09:35:47

标签: vb.net

我正在使用visual basic在visual studio中写一个蛇游戏。

比赛场地是2D盒子的PictureBoxes。 My Snake是Point类型的一维数组。蛇阵列被称为'蛇'。

当表单加载时,Snake(0)被设置为New Point(1,1)。我创建了一个子程序,根据用户按下的箭头键移动蛇。这是一个计时器。蛇(0)(蛇头)设置为等于Snake(0)+方向(方向是由用户按下的箭头键改变的变量,例如,当按下向上方向设置为x:0和y时: -1)

当蛇(0)击中一块食物时,蛇形阵列中的元素数量被设置为数组的长度。 EG(如果是蛇(0)= foodPosition那么ReDim保留蛇(snake.Length)结束如果)

我已经在定时器下创建了一个循环,使蛇的身体跟随头部(例如,蛇(2)=蛇(1)和蛇(1)=蛇(0)但不能让它工作)

代码:

Public Class frmPlayfield

    'Food Creating and Grow Snake Variables
    Dim randF As New Random

    Dim foodPointX As Integer = randF.Next(0, 32)
    Dim foodPointY As Integer = randF.Next(0, 32)

    'Play Field Variables
    Dim playMaxWidth As Integer = 32
    Dim playMaxHeight As Integer = 32
    Dim boxSize As Integer = 16                                'Size of PictureBox
    Dim boxArray(,) As PictureBox                              'PictureBox Array
    'Snake Stuff Variable
    Dim snake(1) As Point                                      'Snake array

    Dim direction As New Point(1, 0)                           'Direction for snake movement

    Private Sub frmPlayfield_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ReDim boxArray(playMaxWidth, playMaxHeight)
        For x As Integer = 0 To playMaxWidth
            For y As Integer = 0 To playMaxHeight
                boxArray(x, y) = New PictureBox
                boxArray(x, y).Width = boxSize
                boxArray(x, y).Height = boxSize
                boxArray(x, y).Top = y * boxSize
                boxArray(x, y).Left = x * boxSize
                boxArray(x, y).Visible = True
                boxArray(x, y).BackColor = Color.White
                boxArray(x, y).BorderStyle = BorderStyle.FixedSingle
                Me.Controls.Add(boxArray(x, y))
            Next
        Next
        Me.ClientSize = New Size((playMaxWidth + 1) * boxSize, (playMaxHeight + 1) * boxSize)
        snake(0) = New Point(1, 1) 'Creates snake head
        boxArray(foodPointX, foodPointY).BackColor = Color.Red
    End Sub

    Private Function createBox(x As Integer, y As Integer, bSize As Integer) As PictureBox
        Dim tempBox As New PictureBox
        tempBox.Width = bSize
        tempBox.Height = bSize
        tempBox.Top = y * bSize
        tempBox.Left = x * bSize
        tempBox.Visible = True
        tempBox.BackColor = Color.White
        tempBox.BorderStyle = BorderStyle.FixedSingle
        Me.Controls.Add(tempBox)
        Return tempBox
    End Function

    Private Sub Food()
        If snake(0).X = foodPointX And snake(0).Y = foodPointY Then
            ReDim Preserve snake(snake.Length)                           'Increases the amount of elements in the snake array.
            For j As Integer = 0 To 0
                foodPointX = randF.Next(0, 32)
                foodPointY = randF.Next(0, 32)
                boxArray(foodPointX, foodPointY).BackColor = Color.Red
            Next
        End If
        For h As Integer = snake.Length - 1 To snake.GetUpperBound(0)
            snake(h) = snake(snake.Length - 2)
        Next
    End Sub

    Private Sub CheckBoundsAndMovement()
        For i As Integer = 0 To snake.GetUpperBound(0)
            boxArray(snake(i).X, snake(i).Y).BackColor = Color.White 'Loop to change the whole snake black
        Next
        snake(1) = snake(0)
        snake(0) = snake(0) + direction
        If snake(0).X > playMaxWidth Then
            snake(0).X -= (playMaxWidth + 1)
        End If
        If snake(0).X < 0 Then
            snake(0).X += (playMaxWidth + 1)
        End If                                                       'Four If statements to check if the snake has gone outside the play area.
        If snake(0).Y > playMaxWidth Then
            snake(0).Y -= (playMaxWidth + 1)
        End If
        If snake(0).Y < 0 Then
            snake(0).Y += (playMaxWidth + 1)
        End If
        For k As Integer = 0 To snake.GetUpperBound(0)
            boxArray(snake(k).X, snake(k).Y).BackColor = Color.Black 'Loop to make the whole snake black
        Next
    End Sub

    Private Sub timGameTick_Tick(sender As Object, e As EventArgs) Handles timGameTick.Tick
        Food()
        CheckBoundsAndMovement()
    End Sub

    Private Sub frmPlayfield_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown 'Subroutine for direction
        Select Case (e.KeyCode)
            Case Keys.Up
                direction = New Point(0, -1)
            Case Keys.Down
                direction = New Point(0, 1)
            Case Keys.Left
                direction = New Point(-1, 0)
            Case Keys.Right
                direction = New Point(1, 0)
        End Select
    End Sub
End Class

吃完第一块食物后,这种方法很好。长度为2的蛇的长度增加到3个。但是当我吃另一块食物时,蛇的末端留在食物被吃掉的地方。

1 个答案:

答案 0 :(得分:0)

好的 - 看起来我发现了问题 -

首先关闭 - 您将snake数组定义为Dim snake (1) As Point这创建了具有两个元素的数组,而不是1

接下来,在你的Food sub中,每次蛇移动时都应该循环将像素卷回蛇身上,而不仅仅是在食用食物时。所以我将它移动到CheckBoundsAndMovement子中以替换该子线的第4行,该线仅将头部的位置复制到下一个点而不是整个蛇。但是当然,当蛇的长度只有一个像素时尝试执行循环会导致数组超出范围异常,所以添加If语句只在snake长度执行循环{} 1}}超过1.

此外,代码中循环的方向也在递增。要正确地做它应该按递减顺序。这样,循环覆盖表示尾部结束的点,下一个点向前,依此类推。最后,将头部的新位置输入snake(0)

所以 - 这里是 -

Public Class frmPlayfield
    'Food Creating and Grow Snake Variables
    Dim randF As New Random

    Dim foodPointX As Integer = randF.Next(0, 32)
    Dim foodPointY As Integer = randF.Next(0, 32)

    'Play Field Variables
    Dim playMaxWidth As Integer = 32
    Dim playMaxHeight As Integer = 32
    Dim boxSize As Integer = 16                                'Size of PictureBox
    Dim boxArray(,) As PictureBox                              'PictureBox Array
    'Snake Stuff Variable
    Dim snake(0) As Point                                      'Snake array
    Dim direction As New Point(1, 0)                           'Direction for snake movement

    Private Sub frmPlayfield_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ReDim boxArray(playMaxWidth, playMaxHeight)
        For x As Integer = 0 To playMaxWidth
            For y As Integer = 0 To playMaxHeight
                boxArray(x, y) = New PictureBox
                boxArray(x, y).Width = boxSize
                boxArray(x, y).Height = boxSize
                boxArray(x, y).Top = y * boxSize
                boxArray(x, y).Left = x * boxSize
                boxArray(x, y).Visible = True
                boxArray(x, y).BackColor = Color.White
                boxArray(x, y).BorderStyle = BorderStyle.FixedSingle
                Me.Controls.Add(boxArray(x, y))
            Next
        Next
        Me.ClientSize = New Size((playMaxWidth + 1) * boxSize, (playMaxHeight + 1) * boxSize)
        snake(0) = New Point(1, 1) 'Creates snake head
        boxArray(foodPointX, foodPointY).BackColor = Color.Red
    End Sub

    Private Function createBox(x As Integer, y As Integer, bSize As Integer) As PictureBox
        Dim tempBox As New PictureBox
        tempBox.Width = bSize
        tempBox.Height = bSize
        tempBox.Top = y * bSize
        tempBox.Left = x * bSize
        tempBox.Visible = True
        tempBox.BackColor = Color.White
        tempBox.BorderStyle = BorderStyle.FixedSingle
        Me.Controls.Add(tempBox)
        Return tempBox
    End Function

    Private Sub Food()
        If snake(0).X = foodPointX And snake(0).Y = foodPointY Then
            ReDim Preserve snake(snake.Length)
            foodPointX = randF.Next(0, 32)
            foodPointY = randF.Next(0, 32)
            boxArray(foodPointX, foodPointY).BackColor = Color.Red
        End If
    End Sub

    Private Sub CheckBoundsAndMovement()
        For i As Integer = 0 To snake.GetUpperBound(0)
            boxArray(snake(i).X, snake(i).Y).BackColor = Color.White 'Loop to change the whole snake white
            boxArray(snake(i).X, snake(i).Y).Update()
        Next
        If snake.Length > 1 Then
            For i As Integer = snake.GetUpperBound(0) To 1 Step -1
                snake(i) = snake(i - 1)
            Next
        End If
        snake(0) = snake(0) + direction
        If snake(0).X > playMaxWidth Then
            snake(0).X -= (playMaxWidth + 1)
        End If
        If snake(0).X < 0 Then
            snake(0).X += (playMaxWidth + 1)
        End If                                                       'Four If statements to check if the snake has gone outside the play area.
        If snake(0).Y > playMaxWidth Then
            snake(0).Y -= (playMaxWidth + 1)
        End If
        If snake(0).Y < 0 Then
            snake(0).Y += (playMaxWidth + 1)
        End If
        For k As Integer = 0 To snake.GetUpperBound(0)
            boxArray(snake(k).X, snake(k).Y).BackColor = Color.Black 'Loop to make the whole snake black
        Next
    End Sub

    Private Sub timGameTick_Tick(sender As Object, e As EventArgs) Handles timGameTick.Tick
        Food()
        CheckBoundsAndMovement()
    End Sub

    Private Sub frmPlayfield_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown 'Subroutine for direction
        Select Case (e.KeyCode)
            Case Keys.Up
                direction = New Point(0, -1)
            Case Keys.Down
                direction = New Point(0, 1)
            Case Keys.Left
                direction = New Point(-1, 0)
            Case Keys.Right
                direction = New Point(1, 0)
        End Select
    End Sub
End Class