球与曲线之间的碰撞作为图形对象

时间:2018-05-01 03:18:39

标签: vb.net gdi+

我正在尝试制作一个游戏,我将一个球从地面上弹出,这是一个封闭的曲线(绿色部分),我只是不知道我将如何计算球与之间的碰撞曲线。

picture of the graphics

我在图片框中使用图形绘制了球和曲线,我想我必须以数学方式进行,因为我在Visual Basic中找不到任何内置功能,让我可以这样做。

我的代码:

Public Class Form1

    Dim BallSpeedY, BallSpeedX As Double
    Dim BallLoc As Point

    Dim Start As Boolean = False

    Dim gameTime As Decimal = 60.1
    Dim gameTimeFont As New Font("Arial", 24, FontStyle.Bold)



    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Me.WindowState = FormWindowState.Maximized

        'Size of the picturebox that is being drawn on
        PictureBox1.Width = Me.Width
        PictureBox1.Height = Me.Height - 24

        DrawGame(False, False, True)

    End Sub

    Private Sub DrawGame(refreshMap As Boolean, drawBall As Boolean, drawTime As Boolean)

        Dim g As Graphics = Graphics.FromImage(PictureBox1.Image)

        Static startcornerpt As PointF
        Static firstpt As PointF
        Static pt2 As PointF
        Static pt3 As PointF
        Static pt4 As PointF
        Static pt5 As PointF
        Static lastpt As PointF
        Static Endcornerpt As PointF



        ' Clears the window
        g.Clear(Color.White)

        If refreshMap Then
            Randomize() ' The rnd seed would always be the same if this is not done

            ' Creates 5 points chosen at random positions on the window within certain parameters
            startcornerpt = New PointF(0, Me.Height)
            pt2 = New PointF(Me.Width * 0.2, Me.Height * ((39 * Rnd() + 30) / 100))
            firstpt = New PointF(0, pt2.Y * 0.5 * 2)
            pt3 = New PointF(Me.Width * 0.4, Me.Height * ((39 * Rnd() + 30) / 100))
            pt4 = New PointF(Me.Width * 0.6, Me.Height * ((39 * Rnd() + 30) / 100))
            pt5 = New PointF(Me.Width * 0.8, Me.Height * ((39 * Rnd() + 30) / 100))
            lastpt = New PointF(Me.Width, pt5.Y * 0.5 * 2)
            Endcornerpt = New PointF(Me.Width, Me.Height)
        End If

        ' Draws the map with the 5 points
        Dim curvepoints As PointF() = {startcornerpt, firstpt, pt2, pt3, pt4, pt5, lastpt, Endcornerpt}
        g.FillClosedCurve(Brushes.PaleGreen, curvepoints)




        If drawBall Then
            ' Draws the ball
            g.DrawEllipse(Pens.Blue, BallLoc.X, BallLoc.Y, 20, 20)
            g.FillEllipse(Brushes.Blue, BallLoc.X, BallLoc.Y, 20, 20)

            ' Accelerates speed
            BallSpeedY = BallSpeedY - 1

            ' Update position
            BallLoc = New Point(BallLoc.X + BallSpeedX, BallLoc.Y - BallSpeedY)



        End If

        If drawTime Then

            gameTime = gameTime - 0.1
            gameTime.ToString()

            g.DrawString(gameTime, gameTimeFont, Brushes.Black, Me.Width / 2 - 120, Me.Height * 0.025) ' Draws the gametime on screen, 
            ' Width is set to be around the middle of the screen while height is just under the strip menu.

        End If

        PictureBox1.Refresh()

    End Sub

    Private Sub StartToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles StartToolStripMenuItem.Click

        If Start = False Then

            gameTime = 60.1

            'Resets ball for testing
            BallLoc.X = 800
            BallLoc.Y = 300
            BallSpeedY = 0

            'Starts the timers
            Gravity.Start()
            Movement.Start()

            Start = True

        ElseIf Start = True Then

            ' Resets the ball
            Dim ballloc As New Point(800, 300)


            Gravity.Stop()
            Movement.Stop()

            Start = False

        End If

    End Sub

    Private Sub NewMapToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NewMapToolStripMenuItem.Click

        ' Creates a new map
        DrawGame(True, False, False)
        Start = False

    End Sub

    Private Sub Movement_Tick(sender As Object, e As EventArgs) Handles Movement.Tick

        ' Starts movement of the ball
        DrawGame(False, True, True)

    End Sub
End Class

编辑:碰撞现在适用于这些新增内容:

Dim wider = CType(ground.Clone(), GraphicsPath)
    Using widenizer As Pen = New Pen(Color.Black, ballDiameter)
        wider.Widen(widenizer)
    End Using

 If ground.IsVisible(BallLoc) OrElse wider.IsVisible(BallLoc) Then
            BallSpeedY = BallSpeedY + 50 ' rebound on collision

        End If

1 个答案:

答案 0 :(得分:0)

下面的代码说明了我添加的关于使用Widen()的评论,因此您可以使用球的中心进行测试。

自从我完成任何VB.NET以来已经很久了,但确实显示了这个想法:

Imports System.Drawing.Drawing2D

Partial Public Class Form1
    Inherits Form

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Dim diameter As Integer = 10
        Dim path As GraphicsPath = New GraphicsPath()
        path.AddCurve(New Point() {New Point(0, 100), New Point(200, 200), New Point(400, 100)})
        path.AddLines(New Point() {New Point(400, 400), New Point(0, 400)})
        path.CloseAllFigures()
        e.Graphics.FillPath(Brushes.Green, path)
        Dim wider = CType(path.Clone(), GraphicsPath)
        Using widenizer As Pen = New Pen(Color.Black, diameter)
            wider.Widen(widenizer)
        End Using

        For x As Integer = 0 To 400 Step diameter
            For y As Integer = 0 To 400 Step diameter

                If path.IsVisible(x, y) OrElse wider.IsVisible(x, y) Then
                    e.Graphics.DrawEllipse(Pens.Red, CType(x - diameter / 2, Single), CType(y - diameter / 2, Single), diameter, diameter)
                Else
                    e.Graphics.DrawEllipse(Pens.Blue, CType(x - diameter / 2, Single), CType(y - diameter / 2, Single), diameter, diameter)
                End If

            Next y
        Next x
    End Sub
End Class

它用圆圈填充该区域,其中红色的是"触摸"地面:

enter image description here