<aside> 💡 js13k is 30-day competition to create a browser game in 13kb of code or less. I am documenting my project here and on twitter.
</aside>
Related Posts
Pt 1: Theme Announcement & Project Setup
Pt 2: Writing a 3D Engine (after trying not to)
Pt 3: Using Bitmap Caching to Unlock 60fps in 3 Dimensions
As a challenge to myself this year, I wanted to make a game that uses an axonometric projection to achieve an engaging top-down effect. As a consolation for making this reckless decision, I convinced myself that if I did it right, I could make simple conversions from "map space" to "screen space", and just run each point through a formula or two, switching back from a true top-down view, to an angled one, with ease.
Nine Parchments has a great top-down game style that works wonders for its combat and immersive environment
This works pretty well up to a point. I started off by converting my square tiles to an axonometric projection and was indeed deceived by how simple it was. I could avoid 3D entirely and simply use these formulas to achieve the effect below:
// <http://clintbellanger.net/articles/isometric_math/>
map.x = screen.x / TILE_WIDTH + screen.y / TILE_HEIGHT;
map.y = screen.y / TILE_HEIGHT - screen.x / TILE_WIDTH;
http://clintbellanger.net/articles/isometric_math/
The issue is that I don't just want to make a map. I want put stuff on it. And that stuff has a 3rd dimension. So when I started trying to place cubes on my map I got frustrated when they wouldn't abide by the simple math I had been using to place tiles.
Of course, the math was only simple because I was using a single rotation of a 2d object, and then approximating a second rotation by using a shortcut that states that the width of a square becomes twice the height of a square in certain axonometric projections.
// drawing a square isn't so hard
drawLines([
new Vector3(0, 0),
new Vector3(500, 0),
new Vector3(500, 500),
new Vector3(0, 500),
new Vector3(0, 0)
]);
/*
thinking I'm a genius because
I found a isometric projection
shortcut and these numbers made
sense in my head
*/
drawLines([
new Vector3(0, 250),
new Vector3(500, 0),
new Vector3(1000, 250),
new Vector3(500, 500),
new Vector3(0, 250)
]);
But what about a cube? Would I be able to find a simple conversion to account for the z coordinate as well? What about the character I wanted to draw? And the environment and game objects?
The short story is no, there's a reason we use proper math to describe rotations, and it took me a while to figure that out. If I had the space I could draw and pre-render all of my art and assets to fit the isometric style, but I don't have the space given that the game must be done in 13k. As such, it seemed that counter-intuitively, the most concise way to achieve was I was after was to build a basic camera and 3D renderer from scratch.