Reputation: 20
I am having trouble attempting to detect when a circle, that is following a point in a circle, has hit a label. When it hits the label, I want the label to go to the top right of the screen. So far, it will draw the circle, and it goes around the point forever, but its going right through the label, without the label being moved to the top left. Here's my code.
Public Sub circleDetection(circle As Rectangle)
If Label1.Bounds.IntersectsWith(circle) Then
Label1.Top = 0
Label1.Left = 0
MsgBox("you DIED!")
End If
End Sub
Private WithEvents TMcircle As New Timer
Dim SunCentre As New Point(300, 300)
Dim OrbitRadius As Integer = 150
Dim PlanetDiameter As Integer = 10
Dim Planet As New Rectangle(OrbitRadius - PlanetDiameter \ 2, PlanetDiameter \ 2, PlanetDiameter, PlanetDiameter)
Dim Angle As Single
Private Sub Tmr_Tick(sender As Object, e As System.EventArgs) Handles TMcircle.Tick
Angle += 1
Invalidate()
circleDetection(Planet)
End Sub
Public Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
' draw center
e.Graphics.TranslateTransform(SunCentre.X, SunCentre.Y)
' draw circle
e.Graphics.RotateTransform(Angle)
e.Graphics.FillEllipse(Brushes.Blue, Planet)
End Sub
I have attempted to draw a secondary circle where the angle leads to, but this has failed to work as I do not have the x and y coordinates of the rotated circle. It didn't fail to run, but nothing showed up no matter how big I made it.
Upvotes: 0
Views: 84
Reputation: 39122
You use the Matrix class to perform the same operations (translate and rotate) on the planet's center point that you do in the Paint()
event. Then you build a rectangle from that transformed point and you now have a rectangle representing the planet in the same coordinate system as that of the Label (with respect to the Forms origin in the top left). Now we can simply use the Rectangle.IntersectsWith()
method as expected to test for a collision.
Example code:
Public Class Form1
Private WithEvents TMcircle As New Timer
Dim Angle As Single
Dim SunCentre As New Point(300, 300)
Dim SunRadius As Integer = 50
Dim OrbitRadius As Integer = 150
Dim PlanetDiameter As Integer = 10
Dim PlanetRadius As Integer = PlanetDiameter / 2
Dim PlanetCentre As New Point(OrbitRadius - PlanetRadius, 0)
Dim M As New Drawing2D.Matrix
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TMcircle.Interval = 50
TMcircle.Enabled = False
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TMcircle.Start()
End Sub
Private Sub Tmr_Tick(sender As Object, e As System.EventArgs) Handles TMcircle.Tick
Angle += 2
Invalidate()
circleDetection()
End Sub
Public Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
' draw sun
e.Graphics.TranslateTransform(SunCentre.X, SunCentre.Y)
Dim rc As New Rectangle(New Point(0, 0), New Size(1, 1))
rc.Inflate(SunRadius, SunRadius)
e.Graphics.FillEllipse(Brushes.Yellow, rc)
' draw planet
e.Graphics.RotateTransform(Angle)
rc = New Rectangle(PlanetCentre, New Size(1, 1))
rc.Inflate(PlanetRadius, PlanetRadius)
e.Graphics.FillEllipse(Brushes.Blue, rc)
End Sub
Public Sub circleDetection()
M.Reset()
M.Translate(SunCentre.X, SunCentre.Y)
M.Rotate(Angle)
Dim points() As Point = {PlanetCentre}
M.TransformPoints(points)
Dim planetRC As New Rectangle(points(0), New Size(1, 1))
planetRC.Inflate(PlanetRadius, PlanetRadius)
If planetRC.IntersectsWith(Label1.Bounds) Then
Label1.Top = 0
Label1.Left = 0
MessageBox.Show("you DIED!")
End If
End Sub
End Class
Here it is in action:
Upvotes: 1