Very Low FPS

sterlingy

Active Member
Licensed User
Longtime User
I've built a test app, which is very stripped down, to check some functionality. I'm moving about 60 bitmaps (all identical) around the screen. There is some math required because of the AI used to move them, but it isn't anything extraordinary.

I'm getting about 7FPS, which is ridiculously low. I've stepped through the code and don't see anything getting hung up.

Is there a way to count cycles, or a way to know how much time certain operations take?

Cheers,

Sterling
 

sterlingy

Active Member
Licensed User
Longtime User
See this example: GameView - Create 2D Android games - Part I

You should get about 60 fps.

Sure that works. The problem is not in the rendering, it's in my AI code, which consists of a Vector2D class. This does every conceivable math operation between vectors, and I have a vehicle class, that initializes several vectors on each Tick, and runs the AI, which makes several calls to the Vector2D class to calculate position, speed and heading for my objects.

I ported the code from AS3, but I've seen the same code in Java and C++. They all seem identical, with the exception of having to initialize.

Could the initialization be seriously slowing down the code?

-Sterling
 
Upvote 0

sterlingy

Active Member
Licensed User
Longtime User
Here's the relevant code for my problem

The GameManager calls the AI "seek" sub
B4X:
fish.seek(fishDest.cloneVector)

fish and fishDest are declared as the Vehicle class, and in my test, seeks a Vector2D Shown here:
B4X:
'Class module
Sub Class_Globals

Private Vector2DX As Double
Private Vector2DY As Double

   
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize (x As Double, y As Double)

   Vector2DX = x
   Vector2DY = y

End Sub

'      /**
'       * Creates an exact copy of this Vector2D prob
'       * @Return Vector2D A copy of this Vector2D
'       */
Public Sub cloneVector As Vector2D
   Dim newVector As Vector2D
   newVector.Initialize(Vector2DX, Vector2DY)
   Return newVector
End Sub


'      /**
'       * Is the vector's length = 1?
'       * @Return Boolean If length Is 1, True, Else False.
'       */
Public Sub isNormalized
   If getlength = 1 Then
      Return True
   Else 
      Return False
   End If
End Sub
      

      
'      /**
'       * Sets the length which will change x AND y, but Not the angle.
'       */
Public Sub setlength(value As Double)
   Dim Vector2Dangle As Double
   Vector2Dangle = getAngle
   Vector2DX = Cos(Vector2Dangle) * value
   Vector2DY = Sin(Vector2Dangle) * value
   If Abs(Vector2DX) < .00000001 Then Vector2DX = 0
   If Abs(Vector2DY) < .00000001 Then Vector2DY = 0
End Sub

'      /**
'       * Returns the length of the vector.
'       **/
Public Sub getlength
   Return Sqrt(lengthSquared)
End Sub
      
'      /**
'       * Returns the length of this vector, before square root. Allows For a faster check.
'       */
Public Sub lengthSquared
   Return Vector2DX * Vector2DX + Vector2DY * Vector2DY
End Sub
      
'      /**
'       * Changes the angle of the vector. X AND Y will change, length stays the same.
'       */
Public Sub  setAngle(value As Double)
   Dim len As Double
   len = getlength
   Vector2DX = Cos(value) * len
   Vector2DY = Sin(value) * len
End Sub

'      /**
'       * Get the angle of this vector.
'       **/
Public Sub getAngle
   Return ATan2(Vector2DY, Vector2DX)
End Sub

'      /**
'       * Sets the vector's length to 1.
'       * @Return Vector2D This vector.
'       */
Public Sub normalize As Vector2D
   If getlength = 0 Then
      Vector2DX = 1
      Return Me
   End If
   
   Dim len As Double
   len = getlength
   Vector2DX = Vector2DX / len
   Vector2DY = Vector2DY / len
   Return Me
End Sub


'      /**
'       * Sets the vector's length to len.
'       * @param len The length To set it To.
'       * @Return Vector2D This vector.
'       */
Public Sub normalcate(len As Double)
   setlength(len)
   Return Me
End Sub
            
'      /**
'       * Calculate squared distance between vectors. Faster than distance.
'       * @param vector2 The other vector.
'       * @Return Number The squared distance between the vectors.
'       */
Public Sub distSQ(vector2 As Vector2D) As Double
   Dim dx As Double 
   Dim dy As Double
   
   dx = vector2.Vector2DX - Vector2DX
   dy = vector2.Vector2DY - Vector2DY
   Return (dx * dx + dy * dy)
End Sub

'      /**
'       * Add a vector To this vector.
'       * @param vector2 The vector To add To this one.
'       * @Return Vector2D This vector.
'       */
Public Sub add(vector2 As Vector2D) As Vector2D
   Vector2DX = Vector2DX + vector2.Vector2DX
   Vector2DY = Vector2DY + vector2.Vector2DY
   Return Me
End Sub
      
'      /**
'       * Subtract a vector from this one.
'       * @param vector2 The vector To subtract.
'       * @Return Vector2D This vector.
'       */
Public Sub subtract(vector2 As Vector2D) As Vector2D
   Vector2DX = Vector2DX - vector2.Vector2DX
   Vector2DY = Vector2DY - vector2.Vector2DY
   Return Me
End Sub
      
'      /**
'       * Mutiplies this vector by another one.
'       * @param scalar The scalar To multiply by.
'       * @Return Vector2D This vector, multiplied.
'       */
Public Sub multiply(scalar As Double) As Vector2D
   Vector2DX = Vector2DX * scalar
   Vector2DY = Vector2DY * scalar
   Return Me
End Sub

'      /**
'       * Divide this vector by a scalar.
'       * @param scalar The scalar To divide by.
'       * @Return Vector2D This vector.
'       */
Public Sub divide(scalar As Double) As Vector2D
   Vector2DX = Vector2DX / scalar
   Vector2DY = Vector2DY / scalar
   Return Me
End Sub
      
'      /**
'       * Set AND get y component.
'       */
Public Sub setY(value As Double)
   Vector2DY = value
End Sub

Public Sub getY
   Return Vector2DY
End Sub
      
'      /**
'       * set AND get x component.
'       */
Public Sub setX(value As Double)
   Vector2DX = value
End Sub

Public Sub getX
   Return Vector2DX
End Sub

The Vehicle class which holds the AI "seek" sub is here:
B4X:
'Class module
Sub Class_Globals
   Private vehicleMass As Double
   Private vehicleMaxSpeed As Double
   Public vehiclePosition As Vector2D
   Public vehicleVelocity As Vector2D
   
   Private vehicleInSightDist As Int   
   Private vehicleMaxForce As Double   
   Public checkLength As Double       'the distance To look ahead For circles   
   Public circleRadius As Int        'the radius of the circle   
   Public vehicleIndex As Int          'the current waypoint index In the Path Array   
   Public slowingDistance As Double     'slowing distance, you can adjust this
   Public wanderAngle As Double        'the change To the current direction. Produces sustained turned, keeps it from being jerky. Makes it smooth
   Public wanderChange As Double       'the amount To change the angle Each frame.
   
   Public screenX, screenY As Double
   
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize (scrX, scrY As Double)

   vehicleInSightDist = 25
   checkLength = 100 
   circleRadius = 6
   vehicleIndex = 0
   slowingDistance = 20
   wanderAngle = 0
   wanderChange = 1
   
   screenX = scrX
   screenY = scrY
   vehicleVelocity.Initialize(0,0)
   vehiclePosition.Initialize(scrX, scrY)
   vehicleMaxSpeed = 2
   vehicleMass = 2
End Sub

Public Sub getMass As Double
   Return vehicleMass
End Sub
      
'      /**
'       * Gets AND sets the Vehicle's mass
'       */
Public Sub setMass(value As Double)
   vehicleMass = value
End Sub

'      /**
'       * Gets AND sets the Max speed of the Vehicle
'       */
Public Sub getMaxSpeed As Double
   Return vehicleMaxSpeed
End Sub
      
Public Sub setMaxSpeed(value As Double)
   vehicleMaxSpeed = value
End Sub
      
'      /**
'       *Gets AND sets the position of the Vehicle
'       */      
      
Public Sub getPosition As Vector2D 
   Return vehiclePosition
End Sub

Public Sub setPosition(value As Vector2D)
   vehiclePosition = value
   screenX = vehiclePosition.getX
   screenY = vehiclePosition.getY
End Sub

'      /**
'       * Gets AND sets the velocity of the Vehicle
'       */
Public Sub getVelocity As Vector2D
   Return vehicleVelocity
End Sub


Public Sub setVelocity(value As Vector2D)
   vehicleVelocity = value
End Sub



' Steering Options

Public Sub seek(target As Vector2D)

   Dim desiredVelocity As Vector2D
   Dim steeringForce As Vector2D
   
'   desiredVelocity = target.subtract(vehiclePosition)
   
   desiredVelocity = target.subtract(vehiclePosition).normalize.multiply(vehicleMaxSpeed)
   steeringForce = desiredVelocity.subtract(vehicleVelocity) ' subtract velocity from the desired velocity To get the force vector
   vehicleVelocity.add(steeringForce.divide(vehicleMass)) ' divide the steeringForce by the mass(which makes it the acceleration), Then add it To velocity To get the new velocity
   vehiclePosition.add(vehicleVelocity)
End Sub
 
Last edited:
Upvote 0

sterlingy

Active Member
Licensed User
Longtime User
Attached is the project file.

You can change the number of objects on the screen by altering createFish(60) in the GameManager Init sub.

If you comment the Seek call in the MainTimer_Tick, you'll get 30FPS as one should expect.

-Sterling
 

Attachments

  • B4ASteer.zip
    19.1 KB · Views: 199
Last edited:
Upvote 0
Top