Over the last few weeks I've been working on the basics of a platformer in polar coordinates, and I though I'd share some of my progress.
The project started when I thought about how to draw circles without using huge amounts of vertices. Obviously, the closest you can get to a perfect circle is drawing it pixel-perfect, so I was looking for a way of producing circles through a shader, and not with geometry.
In the end, I came up with a shader that takes a source image and maps it onto a polar coordinate system. This way, any straight horizontal line on the source image would come out as a perfect circle!
Specifically, the 'x' coordinate in the source image becomes the radius around the circle, and the 'y' coordinate becomes the radius from the center of the circle.
(As it turns out, the wikipedia page about polar coordinates has a file explaining this process, so check it out for a step-by-step explanation)
The initial version of the shader was written on shadertoy, which is amazing if you want to quickly test some idea for a shader. The results from there were already quite nice:
For the curious, a (slightly modified) version of this shader is available here.
I also started playing with tweening between cartesian and polar coordinates:
With the shader in place, I started a luxe project where I ported it over and used it for everything shown on screen.
My first result was good, but there was a slight problem with lines originating from the center:
The problem here was that at the center, only a few pixels had to display the full range of the source image. But after a few hours of thinking, some maths and a walk through the woods (those seem to help) I was able to fix it by sampling the source image at two additional positions with an offset, so that the pixels at the center would pick up the lines as well:
(While fixing this problem, some nice debugging visuals happened as well: )
I also added a nice effect that swaps around the way the source image is mapped onto the radius of the circle. The top of the source image is either the outer edge of the circle, the center, or anything in-between when tweening between the two:
The final shader for this can be found here. It requires a bit more setup on the luxe side, but I tried to document all the variables as best as possible. For some code on how to use screen-wide shaders, also take a look at the parrott sample.
Once the shader was done, the next thing to decide was what to do with it. Since I had been working on some platformer physics code before, I decided that a platformer on a circle could be fun.
I had to fix up some parts, and add a few parts, but when I was done I got a basic platformer together:
The collision code is actually a custom PhysicsEngine that directly integrates into the luxe physics systems (luxe architecture being really useful again). It is very specific to my needs, and quite rough around the edges, but if people want to have a look, the code is available here.
Putting it all together
Putting the two parts together was mostly just copying over files and adding a few lines. The only big thing was adding screen wrapping between the left and right side of the screen, which in the circle representation are right next to each other and should therefore not have an 'invisible wall' between each other.
Once that was done, the basic polar platformer was done!
I also added the circle inversion effect back in, which in the platformer inverts the whole world. I'm especially excited about the possibilities this mechanic opens up!
And that's the state this prototype is at right now. I'm hoping to add loads more to it in the coming days and weeks and make an actual game out of it! I hope I'll post further progress here again, but if you want to see the progress right when it happens, you can follow mere on twitter @KeyMaster_.
Thanks for reading, let me know your thoughts in the comments, and until next time!