Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Solved] Making the view follow player's position and rotation  (Read 3389 times)

0 Members and 1 Guest are viewing this topic.

Guido_Ion

  • Newbie
  • *
  • Posts: 42
    • View Profile
    • Flow Soccer development
I'm trying to get the view to follow the player's position and rotation as it moves. I want to place the view slightly upwards in the direction of the player (variable segment) so the player is placed almost at the bottom of the screen.

Here is the code of the placement of the view:

Code: [Select]
float angle = HumanFieldPlayer::Instance().getSFMLAngle(); // in Degrees
float segment = Game::WindowHeight / 4.f;

m_view.setRotation(angle);

sf::Vector2f posCoords = HumanFieldPlayer::Instance().getSFMLPosition(); // in SFML Coordinates
m_view.setCenter(posCoords.x, posCoords.y - segment);

Game::GetWindow()->setView(m_view);

As you can see in the GIF (see attachment) it's not the behavior I want, when I rotate the player ir should be always in the same position, at the bottom in the middle like in the beginning of the GIF.

I tried a lot of things but I'm pretty lost, what am I missing?

« Last Edit: April 21, 2020, 06:15:46 pm by Guido Bisocoli »

Hapax

  • Hero Member
  • *****
  • Posts: 3387
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Making the view follow player's position and rotation
« Reply #1 on: April 18, 2020, 03:53:49 pm »
Sounds like you want to rotate the view around a point other than the centre?

Try this:
https://github.com/SFML/SFML/wiki/Source%3A-Rotate-View-At-%28specified-co%E2%80%90ordinate%29

 8)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Guido_Ion

  • Newbie
  • *
  • Posts: 42
    • View Profile
    • Flow Soccer development
Re: Making the view follow player's position and rotation
« Reply #2 on: April 18, 2020, 11:30:25 pm »
Thanks Hapax, that's close but not exactly what I need and I'm trying to change it without good results.

That function works on the added rotation, I need it to work with the full rotation. Namely, instead of using rotate on the view I need to use setRotation, or figure out how to get the rotation to add instead of the full rotation.

So far I have this:
Code: [Select]
float rotationToAdd = m_view.getRotation() - HumanFieldPlayer::Instance().getSFMLAngleInDegrees();
float rotationInRadians = rotationToAdd * b2_pi / 180.f;
sf::Vector2f posCoords = HumanFieldPlayer::Instance().getSFMLPosition(); // in SFML Coordinates
posCoords.y -= Game::WindowHeight / 4.f;

const sf::Vector2f offset{ posCoords - m_view.getCenter() };
const float sine{ std::sin(rotationInRadians) };
const float cosine{ std::cos(rotationInRadians) };
const sf::Vector2f rotatedOffset{ cosine * offset.x - sine * offset.y, sine * offset.x + cosine * offset.y };
m_view.rotate(rotationToAdd);
m_view.move(offset - rotatedOffset);

Game::GetWindow()->setView(m_view);

I've tried several things, in this case I'm trying to get the rotation to add instead of the full rotation but when I rotate the player, the view goes crazy.

Hapax

  • Hero Member
  • *****
  • Posts: 3387
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Making the view follow player's position and rotation
« Reply #3 on: April 19, 2020, 12:19:02 am »
If absolute rotation instead of relative rotation is required, you should be able to convert by simply keeping track of the current rotation. Whenever you rotate the view using that function, add that amount to the 'current rotation' value.
If you have two absolute rotations, you can find the relative rotation by finding the difference between the two.

That seems to be what you're asking...
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Guido_Ion

  • Newbie
  • *
  • Posts: 42
    • View Profile
    • Flow Soccer development
Re: Making the view follow player's position and rotation
« Reply #4 on: April 21, 2020, 06:15:02 pm »
I've solved it with a lot of trial and error, with absolute rotation and position. Thanks for the help. Here it is the final code:

First I calculate the offset in coordinates once (in Match constructor):
Code: [Select]
sf::Vector2i segment(0, (int)Game::WindowHeight / 4); // amount of pixels to shift (only in Y axis)
sf::Vector2f segmentCoords = Game::GetWindow()->mapPixelToCoords(segment); // translate to Coordinates
segmentCoord = segmentCoords.y; // store in a float

Then every frame I calculate the view like this:
Code: [Select]
m_view.setRotation(HumanFieldPlayer::Instance().getSFMLAngleInDegrees()) // rotation, straight forward

b2Vec2 direction = -HumanFieldPlayer::Instance().getHeading(); // get inverted direction
sf::Vector2f offset = sf::Vector2f(direction.x, direction.y) * segmentCoord; // add direction (opposite to player) to the segment (offset)

sf::Vector2f posCoords = HumanFieldPlayer::Instance().getSFMLPosition(); // get Player's Position in SFML Coordinates
sf::Vector2f finalVec(posCoords + offset); // add offset to players position
m_view.setCenter(finalVec); // set new center for the view

Hapax

  • Hero Member
  • *****
  • Posts: 3387
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: [Solved] Making the view follow player's position and rotation
« Reply #5 on: April 21, 2020, 10:45:49 pm »
One thing to note is that function that I linked can rotate around an absolute specific point of the window by simply converting a pixel position to a co-ordinate before rotation. It does mention that ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*