Обнаружение столкновений работает только на интервалах - PullRequest
0 голосов
/ 21 апреля 2020

Я делаю 2D игру. В настоящее время я сделал 5 графических блоков, один для игрока и четыре для границ экрана. Я перемещаю персонажа по экрану с помощью таймера с интервалом в одну миллисекунду. Когда срабатывает таймер, оператор if проверяет, были ли нажатия клавиш или нет. Когда Игрок сталкивается со стеной, он отбрасывает их так, как они пришли. Однако иногда игрок может случайным образом go пройти сквозь стены, как если бы они не столкнулись.

    Public Class PlayScreen
    Dim PlayerShip As New PictureBox 'defines the ship as a picture box

    Dim WallNorth As New PictureBox
    Dim WallSouth As New PictureBox
    Dim WallEast As New PictureBox 'these will be given collision detection to check if the player is trying to exit the boundires of the level
    Dim WallWest As New PictureBox

    Dim MoveRight As Boolean = False
    Dim MoveLeft As Boolean = False 'Making movement based upon boolean factors allows for more user friendly controls
    Dim MoveUp As Boolean = False
    Dim MoveDown As Boolean = False
    Private Sub PlayScreen_Load(sender As Object, e As EventArgs) Handles MyBase.Load


        MovementTimer.Start()
        WallCollisionTimer.Start()

        Me.Controls.Add(PlayerShip) 'imports the picture box onto the PlayScreen
        PlayerShip.Width = 40
        PlayerShip.Height = 40 'Dimensions of the player ship
        PlayerShip.BorderStyle = BorderStyle.FixedSingle 'adds a border to the picturebox
        PlayerShip.BackColor = Color.White 'adds colour to the ship background
        PlayerShip.SetBounds(x:=40, y:=40, height:=40, width:=40)


        Me.Controls.Add(WallNorth)
        WallNorth.Width = 750
        WallNorth.Height = 5
        WallNorth.BorderStyle = BorderStyle.FixedSingle 'this is defining the wall at the top of the screen, setting its positions as well as its bounds
        WallNorth.BackColor = Color.Green
        WallNorth.Top = 1
        WallNorth.Left = 1
        WallNorth.SetBounds(x:=1, y:=1, height:=5, width:=750)

        Me.Controls.Add(WallEast)
        WallEast.Width = 5
        WallEast.Height = 750
        WallEast.BorderStyle = BorderStyle.FixedSingle 'This defines the wall at the right of the screen, setting its position as well as its bounds
        WallEast.BackColor = Color.Green
        WallEast.Top = 1
        WallEast.Left = 545
        WallEast.SetBounds(x:=545, y:=1, width:=5, height:=750)

        Me.Controls.Add(WallSouth)
        WallSouth.Width = 750
        WallSouth.Height = 5
        WallSouth.BorderStyle = BorderStyle.FixedSingle
        WallSouth.BackColor = Color.Green
        WallSouth.Top = 574
        WallSouth.Left = 1
        WallSouth.SetBounds(x:=1, y:=573, width:=750, height:=5)

        Me.Controls.Add(WallWest)
        WallWest.Width = 5
        WallWest.Height = 750
        WallWest.BorderStyle = BorderStyle.FixedSingle
        WallWest.BackColor = Color.Green
        WallWest.Top = 1
        WallWest.Left = 1

        PlayerShip.Top = Me.Height / 2
        PlayerShip.Left = Me.Width / 2 'mkes sure the picture box starts somewhat in the centre of the screen
    End Sub

    Private Sub PlayScreen_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
        Select Case e.KeyValue
            Case Keys.Right
                MoveRight = True
            Case Keys.Left
                MoveLeft = True  'This edits the boolean value of the varibales when the correct key is pressed
            Case Keys.Up
                MoveUp = True
            Case Keys.Down
                MoveDown = True
        End Select

        While WallNorth.Bounds.IntersectsWith(PlayerShip.Bounds)
            PlayerShip.Top += 75
        End While

        While WallEast.Bounds.IntersectsWith(PlayerShip.Bounds)
            PlayerShip.Left -= 75
        End While

        While WallSouth.Bounds.IntersectsWith(PlayerShip.Bounds)
            PlayerShip.Top -= 75
        End While

        While WallWest.Bounds.IntersectsWith(PlayerShip.Bounds)
            PlayerShip.Left += 75
        End While
    End Sub

    Private Sub PlayScreen_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
        Select Case e.KeyValue
            Case Keys.Right
                MoveRight = False
            Case Keys.Left
                MoveLeft = False 'This edits the boolean value when the key has been lifted
            Case Keys.Up
                MoveUp = False
            Case Keys.Down
                MoveDown = False
        End Select
    End Sub

    Private Sub MovementTimer_Tick(sender As Object, e As EventArgs) Handles MovementTimer.Tick


        If MoveRight = True Then
            PlayerShip.Left += 5
        End If
        If MoveLeft = True Then
            PlayerShip.Left -= 5
        End If
        If MoveUp = True Then
            PlayerShip.Top -= 5 ' I use a timer to tick every 10 milliseconds ato check the states of each key, this statement controlls the execution of the direction
        End If
        If MoveDown = True Then
            PlayerShip.Top += 5
        End If

    End Sub


End Class
...