Here's how I did smooth animation or "decimal draw" as we call it, for the game I'm working on.
Space Dreamer!
The variables you'll need:
on load do
// This will prevent the player sprite from lagging behind when the button is held
config.inputRepeatDelay = 0.2
config.inputRepeatBetween = 0.2
// This will be the target position that the sprite will be moving to
playerX = 0
// This will be the position our sprite will be drawn
playerDecimalX = playerX
// How much the sprite will move every frame in "pixels"
movementSpeed = 0.25
end
The movement speed variable only has a few values that work. It must also be able to add up to a whole number; if not, it will cause jittering of the player sprite.
For the movement of the player:
on update do
if event.dx==1 then
playerX++
elseif event.dx==-1 then
playerX--
end
end
The player might also lag behind when the button is repeatedly pressed, so you might have to do this instead:
on update do
frameElapsedMoveCheck = event.frame
frameElapsedMoveCheck -= frameElapsedMove
// This is calculated by the delay in secs
// 0.2 secs (config.inputRepeatBetween's value) * 20 frames = 4 frame delay
if frameElapsedMoveCheck>=4 then
if event.dx==1 then
playerX++
frameElapsedMove = event.frame
elseif event.dx==-1 then
playerX--
frameElapsedMove = event.frame
end
end
end
To achieve smooth animation:
on draw do
// The playerDecimalX will be increased/decreased as long as it isn't equivalent to playerX
if playerDecimalX<playerX then
playerDecimalX += movementSpeed
elseif playerDecimalX>playerX then
playerDecimalX -= movementSpeed
else
playerDecimalX = playerX
end
draw "player" at playerDecimalX, 7
end
The y-axis could be done easily by doing the same thing. For the game I'm making, I only have to use the x-axis.
The result of the code thus far will be this.
Yeah, it doesn't look good.
Because it isn't meant for Pulp, a trail of artifacts / rectangles are created when moving. To fix this, there are two ways:
First, is to update the tile in the background and draw it before the player.
on draw do
// Since the trail is behind the player you'll have to do this
x = playerX
x--
// Gets the name of the tile behind the player sprite and draws it, cleaning the artifacts
checkTileName = name x,7
draw checkTileName at x,7
// Then draw the player
if playerDecimalX<playerX then
playerDecimalX += movementSpeed
elseif playerDecimalX>playerX then
playerDecimalX -= movementSpeed
else
playerDecimalX = playerX
end
draw "player" at playerDecimalX, 7
on
If your player sprite has transparency in the middle or has a slower speed, you'll have to clean both behind and in front of the player.
Pro:
- Optimizable Performance
Cons:
- A lot of code to write*
- Many bugs
There might be a lot of code to write, especially if you have many sprites; you'll have to write code to clean the artifacts for every single one. The loss of performance for this method scales with how much it is used, but with a bit of optimization and also depending on the kind of game you're making, it could be a better option.
Second, is to use a tile for a background that will update every frame.
2 frames with 20 fps
Pro:
- No code required
Cons:
- Overall decrease in performance
- Animating tiles in 20 fps
This is what I used for my game. It requires the least amount of effort, and because my game will have many entities and enemies that will be drawn on the screen, I don't have to write code for them. However, the tiles will always be updated even though there's no sprite being drawn, resulting to a loss in performance.
And that's it! There's a lot more going on in the example gifs, but that's basically how to do smooth animation in Pulp. I look forward to seeing more amazing games that utilize this.