Game running slow

Started by
5 comments, last by spedax 14 years, 1 month ago
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 ?
Advertisement
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.
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.
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    nextnext


this is what we in the industry formally call horribly slow.
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
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.
Post some code, we might be able to help you out more directly rather than just guessing at the problem (:
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

This topic is closed to new replies.

Advertisement