Probably the best part about programming is fixing a thing. But sometimes things can break and they actually look cooler broken. This week was pretty much that, as I fixed something, preferred it broken, and came up with systems to break it again.
But, you know, break it in a manageable way.
So, in week 1 I talked about how new levels are loaded. The camera zooms in on the player, and as the camera zooms out, it reveals the next level has loaded in space behind the current level. The camera then zooms over to the new level and play starts anew. It’s a really cool system but due to the nature of rotational matrices, the rotational value of the new level was hard to calculate, and thus sometimes the camera would have to pass right through the room’s floor to get to where it needed to be. Obviously, a problem! A problem that I fixed with way too much maths. So here we go!
Here is a new very basic level, the ending position is in the top right corner. Once the player gets there, the camera zooms in and turns 90 degrees, as the level exit is on the right hand side wall. But, when the camera pulls back, the new level is right behind it!
This gives the illusion (or, rather, will give the illusion) that the player character is just moving through a door to get to the next room. The entrance and exit positions are lined up in world space to give that illusion that the rooms are connected.
Unfortunately, that’s boring. Here’s the same pullback with a few more elements added to it.
Here you can still see the new level being generated behind the current one, but it’s not lined up correctly. It’s slanted and rotated slightly and just a slight bit further away. It adds a little bit of style to the level transitions themselves and allows a certain level of abstraction, and other words I’m using to justify this other than “it looks cool”.
So what’s happening here? First, the ‘fixed’ version.
When the level is completed and the data is getting ready to be overwritten by the new level, it saves a few crucial bits of information. It saves the level position (which is the position of the center of the level), the level width and height, and the position if the player’s ending position. When the new level is loaded in, it also gets the new level width and height, and the player starting position.
With all this data, the code calculates where the new level should be, and I’ll demonstrate that with these hastily drawn images in MS Paint.
So the old level on the left has a width and height of (3, 10), and the ending position of the player is at (2, 0) (positive Y goes down because programming). The new level has a width and height of (10, 8) and a starting position if (9, 5) (9 is the max as 10 is actually a range of 0 to 9 because programming)
The blue points are the room’s positions in world, the one on the right is the one the code figures out, in relation to the one on the left.
First! The code finds what side the starting position is on the new room. The starting position is on the right hand side, so the room is rotated 180 degrees.
It then sets the new room position to the old room position.
Then it minuses the difference between the new start position and the old room position.
Then it adds the difference between the old end position and the old room position.
Finally it adds the size of the walls to the difference, and the rooms join together perfectly.
As simple as it sounds the actual code is rather complex to account for the various combinations of rotations that can happen. But hey, at least it works!
So now it’s time to break it!
The actual breaking of the code isn’t really that interesting, it adds a random value to each rotational axis within -10 and 10, moves it down a bit and rotates it a bit more in the direction the room is rotated.
Since I can’t explain it well, here’s a few last screenshots, here’s it fixed:
Here’s it with a few extra flourishes:
And finally here’s it with some extra random:
And that’s what the room placement looks like! Hopefully next week I’ll have models to show you. I say hopefully because I haven’t modeled in over 3 years! Uh oh!