How Animations Work in KAPLAY
This posts assumes basic knowledge of the KAPLAY library, a library for making games in JavaScript. If you want to learn it, check out my YouTube channel for project based tutorials here and/or check out the library’s docs here.
A topic that comes up again and again is how animations work in KAPLAY. While the API for handling animations is very easy to use, it might, at first, not be intuitive to some.
My goal in this post is to make you familiar with the basics so that you can start putting animations in your games. As for the details, you can later check the KAPLAY docs or join the KAPLAY discord if you need to achieve something more specific.
To be able to play an animation in your game, you need to first package every frame in a single image. This is what’s known as a spritesheet. Down below, is an example.
Before you write any code, you need to make sure that every frame in your spritesheet is properly spaced out. In the example above, every sprite is contained in an imaginary square of 64 by 64 pixels. For a given animation, let’s say frame 0 to 5, each sprite must be roughly in the same position within the square otherwise, your animation will be jittery during playback.
In the image, I’ve outlined each square just for demonstration, they shouldn’t be visible in your spritesheet.
Once this is done, you can load a spritesheet and set the animations you need using the following code. I’ll break it down in the next few paragraphs.
k.loadSprite("dog", "./graphics/dog.png", {
sliceX: 4,
sliceY: 3,
anims: {
search: { from: 0, to: 3, speed: 6, loop: true },
snif: { from: 4, to: 5, speed: 4, loop: true },
detect: 6,
jump: { from: 7, to: 8, speed: 6 },
catch: 9,
mock: { from: 10, to: 11, loop: true },
},
});
Here we’re using the usual loadSprite
function but with a third param where we pass an object to tell KAPLAY how to slice the image into individual frames and which frames to play for each animation.
Let’s take another look at the image I’ve shown earlier.
For KAPLAY to know how to slice the spritesheet into individual frames, it expects us to provide it with the sliceX
and sliceY
properties.
Since there are 4 frames on the X
axis, we need to set the sliceX : 4
. Likewise, on the Y
axis we have 3 frames and therefore, we need to set sliceY: 3
.
Now that KAPLAY can slice the spritesheet, it will assign a number to each frame starting from the top left corner. As you noticed, the first frame is numbered starting from 0 and not 1. It’s important to keep this in mind when setting animations.
How Animations are Set
Now we still need to define our animations for the dog. To achieve this, we had to create an anims
property and specify a few things. Let’s take a closer look.
// previous code omitted for clarity.
anims: {
search: { from: 0, to: 3, speed: 6, loop: true },
snif: { from: 4, to: 5, speed: 4, loop: true },
detect: 6,
jump: { from: 7, to: 8, speed: 6 },
catch: 9,
mock: { from: 10, to: 11, loop: true },
},
// subsequent code omitted for clarity.
The first animation we defined is the search
animation. The key you decide to use will determine the animation name. You’re free to pick whatever valid key in JS you want as the name.
As for the value, we pass an object with 4 properties :
from
determines the starting frame of the animation. In our case, the first animation starts at frame 0.to
determines the last frame of the animation.speed
determines how fast the animation should play in frames per second.loop
determines if the animation should play indefinitely.
speed
and loop
are optional. If not specified, the animation will play at a default speed (I’m not sure exactly but it seems to display at a number of frames in anim/second). If loop
is not specified, the animation will only play once.
While setting animations usually works like just shown, sometimes, you want to display only a single frame as your animation. In that case, no need to pass an object because you can immediately pass the frame number. This is what we do for both the detect
and catch
animations.
How to Play Animations
Let’s assume you have a game object ready with the sprite component.
k.add([
k.sprite("dog"),
k.anchor("center"),
k.pos(k.center())
]);
If you want to play an animation by default when the game object is created you can do :
k.add([
k.sprite("dog", { anim: "search" }),
k.anchor("center"),
k.pos(k.center()),
]);
This is best used for animations that loop indefinitely.
If you want to play another animation later, use the game object’s play
method like this :
const dog = k.add([
k.sprite("dog", { anim: "search" }),
k.anchor("center"),
k.pos(k.center()),
]);
k.wait(2, () => { // wait two seconds before switching anim
dog.play("snif");
});
How to Stop an Animation
To stop animation, simply call the game object’s stop
method.
const dog = k.add([
k.sprite("dog", { anim: "search" }),
k.anchor("center"),
k.pos(k.center()),
]);
k.wait(2, () => { // wait two seconds before stopping anim
dog.stop();
});
Flipping an Animation
To flip an animation (a.k.a. mirroring) you can set the flipX
property to flip your sprite horizontally or use the flipY
property to flip your sprite vertically.
// previous code omitted for clarity
dog.flipX = true;
// or
dog.flipY = true;
How to Know Which Animation is Currently Playing
You can achieve this by using the getCurAnim
method which returns an object with the various properties of the current animation.
In practice, you’d like to know the current animation’s name so that you can determine which animation to switch to. To achieve this, you can do this :
const curAnimName = dog.getCurAnim().name
if (curAnimName === "snif") {
dog.play("detect");
}
Conclusion
We’ve covered the basics of how animations work in KAPLAY and this might be sufficient for a lot of projects. However, if you’d like to dive deeper into all the options and methods you can use for animations, check out this page in the KAPLAY docs.
If you enjoyed this post and want more like it, consider subscribing to not miss out on future releases.
Here are previous posts I’ve written that might peak your interest!