And the moral of the story is...
And the moral of the story is...
Work! Just work!
-- Watsky
Thanks for checking out the thread,
Sky! I definitely agree about the lack of reference when you're moving in an empty space. Right now the only actual tiles are the structures, so the ground is just the background color. The main concerns for adding detail are
1) levels will almost certainly be procedurally generated, so I'm concerned about how to stitch different areas together (esp. w/r/t elevation).
2) the potential memory/performance cost.
Additionally, I'd like to implement a dynamic lighting system and possibly some effects that will deliberately contribute to a sense of confusion, even getting the player lost sometimes.
All that is up in the air right now tho, so I will work on some placeholders to help with orientation! They'll be in the next update! But before that...
Hot damn! I coded a method that will translate a 3D position into 2D screen coordinates. This requires some explanation of Foregunner's camera system, which is complete garbage.
For rendering sprites, the process basically goes like this: the starting position is the X, Y of the obj's world position. This is offset by a unit vector drawn from the inverted rotation of the camera and scaled by the z-depth (i.e. altitude) of the world position. Z-depth is also used to calculate rendering depth (which eventually will be changed to a layer-by-layer rending that eliminates the need for this redundant calculation, or at least reduces the cost). Then the camera rotates the image as well as squashes it in the XY planes by the zoom scaler, and the Y plane additionally by a "Perspective" scaler (all told, the cam is controlled by Position, Zoom, Rotation, and Perspective, but Perspective is just a subcomponent of Zoom).
So this is some complicated-ass bullsh!t compared to using a normal 3d projection matrix. Why do it? Well, I was 17ish when I started this project and didn't know any better. All I knew was that I could draw sprites at offset positions, squash them, and make it look 3d. Factors like raytracing weren't considered. I may some day switch over, but we'll see.
Anyways, I'll walkthrough the code that translates the mouse position to world position:
/// <summary>
/// Translate a screen position to a world position.
/// </summary>
/// <param name="screen">XY coord with origin in top left.</param>
/// <param name="z">The world depth we are looking at.</param>
/// <returns></returns>
public static Vector3 OverlayToWorld(Point screen, float z)
{
// As the camera position is in the center of the screen, not the top left,
// first we adjust position by 1/2 the dimensions of the screen.
Vector2 pos = new Vector2(
screen.X - Main.viewport.Width / 2,
screen.Y - Main.viewport.Height / 2);
// Cam zoom is a multiplicative scaler of the final render;
// perform the operation in reverse.
pos.X /= Main.cam.Zoom.X;
pos.Y /= Main.cam.Zoom.Y;
// Find the angle from the center of the screen to the mouse pos,
// then subtract the camera rotation to find the actual angle we're looking at.
float angle = (float)Math.Atan2(pos.Y, pos.X) - Cinema.Rotation;
// Find the length of the vector to the mouse pos
float length = pos.Length();
// Use the original length and the new vector to calculate the proper position
pos = new Vector2(
(float)Math.Cos(angle) * length,
(float)Math.Sin(angle) * length);
// Offset by the distance the cam is from the origin
pos += Main.cam.Pos;
// Return with the previously specified depth
return new Vector3(pos, z);
}
I admit I feel pretty clever for this, but it's likely a terribly inefficient solution compared to the alternatives! Any advice on the subject would be appreciated, but I'll keep rolling either way.
So to make the tooltips above I basically went in reverse but not exactly, which is probably why they're kinda glitchy and I showed you this other code instead!
Regardless! I am very excited to have this up and running. It will help a lot with the user interface (I'll be able to label different world elements, and have targeted interaction with them), and maybe more importantly, debugging! I'll be able to see readouts for any and all variables I want, tied to their in-game object and position! I am super psyched for this tool and think it will help a lot with my rate of progress. Hell yeah!
Up next: I plan to clean up and refactor large chunks of code relating to how the camera, scripting, and game states are handled, in that order. I'll also be working on basic AI, weaponry, and player abilities at the same time. Basically trying to make more content, while improving my workflow by solving the problems I encounter along the way.
Thanks so much for everyone watching and encouraging! This project is a little bit keeping me sane right now (while also driving me crazy) and having your motivation/feedback is very helpful.