In part 1, we covered the principle of game frame rate and a useful game programming pattern for performance. This part shows the detailed implementation of a game scene with hundreds of moving characters using Android Studio and Kotlin.
Image asset
This game uses a free image from wild-refuge.net.

You can download any similar image (4 x 4 frames) and place it in the res/drawable
of Android project.
The gameloop
interface
For simplicity, we create a minimal game loop. In a real game, you should implement additional methods to synchronize with view life-cycle (Android/iOS).
interface GameLoop {
fun draw()
fun update()
}
The Sprite
class
This class handle the appearance of a character as well as its movement. It has its own thread to update the walking animation. The declaration of the class and some related fields look like this:
class Sprite : Runnable {
private val frameInterval = 1000L/4
var movingDirection = Direction.DOWN
private var frameToDraw = 0
private var frameSize: Point
private var sprite: Bitmap
private var dst: Rect
private var src: Rect
private val pace = 1
//...
}
There will be two animations in this class, the walking animation and the movement. The walking animation has 4fps meanwhile the moving pace is 1 pixel every update. We continue with a constructor which prepare the bitmap and frame to draw. The draw method draws an src
frame to the dst
rectangle. The setDst method set the character to a specified location.
constructor(ctx: Context, id: Int, n_horizontal: Int = 4, n_vertical: Int = 4) {
sprite = BitmapFactory.decodeResource(ctx.resources, id)
frameSize = Point(sprite.width / n_horizontal, sprite.height / n_vertical)
dst = Rect(0, 0, frameSize.x, frameSize.y)
src = Rect(0, 0, frameSize.x, frameSize.y)
Thread(this).start()
}
fun draw(canvas: Canvas) {
canvas.drawBitmap(sprite, src, dst, null)
}
fun setDst(p: Point){
this.dst.set(p.x - dst.width()/2, p.y - dst.height()/2, p.x + dst.width()/2, p.y + dst.height()/2)
}
The function move
will be called within the update
method of class GameView
.
fun move(){
when (movingDirection) {
Direction.RIGHT -> {
dst.right += pace
dst.left += pace
}
Direction.LEFT -> {
dst.right -= pace
dst.left -= pace
}
Direction.UP -> {
dst.top -= pace
dst.bottom -= pace
}
Direction.DOWN -> {
dst.top += pace
dst.bottom += pace
}
}
}
The GameView
class
This class manage all the game objects including sprites, obstacles, etc. Similar to Sprite class, this class has its own thread where we implement a game loop.
class GameView : SurfaceView, Runnable, SurfaceHolder.Callback, GameLoop {
private var sprites = ArrayList<Sprite>()
private var mCanvas: Canvas? = null
private var mHolder: SurfaceHolder? = null
private var mThread: Thread
private var myGestureDetector: GestureDetector
val FRAME_RATE = 60
val MS_PER_SECOND = 1000L / FRAME_RATE
constructor(ctx: Context) : super(ctx)
constructor(context: Context?, attributeSet: AttributeSet) : super(context, attributeSet)
init {
mHolder = holder
myGestureDetector = GestureDetector(context, MyGestureListener())
mHolder?.addCallback(this)
mThread = Thread(this)
mThread.start()
}
//...
}
We implement the update
and draw
methods from the game loop interface to update and draw all sprites stored in an array list.
override fun draw() {
mCanvas?.drawColor(Color.WHITE)
for (sprite in sprites)
sprite.draw(mCanvas!!)
}
override fun update() {
for (sprite in sprites)
sprite.move()
}
Next, we implement the game loop as mentioned in part 1.
override fun run() {
var previous = System.currentTimeMillis()
var lag = 0.0
while (true) {
val current = System.currentTimeMillis()
val elapsed = current - previous
previous = current.toLong()
lag += elapsed
if (mHolder?.surface?.isValid!!) {
mCanvas = mHolder?.lockCanvas()
synchronized(sprites)
{
while (lag >= MS_PER_SECOND) {
update()
lag -= MS_PER_SECOND;
}
draw()
}
mHolder?.unlockCanvasAndPost(mCanvas)
}
}
}
There are synchronized blocks to avoid the concurrentmodificationexception
as we add new sprites with taps.
We also added some code for gesture detection. A single tap will place a new sprite on the screen and a double-tap will change all sprites’ moving direction.
And the animation result

To sum up
This article demonstrates the implementation of a game loop pattern for enhancing the animations of a video game. You can find the source code below.
Source code: Github