|
-
May 13th, 2008, 07:04 PM
#1
Thread Starter
Member
Asteroids
I'm making a game that has a similar feel as asteroids, and I'm a bit stuck.
First off, I want to be able to fire more than one bullet at a time. I was thinking I could use a structure for this, but not eactly sure how to do it.
Also, is there a way to move the form background image? I have a 'space' background tiled to the form and would like it to 'scroll' a little.
Using vb.net 2008
Last edited by WebKill; May 13th, 2008 at 07:30 PM.
-
May 13th, 2008, 09:03 PM
#2
Lively Member
Re: Asteroids
I created a similar game using vb6. I used Dx7.
The scrolling background is most difficult for me. I can't combine the two.
Here is a method for firing. The shuttle has 24 directions and 24 images in an array.
There may be a much simpler way. But this does work well. Just to give you an idea.
Code:
Public Sub ShootFire() 'This is what happens when the player fires
If (GetTickCount - Shuttle.ShootTime) < 300 Then Exit Sub
Shuttle.ShootTime = GetTickCount
If Not sFire Then Exit Sub
Call FireLazer 'DX sound
G = 1
Do Until Not Mgun(G).act Or G = 20 'find an open slot
G = G + 1
Loop
With Mgun(G)
.speed = 5
.act = True: .X = Shuttle.X: .Y = Shuttle.Y: .dire = Shuttle.dire
'.speed = .speed * Shuttle.speed:
mgNum = mgNum + 1
.ShootTime = GetTickCount
Select Case Shuttle.dire
Case 24 'dire the case #
.Y = Shuttle.Y + 20: .X = Shuttle.X + 17
Case 1
.Y = Shuttle.Y + 13: .X = Shuttle.X + 26:
Case 2
.Y = Shuttle.Y + 15: .X = Shuttle.X + 35:
Case 3
.Y = Shuttle.Y + 11: .X = Shuttle.X + 41:
Case 4
.Y = Shuttle.Y + 13: .X = Shuttle.X + 43:
Case 5
.Y = Shuttle.Y + 10: .X = Shuttle.X + 45:
Case 6
.Y = Shuttle.Y + 18: .X = Shuttle.X + 41:
Case 7
.Y = Shuttle.Y + 26: .X = Shuttle.X + 44:
Case 8
.Y = Shuttle.Y + 32: .X = Shuttle.X + 41:
Case 9
.Y = Shuttle.Y + 43: .X = Shuttle.X + 40:
Case 10
.Y = Shuttle.Y + 43: .X = Shuttle.X + 35:
Case 11
.Y = Shuttle.Y + 44: .X = Shuttle.X + 25:
Case 12
.Y = Shuttle.Y + 40: .X = Shuttle.X + 17:
Case 13
.Y = Shuttle.Y + 45: .X = Shuttle.X + 10:
Case 14
.Y = Shuttle.Y + 41: .X = Shuttle.X + 12
Case 15
.Y = Shuttle.Y + 44: .X = Shuttle.X + 12:
Case 16
.Y = Shuttle.Y + 33: .X = Shuttle.X + 15:
Case 17
.Y = Shuttle.Y + 26: .X = Shuttle.X + 15:
Case 18
.Y = Shuttle.Y + 19: .X = Shuttle.X + 20:
Case 19
.Y = Shuttle.Y + 12: .X = Shuttle.X + 17:
Case 20
.Y = Shuttle.Y + 14: .X = Shuttle.X + 15:
Case 21
.Y = Shuttle.Y + 11: .X = Shuttle.X + 12:
Case 22
.Y = Shuttle.Y + 11: .X = Shuttle.X + 7:
Case 23
.Y = Shuttle.Y + 12: .X = Shuttle.X + 9:
End Select
End With
End Sub
Public Sub MoveMgs() 'move bullets ----------
For G = 1 To 20
With Mgun(G)
If .act Then
If btnDown Or goBack Or Shuttle.speed < 2 Then
Mgun(G).speed = 1
Else
Mgun(G)
End If
If .dire = 24 Then 'dire = case #
Mgun(G).Y = Mgun(G).Y - 20 * .speed
ElseIf .dire = 1 Then
Mgun(G).X = Mgun(G).X + 4 * .speed
Mgun(G).Y = Mgun(G).Y - 15 * .speed
ElseIf .dire = 2 Then
Mgun(G).X = Mgun(G).X + 8 * .speed
Mgun(G).Y = Mgun(G).Y - 15 * .speed
ElseIf .dire = 3 Then
Mgun(G).X = Mgun(G).X + 10 * .speed
Mgun(G).Y = Mgun(G).Y - 10 * .speed
ElseIf .dire = 4 Then
Mgun(G).X = Mgun(G).X + 15 * .speed
Mgun(G).Y = Mgun(G).Y - 10 * .speed
ElseIf .dire = 5 Then
Mgun(G).X = Mgun(G).X + 15 * .speed
Mgun(G).Y = Mgun(G).Y - 5 * .speed
ElseIf .dire = 6 Then
Mgun(G).X = Mgun(G).X + 20 * .speed
ElseIf .dire = 7 Then
Mgun(G).X = Mgun(G).X + 15 * .speed
Mgun(G).Y = Mgun(G).Y + 4 * .speed
ElseIf .dire = 8 Then
Mgun(G).X = Mgun(G).X + 15 * .speed
Mgun(G).Y = Mgun(G).Y + 10 * .speed
ElseIf .dire = 9 Then
Mgun(G).X = Mgun(G).X + 10 * .speed
Mgun(G).Y = Mgun(G).Y + 10 * .speed
ElseIf .dire = 10 Then
Mgun(G).X = Mgun(G).X + 9 * .speed
Mgun(G).Y = Mgun(G).Y + 15 * .speed
ElseIf .dire = 11 Then
Mgun(G).X = Mgun(G).X + 4 * .speed
Mgun(G).Y = Mgun(G).Y + 15 * .speed
ElseIf .dire = 12 Then
Mgun(G).Y = Mgun(G).Y + 20 * .speed 'down
ElseIf .dire = 13 Then
Mgun(G).X = Mgun(G).X - 4 * .speed
Mgun(G).Y = Mgun(G).Y + 15 * .speed
ElseIf .dire = 14 Then
Mgun(G).X = Mgun(G).X - 10 * .speed
Mgun(G).Y = Mgun(G).Y + 15 * .speed
ElseIf .dire = 15 Then
Mgun(G).X = Mgun(G).X - 10 * .speed
Mgun(G).Y = Mgun(G).Y + 10 * .speed
ElseIf .dire = 16 Then
Mgun(G).X = Mgun(G).X - 15 * .speed
Mgun(G).Y = Mgun(G).Y + 10 * .speed
ElseIf .dire = 17 Then
Mgun(G).X = Mgun(G).X - 15 * .speed
Mgun(G).Y = Mgun(G).Y + 4 * .speed
ElseIf .dire = 18 Then
Mgun(G).X = Mgun(G).X - 20 * .speed 'left
ElseIf .dire = 19 Then
Mgun(G).X = Mgun(G).X - 15 * .speed
Mgun(G).Y = Mgun(G).Y - 5 * .speed
ElseIf .dire = 20 Then
Mgun(G).X = Mgun(G).X - 15 * .speed
Mgun(G).Y = Mgun(G).Y - 10 * .speed
ElseIf .dire = 21 Then
Mgun(G).X = Mgun(G).X - 10 * .speed
Mgun(G).Y = Mgun(G).Y - 10 * .speed
ElseIf .dire = 22 Then
Mgun(G).X = Mgun(G).X - 5 * .speed
Mgun(G).Y = Mgun(G).Y - 10 * .speed
ElseIf .dire = 23 Then
Mgun(G).X = Mgun(G).X - 4 * .speed
Mgun(G).Y = Mgun(G).Y - 15 * .speed
End If
If .dire >= 1 And .dire <= 11 Then '1 thru 11 rightside clock
If Mgun(G).X >= 1020 Then
Mgun(G).X = 0:
End If
End If
If (GetTickCount - Mgun(G).ShootTime) >= 550 Then 'set stop time
Mgun(G).act = False
.X = .X: .Y = .Y: .dire = 0
End If
If .dire >= 13 And .dire <= 23 Then '13 thru 23 left side clock
If Mgun(G).X <= 0 Then
Mgun(G).X = 1020
End If
End If
If .dire >= 7 And .dire <= 17 Then '17 thru 7 lower clock
If Mgun(G).Y >= 760 Then
Mgun(G).Y = 0
End If
End If
If .dire >= 20 And .dire <= 24 Or .dire <= 1 Or .dire <= 5 Then '20 thru 5 upper clock
If Mgun(G).Y <= 0 Then
Mgun(G).Y = 760
End If
End If
End If
End With
Next G
End Sub
mGun, shuttle are both UDTs.
Using a game loop you call MoveMgs to move the shots.
I added a space station that the shuttle can dock to recharge and the player must protect the station from asteroids.
.
-
May 13th, 2008, 09:03 PM
#3
Hyperactive Member
Re: Asteroids
You're right when you say you will need a structure. A class would work as well, but a structure would probably be better for something small like this.
When you build a structure, you need to incorporate whatever information each instance of that stucture will need. So a individual bullet will obviously need a pictureBox (or whatever control you're using to display your bullets), as well as a position and a speed. More advanced structures could also have a damage value, a size value, or whatever else you want.
Since your pictureBox already has an X,Y Location, you won't need to define that. But you will need to define an xSpeed and ySpeed value.
First of all, create your structure:
vb Code:
Public Structure Bullet
End Structure
Now initialise the variables you'll need for each bullet:
vb Code:
Dim pictureBox As PictureBox
Dim xSpeed As Double
Dim ySpeed As Double
Now add an Update method. You can call this for each Bullet every time the game updates:
vb Code:
Sub UpdateBullet()
'Move the Bullet
picBox.Location() = New Point(picBox.Location.X + xSpeed, picBox.Location.Y + ySpeed)
'Add your collision checking code here
End Sub
You'll also need a bullet List to keep track of the bullets... something like this:
vb Code:
Dim bulletList As List(Of Bullet)
To use the structure now, simply create a bullet, add it to a bullet list and set it's variables:
vb Code:
Dim x As Bullet
x.picBox.Image = myImage 'Preload an image with Dim imageName As Image, then use it
x.xSpeed = 0 'Determine your xSpeed
x.ySpeed = 0 'Determine your ySpeed
bulletList.Add(x)
Finally, update all the bullets in your timer_tick method:
vb Code:
Dim y As Bullet
For Each y In bulletList
y.UpdateBullet()
Next
Hope this helps!
Cheers,
Qu.
"Why do all my attempts at science end with me getting punched by batman?" xkcd.
| Pong| |
Sorry for not posting more often.
-
May 14th, 2008, 07:53 AM
#4
Thread Starter
Member
Re: Asteroids
Wow, thanks for the awsoem help guys! Quasar6, thats exactly what I was looking for, but I'm having a little trouble still, it's saying "Object reference not set to an instance of an object." at the line with "x.picbox.Image = myshot"
At the top I have:
Code:
myshot = picShot.Image
Dim shotList As List(Of Shot)
Public Structure Shot
Dim X As Double
Dim Y As Double
Dim picbox As PictureBox
Dim speed As Single
Dim Damage As Single
Sub UpdateShot()
picbox.Location() = New Point(picbox.Location.X + X, picbox.Location.Y + Y)
End Sub
End Structure
Then for my mouse click:
Code:
Dim x As New Shot
x.picbox.Image = myshot
x.X = 1
x.Y = 1
shotList.Add(x)
Timer1.Enabled = True
And finally my timer:
Code:
Dim y As Shot
For Each y In shotList
y.Updateshot()
Next
-
May 14th, 2008, 09:12 AM
#5
Thread Starter
Member
Re: Asteroids
Ok, I think I got it figured out, but it's still only allowing one shot at a time.
Code:
Public Structure Shot
Dim X As Double
Dim Y As Double
Dim picbox As PictureBox
Dim speed As Single
Dim Damage As Single
Sub UpdateShot()
'Move the Bullet
picbox.Location() = New Point(picbox.Location.X + speed, picbox.Location.Y + speed)
'Add your collision checking code here
End Sub
End Structure
Public shotList As New List(Of Shot)
Then for mouse click I have this, I want the shot to originate from the ship image, dont care where it goes at this point, just want it to fire multiple shots.
Code:
Dim x As New Shot
x.picbox = pctShot
x.picbox.Location() = New Point(mypic.Top + (mypic.Height / 2), mypic.Left + (mypic.Width / 2))
x.X = mypic.Top + (mypic.Height / 2)
x.Y = mypic.Left + (mypic.Width / 2)
x.speed = 1
x.picbox.Visible = True
shotList.Add(x)
Timer1.Enabled = True
And heres the timer:
Code:
Dim y As Shot
For Each y In shotList
y.Updateshot()
Next
Last edited by WebKill; May 14th, 2008 at 09:16 AM.
-
May 14th, 2008, 12:20 PM
#6
Lively Member
Re: Asteroids
Create an array for new shots and you should be able to have mulitple shots fired.
Code:
Dim Shot() as New Shot
Dim A as integer
For A = 1 to 10
with Shot(A)
.pctbox = pctShot
.x = pic.Top + (mypic.Height / 2)
.y = mypic.Left + (mypic.Width / 2)
.speed = 1
'etc.
End With
Next
-
May 14th, 2008, 01:06 PM
#7
Thread Starter
Member
Re: Asteroids
What about the list?
Public shotList As New List(Of Shot)
-
May 14th, 2008, 04:55 PM
#8
Hyperactive Member
Re: Asteroids
A List is infinitely better than an array, because with an array you're limited to a number of shots equal to the array size. With a list you can keep calling ListName.Add forever and all you'll suffer will be lag when you end up with a googleplex or so shots.
As to your problem... I'm thinking about it... give me a moment, I'll reply properly in a second...
Last edited by Quasar6; May 14th, 2008 at 05:34 PM.
"Why do all my attempts at science end with me getting punched by batman?" xkcd.
| Pong| |
Sorry for not posting more often.
-
May 14th, 2008, 05:33 PM
#9
Hyperactive Member
Re: Asteroids
OK, I found your problem... rather than copying a bullet picture and putting it in the new Shot Structure, you're actually making an existing pictureBox the bullet. Then whenever you create a bullet all the old bullets still exist, but the picture box representing the bullet moves to only the position of the last bullet you created.
Try replacing this ...... with something like this...
Code:
x.picbox = New PictureBox()
x.picbox.Image = pctShot.Image
. As you can see, this will create a new PictureBox rather than just moving the old one.
There is one ather thing I should have mentioned: you need to add the PictureBox to Form1 (Or whatever your form's name is) once it's created. Simply add the following line immediately after x.picbox's attributes are set, but before you add x to the shot list...
Code:
Form1.ActiveForm.Controls.Add(x.picbox)
Cheers!
"Why do all my attempts at science end with me getting punched by batman?" xkcd.
| Pong| |
Sorry for not posting more often.
-
May 15th, 2008, 07:40 AM
#10
Thread Starter
Member
Re: Asteroids
Doh, that seems obvious, hehe. Only problem is when I do that, the shot never displays, so I see nothing instead of multiples.
-
May 15th, 2008, 04:17 PM
#11
Thread Starter
Member
Re: Asteroids
Well, I got the shot to display, but I cant get the thing to move Good greif, lol
Here's my shot structure, the bullet fires at the angle of the ship:
vb Code:
Public Structure Shot
Dim XPos As Int32
Dim YPos As Int32
Dim picbox As PictureBox
Dim speed As Int32
Dim distance As Int32
Dim angle As Int32
Dim damage As Single
Sub UpdateShot()
Dim X, Y As Int32
X = -Math.Sin(angle * Math.PI / 180.0) * 3
Y = -Math.Cos(angle * Math.PI / 180.0) * 3
XPos = XPos + X
YPos = YPos + Y
picbox.Location() = New Point(XPos, YPos)
'Add your collision checking code here
End Sub
End Structure
Here's where the shot is created (mouse click):
vb Code:
x.picbox = New PictureBox
x.picbox.Image = pctShot.Image
x.picbox.SizeMode = PictureBoxSizeMode.AutoSize
'x.picbox.Location = New Point(500, 500)
x.XPos = myShip.picbox.Location.X + (myShip.picbox.Width / 2)
x.YPos = myShip.picbox.Location.Y + (myShip.picbox.Height / 2)
x.speed = 3
x.distance = 500
x.picbox.Visible = True
x.angle = myShip.angle
Controls.Add(x.picbox)
shotList.Add(x)
Background worker shot dowork:
vb Code:
For i = 1 To 2
bwShot.ReportProgress(i)
If i = 2 Then i = 1
If bwShot.CancellationPending = True Then
Exit For
End If
System.Threading.Thread.Sleep(30)
Next
Background worker shot progress changed:
vb Code:
Dim y As Shot
For Each y In shotList
y.UpdateShot()
Next
Now I can tell that it is making the shot because it's displaying it (where the ship is), but it's not moving. Through use of msgbox's I've determined that it's getting inside the updateshot routine, but nothing is changing. the updateshot code is basically the same code for the ships movement, only in this case the angle is constant (set to what angle the ship was at fireing). Any thoughts would be appreciated, I'm probably missing somthign obvious.
-
May 15th, 2008, 05:02 PM
#12
Thread Starter
Member
Re: Asteroids
Ok, got it down to this:
vb Code:
XPos = XPos + X
YPos = YPos + Y
For some reason, those variables wont add together, they all have values, but they wont add together for some reason, any thoughts?
-
May 15th, 2008, 05:20 PM
#13
Hyperactive Member
Re: Asteroids
Yep... I think it's a rounding problem, because you're defining X and Y as Integers. This means that if your maths eqation returns less than 0.5, they'll return as 0.
You are going to need to place the final .Location values as integers, but until you do that try to set all your number variables (X,Y, XPos, YPos) as Single (and only convert to Int at the last moment).
Here:
Code:
Public Structure Shot
Dim XPos As Single
Dim YPos As Single
Dim picbox As PictureBox
Dim speed As Int32
Dim distance As Int32
Dim angle As Int32
Dim damage As Single
Sub UpdateShot()
Dim X, Y As Single
X = -Math.Sin(angle * Math.PI / 180.0) * 3
Y = -Math.Cos(angle * Math.PI / 180.0) * 3
XPos = XPos + X
YPos = YPos + Y
picbox.Location() = New Point(CInt(XPos), CInt(YPos))
'Add your collision checking code here
End Sub
End Structure
"Why do all my attempts at science end with me getting punched by batman?" xkcd.
| Pong| |
Sorry for not posting more often.
-
May 15th, 2008, 05:23 PM
#14
Thread Starter
Member
Re: Asteroids
tried that, didn't work.
I can see values for each of them, for instance
525 = 525 - 3
and guess what it returns? 525
-
May 15th, 2008, 05:33 PM
#15
Hyperactive Member
Re: Asteroids
*confused frown...*
That makes no sense whatsoever. Try this, and let me know what it returns:
Sub UpdateShot()
Code:
Dim X, Y As Single
X = -Math.Sin(angle * Math.PI / 180.0) * 3
Y = -Math.Cos(angle * Math.PI / 180.0) * 3
msgBox(XPos+" += "X)
XPos += X
YPos += Y
msgBox(XPos)
picbox.Location() = New Point(CInt(XPos), CInt(YPos))
'Add your collision checking code here
End Sub
If XPos is the same before and after, something is seriously messed up.
"Why do all my attempts at science end with me getting punched by batman?" xkcd.
| Pong| |
Sorry for not posting more often.
-
May 15th, 2008, 05:42 PM
#16
Thread Starter
Member
Re: Asteroids
I figured it out I needed to set xpos and ypos and shared variables. it's moving now, but theres only 1 at a time, grumble, still cant get that part workign, lol
-
May 15th, 2008, 06:03 PM
#17
Hyperactive Member
Re: Asteroids
Sharing XPos and YPos shouldn't do anything other than make the same XPos and YPos apply to all instances of Shot (with obvious consequences).
I'm confused as to the other problem though... can't see whats going wrong. I'll keep thinking on it..
"Why do all my attempts at science end with me getting punched by batman?" xkcd.
| Pong| |
Sorry for not posting more often.
-
May 15th, 2008, 06:30 PM
#18
Thread Starter
Member
Re: Asteroids
Hmm, well sharing it made it work, but when I fire more than 1, it seems to reset and it looks like 2 go at teh same time, so maybe thats the sharing problem? also, I want to make sure it gets destroyed when it's life is up, so I did this:
vb Code:
If life >= distance Then
shotList.RemoveAt(shotIndex)
End If
but it throws this error when it gets to it: "Exception has been thrown by the target of an invocation."
Seems like a pretty general error?
-
May 15th, 2008, 06:33 PM
#19
Thread Starter
Member
Re: Asteroids
Yeha I just tried taking the shared out and just dim the vars and i have landmines instead of shots again :\ This makes no sense at all because it works just fine for the ship movment, but for some reason Xpos and Ypos do not want to change values.
-
May 16th, 2008, 11:29 AM
#20
Thread Starter
Member
Re: Asteroids
Ok, it apears that the variables are resetting each time, they are getting set, but each time updateshot is called it gets reset. Here's my updated code:
List declared at the top to hold all the shots, plus index so I can destroy a shot
vb.net Code:
Public shotList As New List(Of Shot)
Public shotIndex As Int32
Heres the Structure:
vb.net Code:
Public Structure Shot
Dim XPos As Single
Dim YPos As Single
Dim anglex As Single
Dim angley As Single
Dim picbox As PictureBox
Dim speed As Int32
Dim distance As Int32
Dim damage As Int32
Dim life As Int32
Dim turrent As Boolean
Sub UpdateShot()
XPos = XPos + anglex
YPos = YPos + angley
picbox.Location() = New Point(CInt(XPos), CInt(YPos))
life = life + 1
'Add your collision checking code here
End Sub
End Structure
Here’s the creation at mouse click:
vb.net Code:
x.picbox = New PictureBox
x.picbox.Image = pctShot.Image
x.picbox.SizeMode = PictureBoxSizeMode.AutoSize
x.picbox.Location = New Point(myShip.picbox.Location.X + (myShip.picbox.Width / 2), myShip.picbox.Location.Y + (myShip.picbox.Height / 2))
x.XPos = myShip.picbox.Location.X + (myShip.picbox.Width / 2)
x.YPos = myShip.picbox.Location.Y + (myShip.picbox.Height / 2)
x.anglex = -Math.Sin(myShip.angle * Math.PI / 180.0) * 3
x.angley = -Math.Cos(myShip.angle * Math.PI / 180.0) * 3
x.speed = 3
x.distance = 200
x.picbox.Visible = True
Controls.Add(x.picbox)
shotList.Add(x)
Update shot is called by a background worker (a separate thread) that is constantly checking for shots, looping through the list and updating each one.
vb.net Code:
Dim y As Shot
For Each y In shotList
If y.life >= y.distance Then
y.life = 0
shotList.RemoveAt(shotList.IndexOf(y))
End If
y.UpdateShot()
Label4.Text = y.life
Next
-
May 18th, 2008, 06:10 PM
#21
Hyperactive Member
Re: Asteroids
I honestly can't work out what's going on.
I have one little thought... try changing UpdateShot to:
Code:
Me.XPos = Me.XPos + Me.anglex
Me.YPos = Me.YPos + Me.angley
Me.picbox.Location() = New Point(CInt(Me.XPos), CInt(Me.YPos))
Me.life = Me.life + 1
I doubt it will make any difference, but it might work... If it doesn't, try putting it outside of your structure (in the namespace, changing it to this:
Code:
Sub UpdateShot(this As Shot)
this.XPos = this.XPos + this.anglex
this.YPos = this.YPos + this.angley
this.picbox.Location() = New Point(CInt(this.XPos), CInt(this.YPos))
this.life = this.life + 1
'Add your collision checking code here
End Sub
, and calling it like this: I'm not sure whether any of this will work, but it's the only thing I can think of to try.
"Why do all my attempts at science end with me getting punched by batman?" xkcd.
| Pong| |
Sorry for not posting more often.
-
May 19th, 2008, 04:28 PM
#22
Thread Starter
Member
Re: Asteroids
Figured it out, changed it to a class instead of a structure. With a structure it was updating a copy of it, thats why it wouldn't stay. With a class, it accesses the same point in memory. Wow that one baffled me for a while, lol.
-
May 19th, 2008, 04:56 PM
#23
Hyperactive Member
Re: Asteroids
Yay! Remember to mark your thread resolved.
"Why do all my attempts at science end with me getting punched by batman?" xkcd.
| Pong| |
Sorry for not posting more often.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|