This looks so cool. Hope you release this game eventually!
With a little fiddly bit of animation trickery, I have smooth looking movement in Resonant Tale:
It's still tile-based movement, you're still moving on the grid, it's just smoothly(ish) animated as you move from one tile to another.
With Pulp running at 20 fps I had to play around with how many pixels per frame to move to get something that was both smooth and gives a decent movement speed.
Wow, willing to share how you did this? Does this require a separate version of every tile you walk on with the player on it as an animation or did you find a clear solution?
Fortunately not, thanks to player tiles supporting transparency. I'll try my best to briefly explain my approach (and maybe I'm missing a trick to simplify the animation!).
First I have a few variables keeping track of the player's position and direction, which is useful for checking when the player's position has changed and for making sure the player tile matches the direction.
Originally I was updating these at the end of the player's update
event like:
posx = event.px
posy = event.py
pdx = event.dx
pdy = event.dy
However that was causing a minor bug as it turns out update
is called before the player is moved when stepping onto an exit - event.px
, event.py
and event.room
will all report the player's position when stepping onto the exit, not after being moved by the exit. I moved the position tracking to the end of the player's draw
event instead to fix this (the direction tracking stayed in update
as it is more limited in which events it is available).
Anyway, the reason that is useful is because during the update
event I check if the player's position has changed by comparing my tracked variables and what is reported by event.px
and event.py
. If they are different I set a variable called player_moving_frame
to 1
and call ignore
. The variable flags that the game should animate movement (and I also use it to know what animation frame to use each game frame - more on that later) while the ignore
is just to prevent any more input until the movement animation is complete.
I want my player to be animated at 2 fps, but because I'm going to be drawing some player tiles directly to the screen as frames I can't just rely on Pulp's fps config - I need to manually sync the animation myself. So in the game's loop
event I have a generic counter that restarts every 20 frames (1 second):
counter20++
if counter20==20 then
counter20 = 0
end
Then at the start of my player draw
event I have:
if counter20<10 then
player_frame = 0
else
player_frame = 1
end
Then I have my animation handling inside a conditional on player_moving_frame>=0
.
Here comes the fiddly bit - the player tiles.
To smoothly animate I need to have 2 tiles animating together, one for the player "entering" at their new position and one for "exiting" their old position.
"Enter" is the easier half. As it's the actual player tile, I can swap it and then set the frame like this:
swap "player enter {pdx}{pdy} {player_frame}"
frame player_moving_frame
I have animated tiles set to 0 fps for all four directions and for both animation states. Those tiles have 7 frames each moving the player 1 pixel at a time further into the tile, the rest is transparency.
"Exiting" is more difficult, because rather than swapping the player tile I have to draw the exiting animation to the player's previous position. As far as I can tell, you can't specify a frame when drawing a tile. This means that instead of 8 tiles with 7 frames of animation each, I have 56 player tiles each with a single frame. I then choose exactly which tile to draw like so:
draw "player exit {pdx}{pdy} {player_frame} {player_moving_frame}" at x,y
Fear not - I don't actually end up using most of those tiles! Having them all lets you smoothly animate movement 1 pixel at a time. At 20 fps this felt too slow, so I ended up incrementing player_moving_frame
by 2 every frame. Like this:
player_moving_frame += 2
if player_moving_frame>6 then
player_moving_frame = -1
listen
end
So for my animation I only actually go through frames 1, 3 and 5.
There were a few other fixes I had to do but that's the crux of it. I'll see if I can just cut out that code specifically and share the json so you can take a look, if you're interested!
Oh wow, so draw can actually draw transparent tiles too. I didn't know that. Too bad that the player exiting still has to be single tiles instead of frames. Still makes it a little hacky unfortunately. Let's ask if we can get frame settings support for draw! That will probably cleanup your code too.
Here's a demo project you can import:
Smooth Movement Demo.zip (5.3 KB)
I made it so you can press A to toggle smooth movement on/off, and press B to cycle between different movement/animation speeds.
Thank you so much. Great example project! For now this is probably one of the cleanest workarounds possible!
A little update:
I'm pretty happy with how the transitions through the tunnels look and with how smoothed movement looks with the player being hidden behind scenery.
love the little up / down the ladder animations !!
What do you mean Pulp wasn't made for side-scrolling platformers?
Scrolling Platformer Demo.zip (2.9 KB)
This was fun to work out! I tried to keep the code to a minimum and really lean on what Pulp already offers. It's certainly no Mario (shamelessly stolen level layout for this demo aside) but it's not unplayable!
The trick to "screen-scrolling" is in Pulp's follow config and using edge exits set several tiles into the screen to sew together multiple rooms with overlapping layouts. Then I simply used crop
to add the black bars on either side of the screen to hide that room switching from sight! If you load up the json and comment out the crop command in the game script it makes the whole thing very obvious (and is actually a kind of cool looking effect).
The platforming is very rough-and-ready as the jump curve is less of a curve and more of a triangle, but hey the player goes up-and-down and it's not awful (ymmv!).
Unfortunately it seems the player confirm
and cancel
events for pressing the A and B buttons don't fire repeatedly when held no matter the Pulp config, so my idea for varying jump height by how long the button was held was scrapped. Instead I made both A and B do a jump, but the B jump is shorter!
Very infrequently, I've not yet joined the server for playdate/pulp. Definitely more of a forum than chat person I'm afraid!
Introducing Tile Hill - a tile-based sort-of-side-scrolling proof-of-concept platformer in Pulp!
I adjusted the jump curve to feel more natural, and made the jump height with the A button depend on how long of a run up you take. The B button always does the smallest jump so you can still hop at speed. Also - semi-solid platforms!
I added slopes that can be run up-and-down. You can also press down to slide down a slope!
Spikes are, naturally, deadly to any platforming hero. I also made some circular saws which aren't in the demo but are in the editor - the difference is that spikes are only deadly on vertical collisions, but the saw is deadly from any direction.
Finally I added springs. They preserve vertical velocity, so you will bounce off them up to the same height you fell from.
Here's the JSON if you'd like to play with it and see how it is put together
Tile Hill.zip (7.4 KB)
You're doing fantastic work here!
A Doodle Sketch toy - draw with the d-pad and wipe clean with the crank (that is, for all my artistic ability, supposed to be a playdate )
A sneak peek of Pulpino - an even tinier in-game editor made in Pulp!
Moving the cursor "off-screen" makes the HUD show in the editor, but the B button also quickly cycles between tools and the crank will change selected tile. Docking the crank switches to game mode (and undocking it back to the editor).
Not sure how far I'd like to take this. Adding more tiles, certainly, and a HUD for changing rooms on the left. Maybe text input would be cool! I'm not sure how feasible actually saving creations will be - it'd mean a store variable for every tile I guess, which sounds painful!
Edit - and here is the move tool and switching rooms:
Pulpino is now close to something-like-v1...
The objective of any level is to collect all of the floppy disks and get to the computer. As well as solid walls you can place ice (the player slides in the direction of movement), conveyor belts (they move the player in their direction of travel), switch blocks (that are either solid or non-solid), and switches (that are triggered when the player stands on them).
The biggest downside at the moment is not being able to save any creations between play sessions. I'm not sure if there is a good approach to that other than recording every tile in every room...
Nice work on Pulpino so far! I really like the interactable objects and the slide-out menu design.
(Also, you may already know about this, but there is a tool called Pulp Mill that allows you to translate Pulp .json into Lua, so you can work in some saving/loading functions that way)
Using Pulp Mill so I can handle saving/loading in Lua is a very sensible suggestion, but I worry it would compromise the entire concept of making an even smaller game editor in Pulp if it isn't really all done in Pulp. I'm in a corner of my own making
I've got to the point with Pulpino where I really need to test out the performance on an actual Playdate - the only problem being I don't have one yet!
Would anyone lucky enough to have a console be willing to test out the pdx for me?
I'm specifically interested in:
- General in-editor performance (due to drawing the HUD)
- Using the bucket tool, especially when filling large areas of a room
- Using the move tool
- Saving and reloading, especially after making changes in all rooms (using the move tool in each room would be a quick way of making sure all of the tile values have been stored)
I suspect the bucket and move tools may have problems. I really hope saving doesn't!
Here is a zip of the pdx: Pulpino.pdx.zip (156.4 KB)
Edit: A couple of kind people over on discord have tried it out for me. As suspected the bucket and move tools noticeably struggle, reportedly taking 3-5 seconds to process, which is unfortunate but not world-ending, and otherwise the performance sounds ok! I'll see what I can do to improve performance, although it might have to wait until I have my console so I can test first hand.