Game loop in Vue
Posted on
by Kevin FoongHere is how to do a game or animation loop in Vue using Javascript's "requestAnimationFrame" method.
So what is requestAnimationFrame?
requestAnimationFrame
is a method that is part of the very large Web API's under the Window Interface. See this page for more information - https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame
This method provides a callback, typically to the function it is in, to create a recursive loop that can achieve up to 60 frames per second. I've created a very simple growing box animation in Vue to demonstrate.
Some key points,
- You need to pass into requestAnimationFrame(), a callback, which is the function that
requestAnimationFrame()
is in, in order to create a recursive loop. requestAnimationFrame()
returns an object which you need to pass in tocancelAnimationFrame()
in order to stop the animation.- You don't necessarily need both an
animate()
and adraw()
method separately. You can combine them both into one method. One use case for having separate methods is when you want to useanimate()
for calculating the position of your objects anddraw()
for only rendering them. - You need a way to trigger the animation. In the below we used a button to start and stop the animation.
- If you want to slow down the animation you may also want to introduce a timer and only call
draw()
at certain intervals. Take a look at this from Stack Overflow which describes how you can do this.
A full example of requestAnimationFrame in action can be seen in my Whack the Mole! game here.
The full source code is below.
<template>
<div>
<button @click="buttonClick">Toggle animation</button>
<div
style="background-color:blue;"
:style="{
'width': sizeW + 'px',
'height': sizeH + 'px'
}">
</div>
<p>Some text</p>
</div>
</template>
<script>
export default {
name: 'Game',
data() {
return {
request: '', // requestAnimationFrame
btnToggle: true,
sizeW: 10,
sizeH: 10
}
},
methods: {
animate() {
this.request = requestAnimationFrame(this.animate)
this.draw()
},
draw() {
this.sizeW += 1
this.sizeH += 1
if (this.sizeW > 300) this.sizeW = 10
if (this.sizeH > 300) this.sizeH = 10
},
buttonClick() {
if (this.btnToggle) {
this.btnToggle = false
this.animate()
} else {
this.btnToggle = true
cancelAnimationFrame(this.request)
}
}
}
}
</script>
Tags: games Vue Javascript