Changing Vector Directions - vb.net

I'm trying to make a Pong knockoff in VB.net. However, I am having difficulty managing to get the ball object to change directions once it gets outside of the screen. This is what I have right now:
Option Explicit On
Option Infer Off
Option Strict On
Public Class Form1
'Declare variables here
Dim P1Score As Integer = 0
Dim P2Score As Integer = 0
Dim velocity As Integer = 1
Dim RandGen As New Random
Dim angle As Integer
'This function defines the X-value movement
Private Function angleCalcX(ByVal angle As Integer) As Integer
Dim xSpeed As Integer
xSpeed = Convert.ToInt16(ball.Location.X + (velocity * System.Math.Cos(angle)))
If ball.Bounds.IntersectsWith(Player1.Bounds) OrElse ball.Bounds.IntersectsWith(Player2.Bounds) Then
xSpeed = Convert.ToInt16(-(ball.Location.X + (velocity * System.Math.Cos(angle))))
End If
Return xSpeed
End Function
Private Function angleCalcY(ByRef angle As Integer) As Integer
Dim ySpeed As Integer
ySpeed = Convert.ToInt16(ball.Location.Y + (velocity * System.Math.Sin(angle)))
If (ball.Bounds.IntersectsWith(background.Bounds)) = False Then
ySpeed = Convert.ToInt16(-(ball.Location.Y + (velocity * System.Math.Sin(angle))))
End If
Return ySpeed
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MessageBox.Show("Hello, and welcome to Pong! This is a 2-player game. Player 1 uses the W and S keys, and Player 2 uses the K and I keys. First to five goals wins. Press space to start!", "Start Screen.jpg", MessageBoxButtons.OK, MessageBoxIcon.Information)
angle = RandGen.Next(1, 360)
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
ball.Location = New Point(angleCalcX(angle), angleCalcY(angle))
If ball.Location.X > 1049 Then
P1Score += 1
velocity = 1
ElseIf ball.Location.X < 12 Then
P2Score += 1
velocity = 1
End If
End Sub
Public Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.S Then
Player1.Top += 25
ElseIf e.KeyCode = Keys.W Then
Player1.Top -= 25
ElseIf e.KeyCode = Keys.K Then
Player2.Top += 25
ElseIf e.KeyCode = Keys.I Then
Player2.Top -= 25
End If
End Sub
Private Sub quitButton_Click(sender As Object, e As EventArgs) Handles quitButton.Click
Me.Close()
End Sub
End Class
Can anyone help me out?

There's missing something like this in your Timer2_Tick
ElseIf ball.Location.Y < 12 OrElse ball.Location.Y > 600 Then
ySpeed = -ySpeed 'Make a bounce from top/bottom edge
But there's a lot to improve in the rest of code as well. I don't see the reason to use Int16 for speeds or hard-coding boundaries in code for example.

Related

Rotated plane—projected and drawn in 2D—looks crooked instead of straight at some edges

Introductory remarks
The purpose of this program is to rotate a mathematical plane around the x and z axes and to project this onto the 2D GUI.
First about the sign convention:
The plane lies in the xz-plane (so at the origin), where +x goes to the right, +y to the depth of the picture and +z to the top (compare: I look at another person as a person).
Many vectors are used to fill the surface. Depending on the size of the plane, there are often more than 40,000 vectors. So I decided to run the calculation function asynchronously. Since it is now cumbersome / nonsensical to paint in the PictureBox, I write in a bitmap, which I then assign to the PictureBox after each calculation process. Since the Graphics.DrawLine function reached its limits in terms of performance, I integrated SkiaSharp from Visual Studio's own Nuget package manager. Now, I write in an SKBtmap and can move the plane with the WASD keys and get a new image within a few hundred milliseconds.
For the projection, I use a formula that I found at StackOverflow a few months ago. I have now shown it clearly and distinctly. Since the plane partly comes towards me when turning, the distance to me changes. So, I subtract the distance_to_plane to get the real distance.
Dim projected As New PointF(
CSng((Camera - Window_distance) / (Camera - distance_to_plane) * rotatedVec.X),
CSng(-(Camera - Window_distance) / (Camera - distance_to_plane) * rotatedVec.Z))
What is my concern to you:
As you can see from the pictures, the plane has some curves (outliers) at the edges where it should be straight instead. I can't explain the effect.
I suspect the above formula. To remedy this, I set the camera very far away from the plane, and the projection window far away ‘enough’ from both the camera and the plane.
I'll put the complete source code online, maybe it's something else (a typical effect?).
Form ‘Create’ to instantiate a new plane.
Plane strongly rotated around the z-axis with odd edges in the middle. As you can see from the values, the camera is currently 2660 units of length away from the plane, and the projection window is 1000 units of length. (Camera – window 1660)
Form1.vb
Public NotInheritable Class FormMain
Private Plane1 As PlaneInTermsOfGeometry = Nothing
Public ReadOnly Deu As New System.Globalization.CultureInfo("de-DE")
Private Sub FormMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.BackColor = Color.FromArgb(184, 176, 143)
For Each but As Button In Me.Controls.OfType(Of Button)
but.BackColor = Color.FromArgb(201, 200, 193)
Next
TextBox_Window.Text = "-1000"
Label5.Text = ""
Label6.Text = ""
End Sub
Private Sub FormMain_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
New_Plane()
End Sub
Private Sub Button_new_plane_Click(sender As Object, e As EventArgs) Handles Button_new_plane.Click
New_Plane()
End Sub
Private Async Sub New_Plane()
Using FNP As New FormCreateNewPlane
If FNP.ShowDialog(Me) <> DialogResult.OK Then
Return
End If
Plane1 = New PlaneInTermsOfGeometry(
FNP.A0x,
FNP.A0y,
FNP.A0z,
FNP.ABx,
FNP.ABy,
FNP.ABz,
FNP.ACx,
FNP.ACy,
FNP.ACz,
FNP.Enlargement)
Await Plane1.process_async()
PictureBox1.Image = Nothing
PictureBox1.Image = PlaneInTermsOfGeometry.displayedBitmap
Label5.Text = Math.Round(Plane1.current_x_angle, 0).ToString(Deu)
Label6.Text = Math.Round(Plane1.current_z_angle, 0).ToString(Deu)
TextBox_Kamera.Text = Math.Round(Plane1.Camera, 0).ToString(Deu)
End Using
End Sub
Private Sub TextBox_Kamera_TextChanged(sender As Object, e As EventArgs) Handles TextBox_Kamera.TextChanged
If Plane1 Is Nothing Then Return
Dim Kamera As Double
If Double.TryParse(TextBox_Kamera.Text, Kamera) Then
TextBox_Kamera.ForeColor = Color.FromArgb(0, 125, 0)
Plane1.Camera = Kamera
Else
TextBox_Kamera.ForeColor = Color.Red
End If
End Sub
Private Sub TextBox_Fenster_TextChanged(sender As Object, e As EventArgs) Handles TextBox_Window.TextChanged
If Plane1 Is Nothing Then Return
Dim Fenster As Double
If Double.TryParse(TextBox_Window.Text, Fenster) Then
TextBox_Window.ForeColor = Color.FromArgb(0, 125, 0)
Plane1.Window_distance = Fenster
Else
TextBox_Window.ForeColor = Color.Red
End If
End Sub
Private Async Sub FormMain_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
If Plane1 Is Nothing Then Return
Select Case e.KeyCode
Case Keys.W
If Plane1.current_x_angle > -90.0 Then
Plane1.change_x_angle(-1.0)
Await Plane1.process_async()
PictureBox1.Image = Nothing
GC.Collect()
PictureBox1.Image = PlaneInTermsOfGeometry.displayedBitmap
Label5.Text = Math.Round(Plane1.current_x_angle, 0).ToString(Deu)
Label6.Text = Math.Round(Plane1.current_z_angle, 0).ToString(Deu)
TextBox_KOForm.Text = Plane1.Cartesian_Equation()
End If
Case Keys.S
If Plane1.current_x_angle < 90.0 Then
Plane1.change_x_angle(1.0)
Await Plane1.process_async()
PictureBox1.Image = Nothing
GC.Collect()
PictureBox1.Image = PlaneInTermsOfGeometry.displayedBitmap
Label5.Text = Math.Round(Plane1.current_x_angle, 0).ToString(Deu)
Label6.Text = Math.Round(Plane1.current_z_angle, 0).ToString(Deu)
TextBox_KOForm.Text = Plane1.Cartesian_Equation()
End If
Case Keys.A
If Plane1.current_z_angle > -90.0 Then
Plane1.change_z_angle(-1.0)
Await Plane1.process_async()
PictureBox1.Image = Nothing
GC.Collect()
PictureBox1.Image = PlaneInTermsOfGeometry.displayedBitmap
Label5.Text = Math.Round(Plane1.current_x_angle, 0).ToString(Deu)
Label6.Text = Math.Round(Plane1.current_z_angle, 0).ToString(Deu)
TextBox_KOForm.Text = Plane1.Cartesian_Equation()
End If
Case Keys.D
If Plane1.current_z_angle < 90.0 Then
Plane1.change_z_angle(1.0)
Await Plane1.process_async()
PictureBox1.Image = Nothing
GC.Collect()
PictureBox1.Image = PlaneInTermsOfGeometry.displayedBitmap
Label5.Text = Math.Round(Plane1.current_x_angle, 0).ToString(Deu)
Label6.Text = Math.Round(Plane1.current_z_angle, 0).ToString(Deu)
TextBox_KOForm.Text = Plane1.Cartesian_Equation()
End If
Case Else
Exit Select
End Select
End Sub
Private Async Sub FormMain_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
If Plane1 Is Nothing Then Return
If e.Delta > 0 Then
' The Camera must be in front of the window.
If (Plane1.Camera - Plane1.Window_distance) < 0.0 Then
Plane1.change_Camera_distance(20.0)
Await Plane1.process_async()
PictureBox1.Image = Nothing
GC.Collect()
PictureBox1.Image = PlaneInTermsOfGeometry.displayedBitmap
End If
Else
Plane1.change_Camera_distance(-20.0)
Await Plane1.process_async()
PictureBox1.Image = Nothing
GC.Collect()
PictureBox1.Image = PlaneInTermsOfGeometry.displayedBitmap
End If
TextBox_Kamera.Text = Math.Round(Plane1.Camera, 0).ToString(Deu)
End Sub
End Class
class PlaneInTermsOfGeometry (By the way: I was politely instructed to choose a reasonable name for this class instead of just "Plane"...)
Imports System.Windows.Media.Media3D
Imports SkiaSharp
Public NotInheritable Class PlaneInTermsOfGeometry
Private Structure VA0
Public x As Double
Public y As Double
Public z As Double
End Structure
Private A0 As VA0
Private Structure VAB
Public x As Double
Public y As Double
Public z As Double
End Structure
' →
Private AB As VAB
Private Structure VAC
Public x As Double
Public y As Double
Public z As Double
End Structure
' →
Private AC As VAC
Private ReadOnly allVectors As New List(Of Vector3D)
''' <summary>
''' in degrees
''' </summary>
Public current_x_angle As Double = 0.0
''' <summary>
''' in degrees
''' </summary>
Public current_z_angle As Double = 0.0
''' <summary>
''' The picture in which is written and which is shown by the PictureBox.
''' </summary>
Public Shared displayedBitmap As System.Drawing.Bitmap
''' <summary>
''' The camera position on the y-axis (we look along the +y arrow).
''' </summary>
Public Camera As Double = -2660.0
''' <summary>
''' The projection window position on the y-axis. Absolute value!
''' </summary>
Public Window_distance As Double = -1000.0
''' <summary>
''' The distance from the origin of coordinates to the x-length
''' </summary>
Private ReadOnly oneSide As Double
Private ReadOnly Grid As New List(Of Vector3D)
Public Sub New(ByVal A0x As Double,
ByVal A0y As Double,
ByVal A0z As Double,
ByVal ABx As Double,
ByVal ABy As Double,
ByVal ABz As Double,
ByVal ACx As Double,
ByVal ACy As Double,
ByVal ACz As Double,
ByVal enlarg As Double)
Me.A0.x = A0x
Me.A0.y = A0y
Me.A0.z = A0z
Me.AB.x = ABx * enlarg
Me.AB.y = ABy
Me.AB.z = ABz
Me.AC.x = ACx
Me.AC.y = ACy
Me.AC.z = ACz * enlarg
Me.oneSide = ABx * enlarg
For x As Double = -AB.x To AB.x Step 1.0
For z As Double = -AC.z To AC.z Step 2.0
allVectors.Add(New Vector3D(x, 0.0, z))
' For the grid
If CSng(x) Mod 15.0F = 0.0F Then
Grid.Add(New Vector3D(x, 0.0, z))
Else
Grid.Add(New Vector3D(0.0, 0.0, 0.0))
End If
Next
Next
End Sub
Public Sub change_Camera_distance(ByVal dy As Double)
Camera += dy
End Sub
Public Sub change_x_angle(ByVal value As Double)
current_x_angle += value
End Sub
Public Sub change_z_angle(ByVal value As Double)
current_z_angle += value
End Sub
Private Function rotate_around_x_axis(ByVal vec1 As Vector3D) As Vector3D
Return New Vector3D(
vec1.X,
vec1.Y * Math.Cos(current_x_angle * Math.PI / 180.0) - vec1.Z * Math.Sin(current_x_angle * Math.PI / 180.0),
vec1.Y * Math.Sin(current_x_angle * Math.PI / 180.0) + Math.Cos(current_x_angle * Math.PI / 180.0) * vec1.Z)
End Function
Private Function rotate_around_z_axis(ByVal vec2 As Vector3D) As Vector3D
Return New Vector3D(
Math.Cos(current_z_angle * Math.PI / 180.0) * vec2.X - vec2.Y * Math.Sin(current_z_angle * Math.PI / 180.0),
Math.Sin(current_z_angle * Math.PI / 180.0) * vec2.X + vec2.Y * Math.Cos(current_z_angle * Math.PI / 180.0),
vec2.Z)
End Function
Public Async Function process_async() As Task(Of Boolean)
Return Await Task.Run(Function() processing())
End Function
Private Function processing() As Boolean
displayedBitmap = Nothing
Dim i As Integer = 0
Dim imageInfo As New SKImageInfo(FormMain.PictureBox1.Size.Width, FormMain.PictureBox1.Size.Height)
Using surface As SKSurface = SKSurface.Create(imageInfo)
Using canvas As SKCanvas = surface.Canvas
canvas.Translate(FormMain.PictureBox1.Size.Width \ 2, FormMain.PictureBox1.Size.Height \ 2)
Using DarkBlue As New SKPaint With {
.TextSize = 64.0F,
.IsAntialias = True,
.Color = New SKColor(0, 64, 255),
.Style = SKPaintStyle.Fill
}
Using BrightYellow As New SKPaint With {
.TextSize = 64.0F,
.IsAntialias = True,
.Color = New SKColor(255, 255, 64),
.Style = SKPaintStyle.Fill
}
For Each vec As Vector3D In allVectors
Dim rotatedVec As Vector3D = rotate_around_z_axis(rotate_around_x_axis(vec))
If rotatedVec.Y > Window_distance Then ' The object is not further back than the window (the window is not in the object). When false, don't draw!
Dim Angle_in_degrees As Double = Vector3D.AngleBetween(
rotatedVec,
New Vector3D(rotatedVec.X, 0.0, rotatedVec.Z))
If Double.IsNaN(Angle_in_degrees) Then
i += 1
Continue For
End If
' Opposite cathetus
Dim distance_to_plane As Double = oneSide * Math.Sin(Angle_in_degrees * Math.PI / 180.0)
Dim projected As New PointF(
CSng((Camera - Window_distance) / (Camera - distance_to_plane) * rotatedVec.X),
CSng(-(Camera - Window_distance) / (Camera - distance_to_plane) * rotatedVec.Z))
If Grid(i).X = 0.0 AndAlso Grid(i).Y = 0.0 AndAlso Grid(i).Z = 0.0 Then
' draw the mathematical plane
canvas.DrawPoint(projected.X, projected.Y, DarkBlue)
Else
' draw the grid (Gitternetz)
canvas.DrawPoint(projected.X, projected.Y, BrightYellow)
End If
i += 1
End If
Next
End Using
End Using
End Using
'–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
' get the data into ‘displayedBitmap’ because the PictureBox is only accepting an usual System.Drawing.Bitmap.
'–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
Using image As SKImage = surface.Snapshot()
Using data As SKData = image.Encode(SKEncodedImageFormat.Png, 100)
Using mStream As New IO.MemoryStream(data.ToArray())
displayedBitmap = New Bitmap(mStream, False)
End Using
End Using
End Using
End Using
Return True
End Function
'Koordinatenform
Public Function Cartesian_Equation() As String
Dim _N As Vector3D = Vector3D.CrossProduct(rotate_around_z_axis(New Vector3D(AB.x, AB.y, AB.z)), rotate_around_x_axis(New Vector3D(AC.x, AC.y, AC.z)))
Dim _xMinusA0 As String
Dim _yMinusA0 As String
Dim _zMinusA0 As String
If A0.x = 0.0 Then
_xMinusA0 = "x"
Else
_xMinusA0 = $"(x - {A0.x.ToString(FormMain.Deu)})"
End If
If A0.y = 0.0 Then
_yMinusA0 = "y"
Else
_yMinusA0 = $"(y - {A0.y.ToString(FormMain.Deu)})"
End If
If A0.z = 0.0 Then
_zMinusA0 = "z"
Else
_zMinusA0 = $"(z - {A0.z.ToString(FormMain.Deu)})"
End If
Return ($"{Math.Round(_N.X, 3).ToString(FormMain.Deu)} * {_xMinusA0} + {Math.Round(_N.Y, 3).ToString(FormMain.Deu)} * {_yMinusA0} + {Math.Round(_N.Z, 3).ToString(FormMain.Deu)} * {_zMinusA0}").ToString(FormMain.Deu)
End Function
End Class
For the sake of completeness, if someone wants to recreate it, here is FormNewPlane.vb to create a new plane, as shown in the first picture.
Imports Microsoft.VisualBasic.ControlChars
Public NotInheritable Class FormCreateNewPlane
Public A0x, A0y, A0z, ABx, ABy, ABz, ACx, ACy, ACz, Enlargement As Double
Private Sub FormCreateNewPlane_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.BackColor = Color.FromArgb(184, 176, 143)
For Each but As Button In Me.Controls.OfType(Of Button)
but.BackColor = Color.FromArgb(201, 200, 193)
Next
If System.IO.File.Exists(Application.StartupPath & "\Preview.png") Then
PictureBox1.Image = Image.FromFile(Application.StartupPath & "\Preview.png")
End If
'Since this is a plane that lies in the xz plane, only the text box contents that display a 1 should be changed.
Label5.Text = $"Da es hier um eine Ebene geht, die{NewLine}in der xz-Ebene liegt, sollen nur die{NewLine}Textbox-Inhalte verändert werden,{NewLine}die eine 1 anzeigen."
End Sub
Private Sub FormCreateNewPlane_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
If PictureBox1.Image IsNot Nothing Then PictureBox1.Image.Dispose()
End Sub
Private Sub ButtonOK_Click(sender As Object, e As EventArgs) Handles ButtonOK.Click
Me.DialogResult = DialogResult.OK
End Sub
Private Sub TextBoxA0x_TextChanged(sender As Object, e As EventArgs) Handles TextBoxA0x.TextChanged
If Double.TryParse(TextBoxA0x.Text, A0x) Then
TextBoxA0x.ForeColor = Color.FromArgb(0, 125, 0)
Else
TextBoxA0x.ForeColor = Color.Red
End If
End Sub
Private Sub TextBoxA0y_TextChanged(sender As Object, e As EventArgs) Handles TextBoxA0y.TextChanged
If Double.TryParse(TextBoxA0y.Text, A0y) Then
TextBoxA0y.ForeColor = Color.FromArgb(0, 125, 0)
Else
TextBoxA0y.ForeColor = Color.Red
End If
End Sub
Private Sub TextBoxA0z_TextChanged(sender As Object, e As EventArgs) Handles TextBoxA0z.TextChanged
If Double.TryParse(TextBoxA0z.Text, A0z) Then
TextBoxA0z.ForeColor = Color.FromArgb(0, 125, 0)
Else
TextBoxA0z.ForeColor = Color.Red
End If
End Sub
Private Sub TextBoxABx_TextChanged(sender As Object, e As EventArgs) Handles TextBoxABx.TextChanged
If Double.TryParse(TextBoxABx.Text, ABx) Then
TextBoxABx.ForeColor = Color.FromArgb(0, 125, 0)
Else
TextBoxABx.ForeColor = Color.Red
End If
End Sub
Private Sub TextBoxABy_TextChanged(sender As Object, e As EventArgs) Handles TextBoxABy.TextChanged
If Double.TryParse(TextBoxABy.Text, ABy) Then
TextBoxABy.ForeColor = Color.FromArgb(0, 125, 0)
Else
TextBoxABy.ForeColor = Color.Red
End If
End Sub
Private Sub TextBoxABz_TextChanged(sender As Object, e As EventArgs) Handles TextBoxABz.TextChanged
If Double.TryParse(TextBoxABz.Text, ABz) Then
TextBoxABz.ForeColor = Color.FromArgb(0, 125, 0)
Else
TextBoxABz.ForeColor = Color.Red
End If
End Sub
Private Sub TextBoxACx_TextChanged(sender As Object, e As EventArgs) Handles TextBoxACx.TextChanged
If Double.TryParse(TextBoxACx.Text, ACx) Then
TextBoxACx.ForeColor = Color.FromArgb(0, 125, 0)
Else
TextBoxACx.ForeColor = Color.Red
End If
End Sub
Private Sub TextBoxACy_TextChanged(sender As Object, e As EventArgs) Handles TextBoxACy.TextChanged
If Double.TryParse(TextBoxACy.Text, ACy) Then
TextBoxACy.ForeColor = Color.FromArgb(0, 125, 0)
Else
TextBoxACy.ForeColor = Color.Red
End If
End Sub
Private Sub TextBoxACz_TextChanged(sender As Object, e As EventArgs) Handles TextBoxACz.TextChanged
If Double.TryParse(TextBoxACz.Text, ACz) Then
TextBoxACz.ForeColor = Color.FromArgb(0, 125, 0)
Else
TextBoxACz.ForeColor = Color.Red
End If
End Sub
Private Sub TextBox_Enlarg_TextChanged(sender As Object, e As EventArgs) Handles TextBox_Enlarg.TextChanged
If Double.TryParse(TextBox_Enlarg.Text, Enlargement) Then
TextBox_Enlarg.ForeColor = Color.FromArgb(0, 125, 0)
Else
TextBox_Enlarg.ForeColor = Color.Red
End If
End Sub
Private Sub TextBox_Enlarg_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox_Enlarg.KeyDown
If e.KeyCode = Keys.Enter Then
If Double.TryParse(TextBox_Enlarg.Text, Enlargement) Then
TextBox_Enlarg.ForeColor = Color.FromArgb(0, 125, 0)
Else
TextBox_Enlarg.ForeColor = Color.Red
End If
Me.DialogResult = DialogResult.OK
End If
End Sub
Private Sub TextBox_Enlarg_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox_Enlarg.KeyPress
If e.KeyChar = Convert.ToChar(13) Then e.Handled = True ' This suppresses the ‘ding’ sound.
End Sub
End Class
If you'd like to apply perspective projection to the points, the projected point should be something like this;
Dim projected As New PointF(
CSng((Camera - Window_distance) / (Camera - rotatedVec.Y) * rotatedVec.X),
CSng(-(Camera - Window_distance) / (Camera - rotatedVec.Y) * rotatedVec.Z))
' In short, distance_to_plane = rotatedVec.Y

Timer won't start in vb.net

I have started the timer with Game.Start() and by using a breakpoint I have determined that the timer is enabled, the interval is 100. However when stepping through my code, the timer sub is ignored and the paint sub is given priority. Therefore, the timer is never being run.
Here is the code which i am referring to :
Public Class Form1
Dim speed_s As Integer = 5
Dim speed_w As Integer = 5
Dim speed_d As Integer = 5
Dim speed_a As Integer = 5
Dim Enemy1 As New computerControlled(1, 1, Me)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
player1.Bounds = New Rectangle(player1.Location.X, player1.Location.Y, player1.Width, player1.Height)
'Enemy1.DrawEnemy(Me)
Game.Enabled = True
Game.Start()
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.W Then
player1.Top -= speed_w
ElseIf e.KeyCode = Keys.S Then
player1.Top += speed_s
ElseIf e.KeyCode = Keys.A Then
player1.Left -= speed_a
ElseIf e.KeyCode = Keys.D Then
player1.Left += speed_d
' Enemy1.enemypic.Left += 10 this moves enemy class well
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Game.Tick
'Enemy1.enemypic.Left += 10
Enemy1.Walk()
MsgBox("hi")
End Sub
Private MOUSE_X As Integer
Private MOUSE_Y As Integer
Private Sub Form1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
MOUSE_X = e.X
MOUSE_Y = e.Y
End Sub
Private Sub Player_Paint(sender As Object, e As PaintEventArgs) Handles player1.Paint
Dim GFX As Graphics = e.Graphics
Dim BMP As Bitmap = Image.FromFile("c:\firaas\ball.png")
Dim center As Point = New Point(player1.Width \ 2, player1.Height \ 2)
Dim angle As Integer
Dim rad As Double
Dim CENTRE_X As Integer
Dim CENTRE_Y As Integer
'=========================
Using cyan As New Pen(Brushes.Cyan, 2)
GFX.ResetTransform()
GFX.TranslateTransform(CENTRE_X, CENTRE_Y)
GFX.RotateTransform(angle) ' angle in DEGREES!
'For Each pos As PointF In pat.Positions
' Dim r As New Rectangle(pos.X, pos.Y, 1, 1)
' r.Inflate(3, 3)
' GFX.DrawEllipse(cyan, r)
' Next
End Using
'===========================
Dim rotatematrix As New System.Drawing.Drawing2D.Matrix()
Dim srcRect As New RectangleF(64, 64, 64, 64)
Dim OffsetX As Single = Me.Width / 2 - player1.Width / 2
Dim OffsetY As Single = Me.Height / 2 - player1.Height / 2
CENTRE_X = player1.Location.X + player1.Width / 2
CENTRE_Y = player1.Location.Y + player1.Height / 2
rad = Math.Atan2(MOUSE_Y - CENTRE_Y, MOUSE_X - CENTRE_X)
angle = rad * (180 / Math.PI)
'================================================================================
BMP = New Bitmap(My.Resources.ball)
GFX.TranslateTransform(player1.Height / 2, player1.Width / 2)
GFX.RotateTransform(angle)
GFX.DrawImage(BMP, 64, 64, player1.Location.X, player1.Location.Y)
GFX.ResetTransform()
e.Graphics.TranslateTransform(player1.Height / 2, player1.Width / 2)
e.Graphics.RotateTransform(angle)
' BMP.RotateAt(angle, New PointF(player1.Location.X, player1.Location.Y))
e.Graphics.DrawImage(BMP, New Point(-player1.Width \ 2, -player1.Height \ 2))
e.Graphics.DrawImageUnscaled(BMP, New Point(0, 0))
player1.Invalidate()
End Sub
End Class
'latest project
If this is the complete code, it doesn't seem like you're setting your timer's interval.
So you're telling it, it can tick and what to do each tick but not actually setting a time for it to tick.
Game.Interval = 60000 '1 minute
Game.Enabled = True
Game.Start() 'I don't believe you need this line

How can I use collision detection with spawned arrays

Since I have been trying to make a space invaders style game I have been having trouble with collision detection with spawned objects in arrays (and having a bit of trouble with the bullets, they keep stopping and having another generate). I am new at coding and would like some help with these issues, or at least some links to some forums that had the same thread question.
here is my code:
Public Class Form1
'global variables
Dim intAmountOfEnemys As Short = 9
Dim intRowsOfEnemys As Integer = 0 '**
Dim intAmountOfBullets As Integer = 0
Dim picEnemysWave1(intAmountOfEnemys) As PictureBox
Dim lblBullets As New Label
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Welcome_Screen.Hide()
Call EnemyWaves(picEnemysWave1)
End Sub
Sub PlayerMovement(ByVal sender As Object, ByVal e As KeyEventArgs) Handles MyBase.KeyDown
If e.KeyCode = Keys.A Then
If picShip.Right <= 0 Then
picShip.Left = 1567
Else
picShip.Left -= 10
End If
ElseIf e.KeyCode = Keys.D Then
If picShip.Left >= 1567 Then
picShip.Left = -15
Else
picShip.Left += 10
End If
ElseIf e.KeyCode = Keys.Space Then
Do
BulletGeneration(lblBullets)
Loop Until Keys.Space
lblBullets.Left = (picShip.Left + 7)
End If
End Sub
#Region "Enemy waves, Movement, and Properties"
Sub EnemyWaves(ByRef picEnemysWave1() As PictureBox)
'Enemy Generator
Const srtENEMYSPACING_Y As Short = 155
For intCounterForEnemys As Integer = 0 To intAmountOfEnemys
Dim intEnemySpacing As Integer = srtENEMYSPACING_Y * intCounterForEnemys
picEnemysWave1(intCounterForEnemys) = New PictureBox
picEnemysWave1(intCounterForEnemys).Location = New Point(42 + intEnemySpacing, 1)
picEnemysWave1(intCounterForEnemys).Image = My.Resources.enemy
picEnemysWave1(intCounterForEnemys).Width = 124
picEnemysWave1(intCounterForEnemys).Height = 84
picEnemysWave1(intCounterForEnemys).Show()
Me.Controls.Add(picEnemysWave1(intCounterForEnemys))
Next intCounterForEnemys
End Sub``
Private Sub TmrAlien1_Tick(sender As Object, e As EventArgs) Handles TmrAlien1.Tick
For intRandom As Integer = 0 To 9
picEnemysWave1(intRandom).Top += 3
Dim intRandomNum As Integer = Rnd()
If intRandomNum > 0.66 Then
picEnemysWave1(intRandom).Left += 2 'goes left randomly
ElseIf intRandomNum < 0.33 Then
picEnemysWave1(intRandom).Left -= 2 'goes right randomly
End If
If picEnemysWave1(intRandom).Top <= 0 Then
TmrAlien1.Start()
End If
If picEnemysWave1(intRandom).Top >= 952 Then
TmrAlien1.Stop()
End If
Next intRandom
End Sub
#End Region
#Region "Bullet Generation, Movement, and Properties"
Sub BulletGeneration(ByRef lblBullets As Object)
'Generation of Bullets
For intBulletCounter As Integer = 0 To intAmountOfBullets
lblBullets = New Label
lblBullets.location = New Point(760, 785)
lblBullets.image = My.Resources.blast2
lblBullets.width = 32
lblBullets.height = 64
lblBullets.show()
Me.Controls.Add(lblBullets)
Next intBulletCounter
End Sub
Private Sub tmrBullets_Tick(sender As Object, e As EventArgs) Handles tmrBullets.Tick
lblBullets.Top -= 20
End Sub
#End Region
#Region "Collision Detection"
Sub BulletCollision(ByRef lblBullets As Label, ByRef intAmontOfEnemys As Integer)
For Each picEnemy As PictureBox In picEnemysWave1
If lblBullets.Bounds.IntersectsWith(picEnemy.Bounds) Then
picEnemy.Location = New Point(3900, 8700)
Exit For
End If
Next
'what Im trying
End Sub
#End Region

PictureBox initial image

Is there a way that you can set all of the picboxes to a initial image when they are loaded? Such as: when you start a round, all the images are set to a image of a card facing down, then when the round starts it shows an image.
EDIT: How do I clear what is in the PicCard.Image?
Public Class Form1
Private Cards As New List(Of PictureBox)
Private randomnumber As Integer
Private HowManyCards As Integer
Private Sub SetupCards(numberofcards As Integer)
ClearGame()
For i As Integer = 0 To numberofcards
Dim PicCard As PictureBox = New PictureBox()
PicCard.Width = 100
PicCard.Height = 200
PicCard.Top = 50
PicCard.Left = 50 + PicCard.Width * i
Me.Controls.Add(PicCard)
PicCard.Image = imglistBackOfCard.Images(0)
Next i
End Sub
Private Sub ClearGame()
If Cards.Count > 0 Then
For i As Integer = 0 To Cards.Count - 1
Me.Controls.Remove(Cards(i))
Next
End If
' Clear the cards if they were already setup from a previous game.
Cards.Clear()
End Sub
Private Sub RandomCard()
Randomize()
randomnumber = Int(Rnd() * imglist1.Images.Count - 1) + 1
End Sub
Public Sub ShowCards(numberofcards As Integer)
For i As Integer = 0 To numberofcards
Dim PicCard As PictureBox = New PictureBox()
RandomCard()
PicCard.Width = 100
PicCard.Height = 200
PicCard.Top = 50
PicCard.Left = 50 + PicCard.Width * i
Me.Controls.Add(PicCard)
PicCard.Image = imglist1.Images(randomnumber)
PicCard.Tag = randomnumber
AddHandler PicCard.Click, AddressOf Me.cardflip_click
Cards.Add(PicCard)
Next i
End Sub
Private Sub StartGame_Click(sender As Object, e As EventArgs) Handles btnStartGame.Click
ShowCards(HowManyCards - 1)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
HowManyCards = InputBox("How Many Cards?", "Please Enter")
SetupCards(Int(howmanycards - 1))
End Sub
End Class

How to draw points when user clicks on a map

Dim HaveToDraw As New Boolean
Dim xMouse As Integer
Dim yMouse As Integer
Private Sub foo(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
If HaveToDraw = True Then
e.Graphics.FillEllipse(Brushes.Green, xMouse, yMouse, 10, 10)
End If
HaveToDraw = False
End Sub
Sub PictureBox1_MouseClick(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseClick
If RadioButton1.Checked = True Then
xMouse = e.X
yMouse = e.Y
HaveToDraw = True
PictureBox1.Refresh()
End If
End Sub
This code lets the user draw an elipse when he clicks on any point on the map, but there are 2 problems with it: 1 - The user is able to draw only one elipse; 2 - The user is not able to erase a previously created elipse.
So, how can I do that solving these two problems?
As #Idle_Mind suggested, you could use a list to store your points, and a right-click event to remove the points:
Dim radius as Integer = 5
Private points As New List(Of Point)()
Private Sub pictureBox1_MouseClick(sender As Object, e As MouseEventArgs)
If e.Button = System.Windows.Forms.MouseButtons.Left Then
points.Add(e.Location) ' add point on left click
ElseIf e.Button = System.Windows.Forms.MouseButtons.Right Then
For i As Integer = 0 To points.Count - 1 ' remove points on right-click
If distance(points(i).X, points(i).Y, e.Location) < radius Then
points.RemoveAt(i)
End If
Next
End If
pictureBox1.Refresh()
End Sub
'helper function
Private Function distance(x__1 As Integer, y__2 As Integer, mousep As Point) As Integer
Dim X__3 As Integer = CInt(Math.Pow(CDbl(x__1 - mousep.X), 2))
Dim Y__4 As Integer = CInt(Math.Pow(CDbl(y__2 - mousep.Y), 2))
Return CInt(Math.Sqrt(CDbl(X__3 + Y__4)))
End Function
Private Sub pictureBox1_Paint(sender As Object, e As PaintEventArgs)
For i As Integer = 0 To points.Count - 1
e.Graphics.FillEllipse(Brushes.Green, points(i).X - radius, points(i).Y - radius, radius * 2, radius * 2)
Next
End Sub
I also changed the paint code to draw the circles so that they are centered under the mouse-click.