Posts: 159
Threads: 25
Joined: Mar 2012
Reputation:
0
Hello. I am trying to write a Space Shooter game in Visual Basic. Since I've started like a half hour ago, I made the player spaceship movement and the projectile launching.
The projectile launching is triggered by pressing the Space bar key. However, the same one will launch all the time. For better understanding, here are two screenshoots:
Description: Shortly after the first time I press space.
Description: Shortly after the second time I press space while the previous projectile was still in the form.
I assume you've read the image descriptions and seen what is the problem. If you still cannot understand what is the problem, let me explain better. If I just launch the projectile, it will start moving, let's say it reached the middle of the form and now I launch it again, the previous projectile won't reach the end of the form and then disappear, it will teleport to the beginning (a bit above the Spaceship).
Here is the code I use: Code: Dim pro As New PictureBox
Private Sub spawnProjectile()
pro.Image = proj
pro.Visible = True
pro.Width = 9
pro.Height = 32
pro.Top = Player.Top - 20
pro.Left = Player.Left + 20
Controls.Add(pro)
End Sub
I assume you will tell me to move the PictureBox declaration inside the Sub. I've tried that and it doesn't work since the timer which moves it cannot access the variable inside the sub.
So, the main problem is accessing the variable which is inside the sub.
When I finish the game, I will post the download link on this forum. Hopefully the game will be a decent one.
Anyway, thanks in advance.
Also known as Rocketalypse.
System.out.println("I prefer Java.");
Posts: 1,006
Threads: 111
Joined: Jul 2010
Reputation:
1
Well, I can definitely see your problem here! Well, the generally accepted solution to this problem would be to create an array which holds all of the bullets of the player, and every time the timer ticks, each bullet is moved. I have put what I am talking about into code:
Code: Private playerBullets As List(Of PictureBox)
Public Sub Player_Shoot(Sender As Object, e As System.EventArgs)
'This method creates the new bullet!
Dim pro As New PictureBox
pro.Image = proj
pro.Visible = True
pro.Width = 9
pro.Height = 32
pro.Top = Player.Top - 20
pro.Left = Player.Left + 20
Controls.Add(pro)
playerBullets.Add(pro)
End Sub
Public Sub PlayerBullets_Act(sender As Object, e As System.EventArgs)
'This method moves the player bullets and detects their collisions. It should be called every
'time the timer ticks
For Each bullet As PictureBox In playerBullets
If (bullet.Location.Y <= 0) Then
'The bullet has moved off of the screen, we need to remove it to conserve system resources
Controls.Remove(bullet)
playerBullets.Remove(bullet)
End If
'TODO: Check for collisions with enemies here
bullet.Location = New System.Drawing.Point(bullet.Location.X, bullet.Location.Y - 2) 'Move the bullet up
Next
End Sub
Pastebin Version: <!-- m --><a class="postlink" href="http://pastebin.com/1t5iazRR">http://pastebin.com/1t5iazRR</a><!-- m -->
So, essentially what we are doing is keeping track of all the bullets that the player has actually shot, and removing them once they go off the screen. In order to apply this procedure, simply make the timer call PlayerBullets_Act every time the timer ticks.
Posts: 159
Threads: 25
Joined: Mar 2012
Reputation:
0
I get an error when I put the PlayerBullets_Act() in the Timer Tick.
Here is the code snippet:
Code: Private Sub Fire_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Fire.Tick
PlayerBullets_Act()
End Sub
Here is the error:
Quote:1 Argument not specified for parameter 'e' of 'Public Sub PlayerBullets_Act(sender As Object, e As System.EventArgs)'.
2 Argument not specified for parameter 'sender' of 'Public Sub PlayerBullets_Act(sender As Object, e As System.EventArgs)'.
Also known as Rocketalypse.
System.out.println("I prefer Java.");
Posts: 1,006
Threads: 111
Joined: Jul 2010
Reputation:
1
Alright, just remove the (sender As Object, e As System.EventArgs) from the PlayerBullets_Act method.
Posts: 159
Threads: 25
Joined: Mar 2012
Reputation:
0
I am sorry for bothering you so many times in a row, but I still get an error when I try to shoot.
Code: For Each bullet As PictureBox In playerBullets
Quote:Object reference not set to an instance of an object.
Also known as Rocketalypse.
System.out.println("I prefer Java.");
Posts: 1,006
Threads: 111
Joined: Jul 2010
Reputation:
1
Ah, sorry about the faulty code that I provided you with!
Change Private playerBullets As List(Of PictureBox) to this
Private playerBullets As List(Of PictureBox) = New List(Of PictureBox)
Posts: 159
Threads: 25
Joined: Mar 2012
Reputation:
0
Right now, I don't get any errors but nothing fires.
I assume it is hard to help "blindly", a.k.a. without looking at the whole code, so I will just provide a link to it.
http://pastebin.com/VV9w7D92
Also known as Rocketalypse.
System.out.println("I prefer Java.");
Posts: 1,006
Threads: 111
Joined: Jul 2010
Reputation:
1
Alright, thanks for providing me with that! There are a few things that you are going to want to do now. First of all, make the "Fire" timer enabled all the time.
Also, change the sub
Public Sub Player_Shoot(Sender as object, e as eventargs)
to
Public Sub Player_Shoot()
Then, when the user presses space, call Player_Shoot() and delete the line that sets Fire.Enabled = true
Let's see if that fixes it...
Posts: 159
Threads: 25
Joined: Mar 2012
Reputation:
0
Everything works until one bullet reaches the end of the form.
Code: Public Sub PlayerBullets_Act()
'This method moves the player bullets and detects their collisions. It should be called every
'time the timer ticks
For Each bullet As PictureBox In playerBullets
If (bullet.Location.Y <= 0) Then
'The bullet has moved off of the screen, we need to remove it to conserve system resources
Controls.Remove(bullet)
playerBullets.Remove(bullet)
End If
'TODO: Check for collisions with enemies here
bullet.Location = New System.Drawing.Point(bullet.Location.X, bullet.Location.Y - 2) 'Move the bullet up
Next
End Sub
The problem is at the Next. This is what I get:
Quote:Collection was modified; enumeration operation may not execute.
Also known as Rocketalypse.
System.out.println("I prefer Java.");
Posts: 1,006
Threads: 111
Joined: Jul 2010
Reputation:
1
Oh okay! Alright, this is an easy fix. So this error is popping up because we are modifying the array as we are scrolling through it, so the solution to this is to create an array to keep track of the bullets that we need to remove and remove them once we are finished. So something like this...
Code: Public Sub PlayerBullets_Act()
'This method moves the player bullets and detects their collisions. It should be called every
'time the timer ticks
Dim bulletsToRemove As New List(Of PictureBox)
For Each bullet As PictureBox In playerBullets
If (bullet.Location.Y <= 0) Then
'The bullet has moved off of the screen, we need to remove it to conserve system resources
bulletsToRemove.Add(bullet)
End If
'TODO: Check for collisions with enemies here
bullet.Location = New System.Drawing.Point(bullet.Location.X, bullet.Location.Y - 2) 'Move the bullet up
Next
'Now we remove the bullets
For Each bullet As PictureBox In bulletsToRemove
Controls.Remove(bullet)
playerBullets.Remove(bullet)
Next
End Sub
Posts: 159
Threads: 25
Joined: Mar 2012
Reputation:
0
Thank you so much for putting this much effort into solving my problem! Even though this might not mean anything to you, I will put your name in the credits.
Once again, huge thanks! <!-- s --><img src="{SMILIES_PATH}/icon_e_biggrin.gif" alt=" " title="Very Happy" /><!-- s -->
Also known as Rocketalypse.
System.out.println("I prefer Java.");
Posts: 1,006
Threads: 111
Joined: Jul 2010
Reputation:
1
Haha, you're very welcome! I'm glad that it worked out for you!!
|