Results 1 to 9 of 9

Thread: About as bad as it can be

  1. #1

    Thread Starter
    Hyperactive Member notquitehere188's Avatar
    Join Date
    Dec 2004
    Posts
    403

    About as bad as it can be

    VB Code:
    1. Public Sub Collision()
    2.  
    3.  
    4.  
    5. For X = 1 To MaxBullets
    6.     With Bullet(X)
    7.         'makes sure it is visible, has moved, and can move
    8.         If .Visible = True And .Moved = True And .Move = True Then
    9.             'Gets rid of bullets outside of the arena (move to collision
    10.             If .Left > ArenaWidth Then
    11.                 BulletCollideEffects (X), ArenaWidth - .Width, .Top, plat(1), True
    12.             ElseIf .Left < 0 Then
    13.                 BulletCollideEffects (X), 0, .Top, plat(1), True
    14.             ElseIf .Top < 0 Then
    15.                 BulletCollideEffects (X), .Left, 0, plat(1), False
    16.             ElseIf .Top > ArenaHeight Then
    17.                 BulletCollideEffects (X), .Left, ArenaHeight - .Height, plat(1), False
    18.             End If
    19.        
    20.             If .Xinertia = 0 Then .Xinertia = 1 'prevent divide by 0
    21.             M = .Yinertia / .Xinertia 'find slope
    22.             If M = 0 Then M = 0.001 'prevent divide by 0
    23.             'y intercept for top left (b) and bottom right(bb)
    24.             B = (.Top - .Yinertia) - (M * (.Left - .Xinertia))
    25.             BB = ((.Top + .Height) - .Yinertia) - (M * ((.Left + .Width) - .Xinertia))
    26.            
    27.             For Y = 1 To PlatCount
    28.                
    29.                 If plat(Y).Visible Then
    30.                     'finds the point where it passes each side
    31.                     Ty = plat(Y).Top
    32.                     Tx = (B - Ty) / -M
    33.                     Tbx = (BB - Ty) / -M
    34.                    
    35.                     Hy = plat(Y).Top + plat(Y).Height
    36.                     Hx = (B - Hy) / -M
    37.                     Hbx = (BB - Hy) / -M
    38.                    
    39.                     Lx = plat(Y).Left
    40.                     Ly = M * Lx + B
    41.                     Lby = M * Lx + BB
    42.                    
    43.                     Wx = plat(Y).Left + plat(Y).Width
    44.                     Wy = M * Wx + B
    45.                     Wby = M * Wx + BB
    46.                    
    47.                     'makes sure that it crosses the line inside the block
    48.                     If Ly >= plat(Y).Top And Ly <= plat(Y).Top + plat(Y).Height And .Left >= Lx And .Left - .Xinertia <= Lx Then
    49.                             BulletCollideEffects (X), Lx - .Width, (Ly), plat(Y), True
    50.                            
    51.                     ElseIf Wy >= plat(Y).Top And Wy <= plat(Y).Top + plat(Y).Height And .Left <= Wx And .Left - .Xinertia >= Wx Then
    52.                         BulletCollideEffects (X), (Wx), (Wy), plat(Y), True
    53.                        
    54.                     ElseIf Lby >= plat(Y).Top And Lby <= plat(Y).Top + plat(Y).Height And .Left >= Lx And .Left - .Xinertia <= Lx Then
    55.                             BulletCollideEffects (X), Lx - .Width, Lby - .Height, plat(Y), True
    56.                            
    57.                     ElseIf Wby >= plat(Y).Top And Wby <= plat(Y).Top + plat(Y).Height And .Left <= Wx And .Left - .Xinertia >= Wx Then
    58.                         BulletCollideEffects (X), (Wx), Wby - .Height, plat(Y), True
    59.                        
    60.                     End If
    61.                        
    62.                    
    63.                            
    64.                     If Tx >= plat(Y).Left And Tx <= plat(Y).Left + plat(Y).Width And .Top >= Ty And .Top - .Yinertia <= Ty Then
    65.                             BulletCollideEffects (X), (Tx), Ty - .Height, plat(Y), False
    66.                            
    67.                     ElseIf Hx >= plat(Y).Left And Hx <= plat(Y).Left + plat(Y).Width And .Top <= Hy And .Top - .Yinertia >= Hy Then
    68.                         BulletCollideEffects (X), (Hx), (Hy), plat(Y), False
    69.                        
    70.                     ElseIf Tbx >= plat(Y).Left And Tbx <= plat(Y).Left + plat(Y).Width And .Top >= Ty And .Top - .Yinertia <= Ty Then
    71.                             BulletCollideEffects (X), Tbx - .Width, Ty - .Height, plat(Y), False
    72.                            
    73.                     ElseIf Hbx >= plat(Y).Left And Hbx <= plat(Y).Left + plat(Y).Width And .Top <= Hy And .Top - .Yinertia >= Hy Then
    74.                         BulletCollideEffects (X), Hbx - .Width, (Hy), plat(Y), False
    75.                        
    76.                     End If
    77.                    
    78.                 End If
    79.            
    80.             Next Y
    81.            
    82.             For Y = 1 To PlayerCount
    83.                
    84.                 If player(Y).Visible Then
    85.                     'finds the point where it passes each side
    86.                     Ty = player(Y).Top
    87.                     Tx = (B - Ty) / -M
    88.                     Tbx = (BB - Ty) / -M
    89.                    
    90.                     Hy = player(Y).Top + player(Y).Height
    91.                     Hx = (B - Hy) / -M
    92.                     Hbx = (BB - Hy) / -M
    93.                    
    94.                     Lx = player(Y).Left
    95.                     Ly = M * Lx + B
    96.                     Lby = M * Lx + BB
    97.                    
    98.                     Wx = player(Y).Left + player(Y).Width
    99.                     Wy = M * Wx + B
    100.                     Wby = M * Wx + BB
    101.                    
    102.                     'makes sure that it crosses the line inside the block
    103.                     If Ly >= player(Y).Top And Ly <= player(Y).Top + player(Y).Height And .Left >= Lx And .Left - .Xinertia <= Lx Then
    104.                             BulletCollideEffects (X), Lx - .Width, (Ly), player(Y), True
    105.                            
    106.                     ElseIf Wy >= player(Y).Top And Wy <= player(Y).Top + player(Y).Height And .Left <= Wx And .Left - .Xinertia >= Wx Then
    107.                         BulletCollideEffects (X), (Wx), (Wy), player(Y), True
    108.                        
    109.                     ElseIf Lby >= player(Y).Top And Lby <= player(Y).Top + player(Y).Height And .Left >= Lx And .Left - .Xinertia <= Lx Then
    110.                             BulletCollideEffects (X), Lx - .Width, Lby - .Height, player(Y), True
    111.                            
    112.                     ElseIf Wby >= player(Y).Top And Wby <= player(Y).Top + player(Y).Height And .Left <= Wx And .Left - .Xinertia >= Wx Then
    113.                         BulletCollideEffects (X), (Wx), Wby - .Height, player(Y), True
    114.                        
    115.                     End If
    116.                        
    117.                    
    118.                            
    119.                     If Tx >= player(Y).Left And Tx <= player(Y).Left + player(Y).Width And .Top >= Ty And .Top - .Yinertia <= Ty Then
    120.                             BulletCollideEffects (X), (Tx), Ty - .Height, player(Y), False
    121.                            
    122.                     ElseIf Hx >= player(Y).Left And Hx <= player(Y).Left + player(Y).Width And .Top <= Hy And .Top - .Yinertia >= Hy Then
    123.                         BulletCollideEffects (X), (Hx), (Hy), player(Y), False
    124.                        
    125.                     ElseIf Tbx >= player(Y).Left And Tbx <= player(Y).Left + player(Y).Width And .Top >= Ty And .Top - .Yinertia <= Ty Then
    126.                             BulletCollideEffects (X), Tbx - .Width, Ty - .Height, player(Y), False
    127.                            
    128.                     ElseIf Hbx >= player(Y).Left And Hbx <= player(Y).Left + player(Y).Width And .Top <= Hy And .Top - .Yinertia >= Hy Then
    129.                         BulletCollideEffects (X), Hbx - .Width, (Hy), player(Y), False
    130.                        
    131.                     End If
    132.                    
    133.                 End If
    134.            
    135.             Next Y
    136.            
    137.            
    138.            
    139.         End If
    140.        
    141.         If Bullet(X).Type = 1 Then
    142.             For Y = 1 To PlayerCount
    143.                 If collide(Bullet(X), player(Y)) = True And Bullet(X).Belong <> (Y) And Bullet(X).Visible = True Then
    144.                     player(Y).Xinertia = Bullet(X).Xinertia
    145.                     player(Y).Yinertia = Bullet(X).Yinertia
    146.                     player(Y).Life = player(Y).Life - GT(1).Power
    147.                 End If
    148.             Next Y
    149.         End If
    150.        
    151.         If .Visible And .Kiboshed Then
    152.             For Y = 1 To PlayerCount
    153.                 If player(Y).OnFire = False And player(Y).Visible And collide(player(Y), Bullet(X)) And GT(.Type).Explode Then
    154.                      CenterX = .Left + (.Width / 2)
    155.                      CenterY = .Top + (.Height / 2)
    156.                      CenterX2 = player(Y).Left + (player(Y).Width / 2)
    157.                      CenterY2 = player(Y).Top + (player(Y).Height / 2)
    158.                      
    159.                      'absolute of cursor position
    160.                     XXX = Abs(CenterX2 - CenterX)
    161.                     YYY = Abs(CenterY - CenterY2)
    162.                      
    163.                     'Makes sure you do not divide by 0
    164.                     If XXX = 0 Then
    165.                          Angle = 0
    166.                     Else
    167.                         'find angle
    168.                          Angle = Atn(YYY / XXX)
    169.                     End If
    170.                    
    171.                     'finds absolute x and y aim
    172.                     XXX = RR * Cos(Angle)
    173.                     YYY = RR * Sin(Angle)
    174.                    
    175.                     'Sets result aiming co-ordinates
    176.                     player(Y).Xinertia = Sgn(CenterX2 - CenterX) * XXX / 20
    177.                     player(Y).Yinertia = (Sgn(CenterY2 - CenterY) * YYY) / 20
    178.                    
    179.                     'other effects
    180.                     player(Y).OnFire = True
    181.                     player(Y).Firetime = 40
    182.                     player(Y).Life = player(Y).Life - 10
    183.                 End If
    184.             Next Y
    185.         End If
    186.     End With
    187. Next X

    This is my collision sub, it checks (almost) every collision in my game however it is VERY redundant as you can see but i cant figure out how to shrink it

    also note that collide is a function elsewhere in the code for finding if two things are actually touching where the majority of this code is for objects moving over something and finding if and where they should have hit

    and if you were wondering, that is the bulletcollideeffects sub
    It's not just Good, It's Good enough!



    Spelling Eludes Me

  2. #2

    Thread Starter
    Hyperactive Member notquitehere188's Avatar
    Join Date
    Dec 2004
    Posts
    403

    Re: About as bad as it can be

    this is the bullet collide effects sub if you were wondering
    VB Code:
    1. Public Sub BulletCollideEffects(BulletNum As Integer, X As Integer, Y As Integer, WhoHit As Bltty, HitSide As Boolean)
    2.  
    3. With Bullet(BulletNum)
    4.     .Top = Y
    5.     .Left = X
    6.    
    7.    
    8.     If WhoHit.Move = True Then
    9.         WhoHit.Xinertia = WhoHit.Xinertia + (.Xinertia * GT(.Type).Weight)
    10.         WhoHit.Yinertia = WhoHit.Yinertia + (.Yinertia * GT(.Type).Weight)
    11.         WhoHit.Life = WhoHit.Life - GT(.Type).Power
    12.         If .Type = 3 Then
    13.             WhoHit.OnFire = True
    14.             WhoHit.Firetime = 10
    15.         End If
    16.         KillBullet BulletNum
    17.     ElseIf GT(.Type).Bounce = True And HitSide = True Then
    18.         .Xinertia = .Xinertia * -1
    19.         Moved = False
    20.     ElseIf GT(.Type).Bounce = True Then
    21.         .Yinertia = .Yinertia * -1
    22.         Moved = False
    23.     Else
    24.         .Move = False
    25.         KillBullet BulletNum
    26.     End If
    27. End With
    28.        
    29.  
    30. End Sub
    It's not just Good, It's Good enough!



    Spelling Eludes Me

  3. #3
    Elite Hacker Jacob Roman's Avatar
    Join Date
    Aug 2004
    Location
    Miami Beach, FL
    Posts
    5,349

    Re: About as bad as it can be

    Show the code where you declared your variables (all of them that are in these Subs) so I can see what data types you are using.

    Here is one area you can increase some speed. The Cos() and Sin() functions. Rather than using them, let's create some lookup tables. This is based on Andre Lamothe's code in my Tricks of the 3D Game Programming Gurus book written by him.

    VB Code:
    1. Public Const PI As Double = 3.14159265358979 '4 * Atn(1)
    2.  
    3. Public Cos_Look_Up_Table(361) As Single
    4. Public Sin_Look_Up_Table(361) As Single
    5.  
    6. Public Sub Build_Sin_Cos_Tables()
    7.  
    8.     Dim Angle As Long
    9.    
    10.     For Angle = 0 To 360
    11.    
    12.         Dim Theta As Single
    13.    
    14.         Theta = Angle * PI / 180
    15.    
    16.         Cos_Look_Up_Table(Angle) = Cos(Theta)
    17.         Sin_Look_Up_Table(Angle) = Sin(Theta)
    18.    
    19.     Next Angle
    20.    
    21. End Sub
    22.  
    23. Public Function Fast_Cos(ByVal Theta As Single) As Single
    24.  
    25.     Theta = Theta Mod 360
    26.    
    27.     If Theta < 0 Then Theta = Theta + 360
    28.    
    29.     Dim Theta_Integer As Long
    30.     Dim Theta_Fraction As Single
    31.    
    32.     Theta_Integer = Theta
    33.     Theta_Fraction = Theta - Theta_Integer
    34.    
    35.     Fast_Cos = Cos_Look_Up_Table(Theta_Integer) + Theta_Fraction * (Cos_Look_Up_Table(Theta_Integer + 1) - Cos_Look_Up_Table(Theta_Integer))
    36.    
    37. End Function
    38.  
    39. Public Function Fast_Sin(ByVal Theta As Single) As Single
    40.  
    41.     Theta = Theta Mod 360
    42.    
    43.     If Theta < 0 Then Theta = Theta + 360
    44.  
    45.     Dim Theta_Integer As Long
    46.     Dim Theta_Fraction As Single
    47.    
    48.     Theta_Integer = Theta
    49.     Theta_Fraction = Theta - Theta_Integer
    50.    
    51.     Fast_Sin = Sin_Look_Up_Table(Theta_Integer) + Theta_Fraction * (Sin_Look_Up_Table(Theta_Integer + 1) - Sin_Look_Up_Table(Theta_Integer))
    52.    
    53. End Function


    Then you add the line Build_Sin_Cos_Tables in the area where you initialize everything to build a look up table, and then use Fast_Cos() and Fast_Sin() in replace of your Cos() and Sin() functions.

    Another area to improve is this area:

    VB Code:
    1. BulletCollideEffects(BulletNum As Integer, X As Integer, Y As Integer, WhoHit As Bltty, HitSide As Boolean)

    Never use the Integer data type unless it's needed, like for example, API's. For a good speed difference, use the Long data type. Here are the reasons. 1) Don't have to worry about overflow that much. 2) Your CPU processor in your computer is 32 bit, and works with 32 bit variables faster. The Long data type is 4 bytes (32 bits) while the Integer data type is only 2 bytes (16 bits), and the processor will have to convert it in order to accomidate.

    And also be sure to either include ByVal or ByRef. Leaving it blank, although by default it'll be ByRef, every time the function is called, it's somewhat slower. Using ByVal is faster. Only use ByRef if your varables in your arguements are gonna be returning a result. Only thing is though you can't use ByVal on variables that are User Defined Types, such as Blitty.

    Now I got that out of the way, here is your new and improved Sub setup:

    VB Code:
    1. BulletCollideEffects(ByVal BulletNum As Long, ByVal  X As Long, ByVal Y As Long, WhoHit As Bltty, ByVal HitSide As Boolean)

  4. #4

    Thread Starter
    Hyperactive Member notquitehere188's Avatar
    Join Date
    Dec 2004
    Posts
    403

    Re: About as bad as it can be

    "Only use ByRef if your varables in your arguements are gonna be returning a result"
    ???

    what does byval do
    It's not just Good, It's Good enough!



    Spelling Eludes Me

  5. #5
    Elite Hacker Jacob Roman's Avatar
    Join Date
    Aug 2004
    Location
    Miami Beach, FL
    Posts
    5,349

    Re: About as bad as it can be

    ByVal variables in the arguements don't return values. If you were to do something like this:

    VB Code:
    1. Option Explicit
    2.  
    3. Private Sub Test(ByVal Testing As Long)
    4.  
    5.     Testing = 5
    6.  
    7. End Sub
    8.  
    9. Private Sub Test2(ByRef Testing As Long)
    10.  
    11.     Testing = 5
    12.  
    13. End Sub
    14.  
    15. Private Sub Form_Activate()
    16.  
    17.     Dim I As Long
    18.    
    19.     Test I
    20.    
    21.     Print I 'Returns 0
    22.    
    23.     Test2 I
    24.    
    25.     Print I 'Returns 5
    26.  
    27. End Sub

    You would see that ByVal did not make the variable I equal 5. It stayed the same value as it was before. But when I used ByRef, it made I equal 5. Hope this helps.

  6. #6

    Thread Starter
    Hyperactive Member notquitehere188's Avatar
    Join Date
    Dec 2004
    Posts
    403

    Re: About as bad as it can be

    it does indeed
    It's not just Good, It's Good enough!



    Spelling Eludes Me

  7. #7
    Hyperactive Member Maven's Avatar
    Join Date
    Feb 2003
    Location
    Greeneville, TN
    Posts
    322

    Re: About as bad as it can be

    Quote Originally Posted by notquitehere188
    [Highlight=VB] Public Sub Collision()
    This is my collision sub, it checks (almost) every collision in my game however it is VERY redundant as you can see but i cant figure out how to shrink it

    also note that collide is a function elsewhere in the code for finding if two things are actually touching where the majority of this code is for objects moving over something and finding if and where they should have hit

    and if you were wondering, that is the bulletcollideeffects sub
    Well the first thing I noticed is that you're using divison a lot with a variable called M. After you setup M, dividie it into 1 one time. After that use multiplication to get you're divison results.

    Tx = (B - Ty) * -M
    Tbx = (BB - Ty) * -M

    You may have to use an extra variable but you'll be trading 8 division instructions for 8 multiplication instuctions. Should give you an instant speedup.
    Education is an admirable thing, but it is well to remember from time to time that nothing that is worth knowing can be taught. - Oscar Wilde

  8. #8
    Hyperactive Member Maven's Avatar
    Join Date
    Feb 2003
    Location
    Greeneville, TN
    Posts
    322

    Re: About as bad as it can be

    Quote Originally Posted by Maven
    Well the first thing I noticed is that you're using divison a lot with a variable called M. After you setup M, dividie it into 1 one time. After that use multiplication to get you're divison results.

    Tx = (B - Ty) * -M
    Tbx = (BB - Ty) * -M

    You may have to use an extra variable but you'll be trading 8 division instructions for 8 multiplication instuctions. Should give you an instant speedup.
    In fact if the following doesn't change with every iteration of the loop, then i would move it outside of the loops and setup the above suggestion outside of the loop.

    M = .Yinertia / .Xinertia 'find slope
    Education is an admirable thing, but it is well to remember from time to time that nothing that is worth knowing can be taught. - Oscar Wilde

  9. #9
    Hyperactive Member
    Join Date
    Jul 2002
    Location
    WGTN, New Zealand
    Posts
    338

    Re: About as bad as it can be

    Quote Originally Posted by Jacob Roman
    Show the code where you declared your variables (all of them that are in these Subs) so I can see what data types you are using.

    Here is one area you can increase some speed. The Cos() and Sin() functions. Rather than using them, let's create some lookup tables. This is based on Andre Lamothe's code in my Tricks of the 3D Game Programming Gurus book written by him.

    VB Code:
    1. Public Const PI As Double = 3.14159265358979 '4 * Atn(1)
    2.  
    3. Public Cos_Look_Up_Table(361) As Single
    4. Public Sin_Look_Up_Table(361) As Single
    5.  
    6. Public Sub Build_Sin_Cos_Tables()
    7.  
    8.     Dim Angle As Long
    9.    
    10.     For Angle = 0 To 360
    11.    
    12.         Dim Theta As Single
    13.    
    14.         Theta = Angle * PI / 180
    15.    
    16.         Cos_Look_Up_Table(Angle) = Cos(Theta)
    17.         Sin_Look_Up_Table(Angle) = Sin(Theta)
    18.    
    19.     Next Angle
    20.    
    21. End Sub
    22.  
    23. Public Function Fast_Cos(ByVal Theta As Single) As Single
    24.  
    25.     Theta = Theta Mod 360
    26.    
    27.     If Theta < 0 Then Theta = Theta + 360
    28.    
    29.     Dim Theta_Integer As Long
    30.     Dim Theta_Fraction As Single
    31.    
    32.     Theta_Integer = Theta
    33.     Theta_Fraction = Theta - Theta_Integer
    34.    
    35.     Fast_Cos = Cos_Look_Up_Table(Theta_Integer) + Theta_Fraction * (Cos_Look_Up_Table(Theta_Integer + 1) - Cos_Look_Up_Table(Theta_Integer))
    36.    
    37. End Function
    38.  
    39. Public Function Fast_Sin(ByVal Theta As Single) As Single
    40.  
    41.     Theta = Theta Mod 360
    42.    
    43.     If Theta < 0 Then Theta = Theta + 360
    44.  
    45.     Dim Theta_Integer As Long
    46.     Dim Theta_Fraction As Single
    47.    
    48.     Theta_Integer = Theta
    49.     Theta_Fraction = Theta - Theta_Integer
    50.    
    51.     Fast_Sin = Sin_Look_Up_Table(Theta_Integer) + Theta_Fraction * (Sin_Look_Up_Table(Theta_Integer + 1) - Sin_Look_Up_Table(Theta_Integer))
    52.    
    53. End Function


    Then you add the line Build_Sin_Cos_Tables in the area where you initialize everything to build a look up table, and then use Fast_Cos() and Fast_Sin() in replace of your Cos() and Sin() functions.

    Another area to improve is this area:

    VB Code:
    1. BulletCollideEffects(BulletNum As Integer, X As Integer, Y As Integer, WhoHit As Bltty, HitSide As Boolean)

    Never use the Integer data type unless it's needed, like for example, API's. For a good speed difference, use the Long data type. Here are the reasons. 1) Don't have to worry about overflow that much. 2) Your CPU processor in your computer is 32 bit, and works with 32 bit variables faster. The Long data type is 4 bytes (32 bits) while the Integer data type is only 2 bytes (16 bits), and the processor will have to convert it in order to accomidate.

    And also be sure to either include ByVal or ByRef. Leaving it blank, although by default it'll be ByRef, every time the function is called, it's somewhat slower. Using ByVal is faster. Only use ByRef if your varables in your arguements are gonna be returning a result. Only thing is though you can't use ByVal on variables that are User Defined Types, such as Blitty.

    Now I got that out of the way, here is your new and improved Sub setup:

    VB Code:
    1. BulletCollideEffects(ByVal BulletNum As Long, ByVal  X As Long, ByVal Y As Long, WhoHit As Bltty, ByVal HitSide As Boolean)

    The amount of calculations (especially the conversion between integer and floating points) by far exceeds the normal amount of work done using the floating-point processor alone.

    It is far wiser to stay using doubles or singles than to constantly convert between to and from integer formats. The process of loading an integer into a floating-point register is long enough; and the floating-point processor already has an instruction to calculate the sine of the value in the register. This is far more efficient than constantly converting between two types and jumping around memory, and adding latency by performing extra calculations.

    Consider the following and assume x, a and b are integers:

    x = 1.5 * b - a + 3

    We could load all constants into the floating point registers, which would be highly inefficient, but we would still acheive results (inefficient because we would have to convert the result back to integers). Instead, we could cast the result of the floating point calculation so that it forces the remaining calculations to be done with integer operations. This is quicker than allowing all operands to be converted to floating point.

    x = CLng(1.5 * b) - a + 3

    Bearing this in mind, you could save on latency times, and just the tiniest improvements can go a long way in a lengthy loop.

    I can see how the sine tables would improve performance on a CPU without an FPU co-processor, but even the AMD efficiency guide shows you should never use tables for sine.
    Last edited by Dreamlax; May 3rd, 2005 at 04:53 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width