Sign in to follow this  
spedax

Game running slow

Recommended Posts

I created a game in VB.net I have a tank that can shoot at enemies, and my collision detection is also working great. But the only problem is. I use a game loop ( with a stopwatch ) that runs every 15ms, now once I shoot, the game starts to run more slowly, and once the bullet hit something, the game runs smooth again. Could this be because im using picture boxes instead of system.drawing ?

Share this post


Link to post
Share on other sites
Your game loop seems to take more than 15ms, hence the slowdown. This is probably because of your collision detection because it happens only when a bullet is on screen.

I don't know about picture boxes, but I'm pretty sure that if you're doing pixel per pixel collision detection, it can be really costly, especially in VB. You'll have to profile your code and find what's using that much CPU and optimize that. You should filter you collision with a bounding box test before doing any pixel test, you'll get a huge speed up boost.

Share this post


Link to post
Share on other sites
I use
image1.Bounds.IntersectsWith(image2.Bounds)
for collision dection, might this be the problem ?

If also added movement to my my enemies, and now the game got really sluggish.

Any help would be greatly appriciated!

edit: Even if I put my game loop cycle op to 100 ms, the game runs slower once I shoot or when the enemies start moving.

Could it be that the problem lays with the movement instead of the collision dection ?

second edit : I removed the collision detection and I still have the same problem, once I shoot or the enemies start moving, the game slows down allot.

Share this post


Link to post
Share on other sites
How are you testing collision of one object against another? Please tell me you arent doing this:


for i = 1 to 100
for j = 1 to 100
' collision test goes here
next
next


this is what we in the industry formally call horribly slow.

Share this post


Link to post
Share on other sites
Also, I don't know how you did all your timings, but you should use a dynamic timestep. More or less, everytime your loop iterates, you take how long has passed, and you send that to everything you call so when the bullet(or whatever) updates how far it travelled last frame, it uses that. Something like this:

time_passed = how long has passed since the last time we updated bullet position
bullet_speed = how far a bullet goes in 1 millisecond

bullet_new_position = bullet_old_position + time_passed * bullet_speed;

However, there's definitely another issue if you're seeing a slow-down on 100ms loop, and it's almost certainly with collision detection. For your collision detection, you should use a bounding box (circle, actually) for every collidable object and test those circles first, then if those circles intersect do an accurate collision detection. This is because collision detections on circles is vastly cheaper than CD on every other kind of object (for mathematical reasons).

We do these detections because if a circle bigger than an object doesn't intersect with a circle bigger than the other object, there's no way those two can touch.

Share this post


Link to post
Share on other sites
here is my code for collision detection
( between the "bullet" and the enemies, I only have 2)


Public Function collision(ByVal imgbullet As PictureBox, ByVal imgenemy1 As PictureBox, ByVal imgenemy2 As PictureBox) As Integer
If imgenemy1.Bounds.IntersectsWith(imgbullet.Bounds) Then
Return 1
ElseIf imgenemy2.Bounds.IntersectsWith(imgbullet.Bounds) Then
Return 2
Else
Return 0
End If
End Function



here is the code for moving the bullet


Public Sub shoot(ByRef imgbullet As PictureBox, ByVal angle As Double)
imgbullet.Visible = True
Dim xcord, ycord As Integer
Dim loc As Point
If Between(CInt(angle), 0, 90) Then
angle /= 90
angle *= 50
ycord = CInt(angle)
xcord = 50 - CInt(angle)
loc = New Point(imgbullet.Location.X - xcord, imgbullet.Location.Y - ycord)
imgbullet.Location = loc
ElseIf Between(CInt(angle), 91, 180) Then
angle -= 90
angle /= 90
angle *= 50
xcord = CInt(angle)
ycord = 50 - CInt(angle)
loc = New Point(imgbullet.Location.X + xcord, imgbullet.Location.Y - ycord)
imgbullet.Location = loc
ElseIf Between(CInt(angle), 181, 270) Then
angle -= 180
angle /= 90
angle *= 50
ycord = CInt(angle)
xcord = 50 - CInt(angle)
loc = New Point(imgbullet.Location.X + xcord, imgbullet.Location.Y + ycord)
imgbullet.Location = loc
ElseIf Between(CInt(angle), 271, 359) Then
angle -= 270
angle /= 90
angle *= 50
xcord = CInt(angle)
ycord = 50 - CInt(angle)
loc = New Point(imgbullet.Location.X - xcord, imgbullet.Location.Y + ycord)
imgbullet.Location = loc
End If

End Sub


and finally here is the code to move the enemy ( it has some random values in it to make it go left and right randomly )


Public Sub move(ByRef imgenemy As PictureBox)
Dim random As New Random
Dim point As Point

'random richting veranderen
If random.Next(0, 50) = 5 Then
If richting = "rechts" Then
richting = "links"
Else
richting = "rechts"
End If
End If

'als richting rechts is
If richting = "rechts" Then
'als bij volgende stap picturebox niet voorbij rand gaat
If imgenemy.Location.X + 25 + steps < 950 Then
point = New Point(imgenemy.Location.X + steps, imgenemy.Location.Y)
imgenemy.Location = point
'zowel
Else
richting = "links"
End If
End If

'als richting links is
If richting = "links" Then
'als bij volgende stap picturebox niet voorbij rand gaat
If imgenemy.Location.X - steps > 0 Then
point = New Point(imgenemy.Location.X - steps, imgenemy.Location.Y)
imgenemy.Location = point
'zowel
Else
richting = "rechts"
End If
End If
End Sub


and this is call called in the gameloop


Private Sub GameLoop()
timer.Start()
Do While (Me.Created)
startTick = timer.ElapsedMilliseconds

Dim value As Double = Math.Atan2((ymouse - (imgtank.Location.Y + 22)), (xmouse - (imgtank.Location.X + 22)))
Dim Angle As Integer = CInt(value * (180 / Math.PI)) + 180
intangle = Angle
lblangle.Text = "angle = " & CStr(Angle)

If bullet.shot = True Then

If bullet.collision(imgbullet, imgenemy1, imgenemy2) <> 0 Then
Select Case bullet.collision(imgbullet, imgenemy1, imgenemy2)
Case 1
enemy1.respawn(imgenemy1)
Case 2
enemy2.respawn(imgenemy2)
End Select

bullet.shot = False
bullet.move(imgbullet, imgtank.Location.X, imgtank.Location.Y)
imgbullet.Visible = False
game.score += 1
lblscore.Text = CStr(game.score)

ElseIf bullet.outter(imgbullet) Then
bullet.shot = False
bullet.move(imgbullet, imgtank.Location.X, imgtank.Location.Y)
imgbullet.Visible = False
Else
bullet.shoot(imgbullet, CDbl(intshootangle))
End If
End If

If blnleft = True Then
tank.move(imgtank, "left", lblline)
If bullet.shot = False Then
bullet.move(imgbullet, imgtank.Location.X, imgtank.Location.Y)
End If
ElseIf blnright = True Then
tank.move(imgtank, "right", lblline)
If bullet.shot = False Then
bullet.move(imgbullet, imgtank.Location.X, imgtank.Location.Y)
End If

End If
If bullet.shot = False Then
bullet.move(imgbullet, imgtank.Location.X, imgtank.Location.Y)
End If

enemy1.move(imgenemy1)
enemy2.move(imgenemy2)

Application.DoEvents()
Do While timer.ElapsedMilliseconds - startTick < interval

Loop
Loop
End Sub

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this