I am writing a game with directx in which the player can hurl himself off of planets, into space, at which time he will be affected by gravity of other planets and be sucked onto whichever planet he collides with first.
The stored entity position is the position of the centre of the object, to make gravity calculations easier.
The following code is supposed to use the position of the rock and the player to calculate the angle at which to 'attach' the player to the rock. an angle of 0 radians puts the player directly underneath the planet, 1 radian puts him directly on top of the planet. Currently the below code works when the player approaches a planet directly from the top or side, but when coming at an angle the player is attached in the wrong place. It also only works when the player approaches from the right but this will be sorted after I get the angle calculations correct.
if (m_entityVector[a]->getType() == player)
if (m_entityVector[b]->getType() == rock)
{
D3DXVECTOR2 playerPos = m_entityVector[a]->getPos();
D3DXVECTOR2 rockPos = m_entityVector[b]->getPos();
int playerWidth = VIS.getFrameWidth(m_entityVector[a]->getID()) * m_entityVector[a]->getScale();
int rockWidth = VIS.getFrameWidth(m_entityVector[b]->getID()) * m_entityVector[b]->getScale();
// obtain the position of the 'feet' of the item about to be attached
// by getting a vector going from the item to the rock
// taking its unit vector and multiplying it by half the width of the item
D3DXVECTOR2 playerToRock = rockPos - playerPos;
playerToRock = CUtility::UnitVector(playerToRock);
playerToRock = playerToRock * (playerWidth/2);
D3DXVECTOR2 feetPos = playerPos + playerToRock;
// find the position of the top of the rock
D3DXVECTOR2 topOfRock(rockPos.x, rockPos.y - (rockWidth/2));
// find the y distance between the 'feet' and the top of the rock
float yDiff = (feetPos.y - topOfRock.y);
// divide by the width of the rock giving us a value between 0 and 1
// by which we multiply pi radians to obtain the angle at which to attach
float scalar = yDiff/rockWidth;
m_entityVector[b]->Attach(m_entityVector[a], D3DX_PI + (D3DX_PI*scalar)
}
I have tested the Attach function and it works exactly as it should.
Please feel free to ask questions if the code is unclear.
* What is your coordinate system? Is the angle theta in terms of the entity (the rock in this case)? If this is the case, why does -1 and 1 correspond to the top and bottom of the rock. I would assume it would be -pi and +pi respectively in euclidean coordinates.
* Athar's solution looks correct. Use the arctan function (atan2() in C++) to calculate the angle between the difference between the x and y coordinates of the rock and player (ie: y2 - y1 = y_diff and x2 - x1 = xdiff) The atan2(xdiff, ydiff) will yield the correct angle.
Watch out though.... this is an angle relative to xdiff and ydiff. Depending on your coord. system, you might have to manipulate the angle by adding/subtracting pi.
1 - I know very little about maths so that's probably why I only used the y difference, I just figured that if the feet, the part which will be touching the planet, were half way between the top and the bottom of the rock, it should go right on the side of the rock, and if they are at the same level as the top of the rock, it shoud go right on top of the rock. You may be right. Let me make sure you have it clear that the player can only travel around the outside edge of the rock, there is no 3d element to the game. Just one question, will the atan function return an angle in radians or degrees?
2 - In this case the height and width of my textures are the same so it made no difference but you're totally right.
3 - You're totally right cdel 2pi radians corresponds to one full journey around the rock, don't know why I put 0 and 1, I must've been thinking in terms of the scalar that I calculate.
I'm very interested in your project. Can you tell me more on what development tools and platform you're using, what's the general idea/goal of the project, and what are your thoughts/motivations in completing such a project?
I am leaning towards doing a similar project myself.
I don't really have a goal for the project it's just something to keep me programming during the summer, I'm going into my final year of university this year and don't want to get out of the habit. Im making a win32 application and I got the idea when playing super mario galaxy, in a way it will be similar but in 2d, but it is not yet fully designed so who knows how it will end up.
The thing I find most interesting about it though is that in the way I'm making it, my entities will contain pointers to other entities allowing the environment that an entity exists in to be controlled by the entity which currently holds a pointer to it. For example, when the player is floating around in space it will be updated in the main update loop of the world class, having gravity applied to him, but when he is attached to a planet it will be updated within the update function of that planet, because of course once a player is on a planet it should no longer be pulled by other planets until it is launched back into space.
It may never get completed, but I'm having fun with it. Thanks for the interest and even more for the help =)