In a 2d game, doing collisions with the edges of your screen is easy. Your textures are a 1:1 mapping of your screen resolution because your verities are too.. if your x position is > than ( screen width / 2 ) then you have hit the edge of your screen and shouldn't be able to escape it.
How do you solve the same problem once your game is in 3d coordinates?
I've tried the following but I'm missing something, the output is far too large. I'm expecting a number like 6.0 instead I'm getting 41.0 because I'm multiplying 25 or so by 1.5
float Window::width = 1920.0f;
float Window::height = 1080.0f;
float PlayingFrame::cameraPosition = -1.0f;
float PlayingFrame::fov = 45;
float PlayingFrame::defaultPlayDistance = 25.0f; // how far back my player is pushed into the frustrum... mainly for scaling.
float PlayingFrame::defaultFrameWidth = 0.0f; // I want to know how far my scaled player can go left / right until he hits the edge of the viewable screen
float PlayingFrame::defaultFrameHeight = 0.0f; // same as above but with top / bottom
float PlayingFrame::nearFrustrum = 1.0f;
float PlayingFrame::GetWorldSpaceHeight( float distance )
{
float a = PlayingFrame::nearFrustrum + abs(PlayingFrame::cameraPosition) + distance;
float o = 1.0f + tan(PlayingFrame::fov * 0.5);
return a * o;
}
float PlayingFrame::GetWorldSpaceWidth(float distance)
{
float a = PlayingFrame::nearFrustrum + abs(PlayingFrame::cameraPosition) + distance;
float o = 1.0f + tan(PlayingFrame::fov * 0.5);
return a * o;
}
Fyi, distance coming in as a parameter is actually set to 25.0f at the moment, I was trying to think ahead
It may help to see the actual problem I'm having... I basically want 2d characters in a 3d world so I can do cool rotation things.. but I cannot figure out how to know when my character has hit the edge of the viewable screen:
https://www.youtube.com/watch?v=A-jcnFfLu6c
I'm going to tell this story more thoroughly:
I originally made a 2D game. I had vertices for my background filling up 1920 x 1200:
const VERTEX World::vertices[ 4 ] = {
{ -960.0f, -600.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // side 1 screen coordinates centred
{ 960.0f, -600.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
{ -960.0f, 600.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
{ 960.0f, 960.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }
};
I applied Orthographic projections to my vertices and obviously it came out lovely on my screen! my 1920 x 1200 texture mapped perfect to my full screen app. beautiful.
Same goes with all of my players and enemies etc, I had vertices like:
const VERTEX Player::vertices[ 4 ] = {
{ -64.0f, -32.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // side 1 screen coordinates centred
{ 64.0f, -32.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
{ -64.0f, 32.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
{ 64.0f, 32.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }
};
this image was 128 x 64... and so was my texture, so it mapped perfectly... it fit on the screen as if it were 1:1 mapped... spot on!
The problem
I wanted to make my game 3D... so I now applied a perspective fov left hand projection and a camera... rather than the orthographic projection which allowed it to be 2D:
I set up a camera like so:
XMVECTOR vecCamPosition = XMVectorSet( 0.0f, 0.0f, PlayingFrame::cameraPosition, 0 );
XMVECTOR vecCamLookAt = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f );
XMVECTOR vecCamUp = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
matView3D = XMMatrixLookAtLH( vecCamPosition, vecCamLookAt, vecCamUp );
I set up a projection like so:
matProjection = XMMatrixPerspectiveFovLH(
XMConvertToRadians( PlayingFrame::fov ), // the field of view
Window::width / Window::height, // aspect ratio
PlayingFrame::nearFrustrum, // the near view-plane
100.0f ); // the far view-plan
I did not change my vertices but I added a z of 1.0f to my objects with just a simple translation... The issue (and I guess you already realise this) was that my textures / vertices were HUGE... I either had to scale all of my objects by some roughly correct size with a scaling transformation, or change my vertices (and this is what I did in the end) to something more like this:
const VERTEX Player::vertices[ 4 ] = {
{ -1.0f, -0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // side 1 screen coordinates centred
{ 1.0f, -0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
{ -1.0f, 0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
{ 1.0f, 0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }
}
Both choices are killing me. Choice 1 meant I had to scale all of my collisions aswell, and both choice 1 and 2 meant I had to estimate how scaled they should be. so much so that my original 1920 x 1200 background I put back into orthographic projection coz I could not get it to scale well...
The last and most frustrating issue is that I have NO IDEA how to calculate where the borders of my screen are...
What is the usual approach to this?