Search code examples
c++classobjectc++14sfml

Setting up the card position on the window screen with class function


I don't want to hardcode the position for the card to be in the middle of the screen and we did a project like this without class. So though would be easy to just put what I did to make the card to be in the center but no matter what I did, the card stays at the top left corner.

I even notice at times if I put the rectSize or something the rectangle proportions changes and look like a square when maximizing the screen.

What am I doing wrong?

This is my background cpp file:

#include "background.h"

background::background() : background(450, 750)
{

}
background::background(float x, float y)
{
    sf::RenderWindow window;
    sf::RectangleShape rectangle;

    sf::RectangleShape::setSize({x, y});

//    sf::Vector2f center;
//
//    sf::RectangleShape::setPosition({});
}

void setPostioning (sf::RenderWindow &window, sf::RectangleShape &rectangle, float x, float y)
{
    sf::Vector2f rectSize ={x,y};
    rectangle.setSize(rectSize);
    sf::Vector2f center;

    rectangle.setPosition({
        center.x = window.getSize().x/2 - rectSize.x/2,
        center.y = window.getSize().y/2 - rectSize.y/2
    });
}

This is my header file of what I have done:

#include <SFML/Graphics.hpp>

class background : public sf::RectangleShape
{
public:
    background();
    background(float x, float y);
    void setPostioning(sf::RenderWindow &window, sf::RectangleShape &rectangle, float x, float y);
};

And now this is my main main file

int main()
{
    //set up of the window
    sf::VideoMode videoMode(1280,1024,32);
    sf::RenderWindow window(videoMode, "SFML Tutorial");//window will display name
    window.setFramerateLimit(15);//frame rate

    background b;
    rank r;
    Card Joker;
    while(window.isOpen())
    {
        sf::Event event;

        while (window.pollEvent(event))
        {
            //when window is running they can close it with the close button
            if (event.type == sf::Event::Closed)
            {
                window.close();
            }

            //this if statement will make our card stay in the same ratio no matter what
            if (event.type == sf::Event::Resized)
            {
                // update the view to the new size of the window and keep the center
                window.setView(sf::View(window.getView().getCenter(),
                                        sf::Vector2f((float) event.size.width, (float) event.size.height)));
            }
        }
        //invoking and set up to be drawn and display on the window when running
        window.clear(sf::Color::Black);
        window.draw(Joker);
        window.draw(r);
        window.display();
    }

So yes unsure why the position is not being set up or being taken from the window size or maybe it has to do with the rectSize that I did and being misread. I also think it has to do with the x and y as I set them up already with 450 nd 750.


Solution

  • It is tricky to help you without full code, cause I don't know how exactly did you want to use setPostioning. After a small workaround, It finally appeared in the center of the screen. Feel free to comment, if my example still doesn't satisfy your needs.

    In the header file I added a reference to sf::RenderWindow, to use it in setPostioning.

    Updated background.h:

    class background : public sf::RectangleShape
    {
    public:
        background(sf::RenderWindow &window);
        background(sf::RenderWindow &window, float x, float y);
        void setPostioning(float x, float y);
    
    private:
        //  Added a refence to original window to have possibility use it in setPositioning
        sf::RenderWindow& m_window;
    };
    

    In .cpp file I removed some redundant refs to sf::RectangleShape (cause you already inherited from it), and to sf::RenderWindod (cause a referene to it is stored inside class).
    Updated background.cpp:

    background::background(sf::RenderWindow &window) : background(window, 450, 750)
    {
    
    }
    background::background(sf::RenderWindow &window, float x, float y) : m_window(window)
    {
        //  sf::RectangleShape rectangle;
    
        sf::RectangleShape::setSize({ x, y });
    }
    
    void background::setPostioning(float x, float y)
    {
        sf::Vector2f rectSize = { x,y };
    
        // don't use rectangle from param, because you already inherited from sf::RectangleShape
        //rectangle.setSize(rectSize);
        setSize(rectSize);
        sf::Vector2f center;
    
        // again, don't use rectangle from param, because you already inherited from sf::RectangleShape
        //rectangle.setPosition({
        setPosition({
            center.x = m_window.getSize().x / 2 - rectSize.x / 2,
            center.y = m_window.getSize().y / 2 - rectSize.y / 2
        });
    }
    

    In main function I called setPostioning before the event loop and added window.draw(b); to render your background. Updated main function:

    int main()
    {
        //set up of the window
        sf::VideoMode videoMode(1280, 1024, 32);
        sf::RenderWindow window(videoMode, "SFML Tutorial");//window will display name
        window.setFramerateLimit(15);//frame rate
    
        background b(window);
        //  use setPostioning
        b.setPostioning(200.f, 200.f);
    
        while (window.isOpen())
        {
            sf::Event event;
    
            while (window.pollEvent(event))
            {
                //when window is running they can close it with the close button
                if (event.type == sf::Event::Closed)
                {
                    window.close();
                }
    
                //this if statement will make our card stay in the same ratio no matter what
                if (event.type == sf::Event::Resized)
                {
                    // update the view to the new size of the window and keep the center
                    window.setView(sf::View(window.getView().getCenter(),
                        sf::Vector2f((float)event.size.width, (float)event.size.height)));
                }
            }
            //invoking and set up to be drawn and display on the window when running
            window.clear(sf::Color::Black);
            window.draw(b);
            window.display();
        }
    }