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

Author Topic: Help with sf::View and Origin  (Read 1901 times)

0 Members and 1 Guest are viewing this topic.

Palkisa

  • Newbie
  • *
  • Posts: 2
    • View Profile
    • Email
Help with sf::View and Origin
« on: November 17, 2019, 03:40:03 am »
I am making this small project/game and I ran into a problem. I need my sprite(player) to rotate with mouse cursor. So where cursor is in window there my sprite rotates, and I got it to work. But now I need a View to follow my sprite, and when I set a View it seems that my Origin resets to 0,0.

Main:
#include <iostream>
#include "SFML/Graphics.hpp"

#include "Player.h"

int main()
{
        sf::RenderWindow window(sf::VideoMode(1024, 768), "Game");
        sf::Event sfEvent;

        Player* player = new Player("soldier.png");

               
        sf::View camera;
        camera.setSize(sf::Vector2f(1024, 768));

        while (window.isOpen())
        {
                while (window.pollEvent(sfEvent))
                {
                        if (sfEvent.type == sf::Event::EventType::Closed)
                        {
                                window.close();
                        }
                }
                player->movement();

                player->facingDirection(window);

                player->setOrigin();

                camera.setCenter(player->getOrigin());

                window.clear();

                window.setView(camera);

                player->draw(window);

                window.display();

        }
}
 

Player.cpp:
#include "Player.h"

Player::Player(std::string textureName)
{
        _texture = new sf::Texture;
        _texture->loadFromFile(P_TEX_PATH + textureName);

        _sprite = new sf::Sprite(*_texture);


}

Player::~Player()
{
        delete _texture;
        delete _sprite;
}

void Player::movement()
{
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A))
        {
                _sprite->move(-_speed, 0.0f);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D))
        {
                _sprite->move(_speed, 0.0f);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W))
        {
                _sprite->move(0.0f, -_speed);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S))
        {
                _sprite->move(0.0f, _speed);
        }
}
void Player::facingDirection( sf::RenderWindow &window)
{
        mousePosition = sf::Mouse::getPosition(window);
        _spritePosition = _sprite->getPosition();

        float dx = mousePosition.x - _spritePosition.x;
        float dy = mousePosition.y - _spritePosition.y;

        _rotation = (atan2(dy, dx)) * 180 / 3.14159265 ;

        _sprite->setRotation(_rotation);

}

sf::Vector2f Player::getLocation()
{
        return _sprite->getPosition();
}

sf::Vector2f Player::getOrigin()
{
        return _sprite->getOrigin();
}

float Player::getSpriteOrientation()
{
        return _sprite->getRotation();
}

void Player::setOrigin()
{
        _scaleW = _sprite->getLocalBounds().width;
        _scaleH = _sprite->getLocalBounds().height;
        _scaleW = _scaleW / 2;
        _scaleH = _scaleH / 2;
        _sprite->setOrigin(_scaleH,_scaleW - 4.f);
}

void Player::draw(sf::RenderTarget& window)
{
        window.draw(*_sprite);
}
 

Player.h
#pragma once
#include <iostream>
#include <string>
#include "SFML/Graphics.hpp"

#define P_TEX_PATH "textures\\player\\"


class Player
{
public:
        Player(std::string textureName);
        ~Player();

        void draw(sf::RenderTarget& window);
        void movement();
        void facingDirection(sf::RenderWindow &window);
        sf::Vector2f getLocation();
        sf::Vector2f getOrigin();
        float getSpriteOrientation();
        void setOrigin();
        sf::Vector2i mousePosition;

       
private:
        sf::Sprite* _sprite;
        sf::Texture* _texture;
        float _size = 20.f;
        float _speed = 0.020f;
        sf::Vector2f _spritePosition;
        float _rotation = 0;
        float _scaleW = 0;
        float _scaleH = 0;
        float _locationX = 0;
        float _locationY = 0;

       
};
 

Any feedback about the rest of the code would be helpfull, ty

G.

  • Hero Member
  • *****
  • Posts: 1592
    • View Profile
Re: Help with sf::View and Origin
« Reply #1 on: November 17, 2019, 06:38:20 am »
The sprite origin is local to the sprite, the position or rotation of the sprite doesn't change it's origin.
You probably want the camera to follow the sprite position instead.

Palkisa

  • Newbie
  • *
  • Posts: 2
    • View Profile
    • Email
Re: Help with sf::View and Origin
« Reply #2 on: November 17, 2019, 06:57:59 am »
But I do have a setOrigin function that is constantly changing origin to the middle of the sprite. Or at least it should do it XD. Also I tried to change my camera center from sprite location to sprite origin but the same problem still hapends.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10815
    • View Profile
    • development blog
    • Email
Re: Help with sf::View and Origin
« Reply #3 on: November 17, 2019, 07:52:51 pm »
view.setCenter(sprite.getOrigin()) is certainly wrong, as the origin is in local coordinates while the view center is in world coordinates.

With such problems it's always a good idea to print various values (position, origin, etc) and compare them to the expected values (potentially calculated by hand).
If you notice the difference in values, you can the set break points and step through your code step by step, while constantly checking values. That way you should be able to find the "bad" logic.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Palkisa

  • Newbie
  • *
  • Posts: 2
    • View Profile
    • Email
Re: Help with sf::View and Origin
« Reply #4 on: November 17, 2019, 09:33:50 pm »
view.setCenter(sprite.getOrigin()) is certainly wrong, as the origin is in local coordinates while the view center is in world coordinates.

I also tryed to view.setCenter(sprite.getLocation()) but same problem hapends. And isnt my setOrigin() function suppose to constantly change origin to center of my sprite. Also is there any other fix beside calculating values since math is not my strong side XD. Sry if im banging my head against the wall and not understanding you, but I just started c++ and SFML. ALSO is there any difference in sprite.move and sprite.setPosition. Also again XD could you please explain diferece between local and world cordinates ( in some easy wasy) , I looked up online but I couldnt understand it since english is not my first language.

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Help with sf::View and Origin
« Reply #5 on: November 19, 2019, 04:44:57 pm »
I'll try an analogy.

Imagine holding a small piece of paper with a picture on it. You know which way up it is and which corner is the top-left, even if you aren't holding it perfectly straight. This is the local co-ordinates.

When you "set the origin", imagine taking a small pin and poking it through that picture. Where you put that hole is dependant on which part of the picture you want it to be. The hole is the origin.

Then, imagine having a rectangular surface - a large wooden board, for example - and you can choose anywhere on that board. That position is global co-ordinates.

The next thing to do is take the picture with the pin and put that pin into the board at the position you chose. Note that the chosen origin is at the position, not the corner.

You can also rotate the picture freely as the pin holds the origin in position.

Note that when you change the origin, you are simply just changing which part of the picture to place the pin. It makes no difference where on the board it is or how it is rotated; the origin will always be in the part of the picture (the local co-ordinates) you say.



Hopefully this helps to visualise what those terms are and how they work.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

 

anything