我的“身体” SFML 中的类:它如何自行正确旋转成员形状?

发布于 2024-11-19 04:32:10 字数 3134 浏览 3 评论 0原文

嘿,所以我创建了一个“body”类,它继承自 SFML 中的 sf::drawable,它将形状保持在一起,这样我就可以形成更复杂的形状和图形。我发现我必须在渲染时根据身体自上次渲染以来发生的整体情况对每个单独的成员形状进行一些更新。

这包括:

  • 旋转
  • 平移
  • 缩放

我想我必须手动编写代码来考虑整个身体可能发生的这些变化,因此形状位置是正确的。然而,在编码旋转部分时,我在编写手动代码后发现,即使我使 Bodies Render() 函数仅迭代并渲染每个形状而不更改它们,它们无论如何都会以正确的方向出现。 这怎么可能?

我注释掉了我编写的显然不需要的代码,并且我使用 Draw() 函数进行渲染。请向我解释一下我的自己的代码!(天哪,我感觉自己很弱智)。

这是课程:

class Body : public sf::Drawable{ 

    public:
        Body(const sf::Vector2f& Position = sf::Vector2f(0, 0), const sf::Vector2f& Scale = sf::Vector2f(1, 1), float Rotation = 0.f, const sf::Color& Col = sf::Color(255, 255, 255, 255)){
            SetPosition(Position);
            SetScale(Scale);
            SetRotation(Rotation);
            SetColor(Col);
            RotVal=0;};

////////////////// Drawable Functions   ////////////////////
        void SetX(float X){
            MoveVal.x += X - GetPosition().x;
            Drawable::SetX(X);};

        void SetY(float Y){
            MoveVal.y += Y - GetPosition().y;
            Drawable::SetY(Y);};

        void SetRotation(float Rotation){
            RotVal+= Rotation-GetRotation();
            Drawable::SetRotation(Rotation);};
////////////////////////////////////////////////////////////

        bool AddShape(sf::Shape& S){
            Shapes.push_back(S); return true;};
        bool AddSprite(sf::Sprite& S){
            Sprites.push_back(S); return true;};

        void Draw(sf::RenderTarget& target){
            for(unsigned short I=0; I<Shapes.size(); I++){
                //Body offset
                Shapes[I].SetPosition( 
                    Shapes[I].GetPosition().x + MoveVal.x,
                    Shapes[I].GetPosition().y + MoveVal.y);

                // Aparrently Body shapes rotate on their own...
                //WWTFFFF>>>>??????????

                //Body Rotation
                //float px= GetPosition().x,
                //    py= GetPosition().y,
                //    x=  Shapes[I].GetPosition().x,
                //    y=  Shapes[I].GetPosition().y,
                //   rot= ConvToRad(RotVal);

                /*Shapes[I].SetPosition( 
                    px + ((x-px)*cos(rot)) - ((y-py)*sin(rot)),
                    py - ((x-px)*sin(rot)) + ((y-py)*cos(rot)));*/ //TODO: put this in a math header
                //Shapes[I].Rotate(RotVal);
            }

            target.Draw(*this); // draws each individual shape

            //Reset all the Change Values
            RotVal=0;
            MoveVal.x=0;
            MoveVal.y=0;
        };

    private:
        sf::Vector2f MoveVal;
        float         RotVal;
        std::vector<sf::Shape> Shapes;
        std::vector<sf::Sprite> Sprites;

        virtual void Render(sf::RenderTarget& target) const{                
            for(unsigned short I=0; I<Shapes.size(); I++){
                target.Draw(Shapes[I]);}
            for(unsigned short I=0; I<Sprites.size(); I++){
                target.Draw(Sprites[I]);}
        };
};

Hey so i've made a 'body' class, which inherits from sf::drawable in SFML that holds shapes together so i can form more complicated shapes and figures. I found i had to do a few updates on each individual member shape at render time, based on what's happened to the body over-all since last render.

This included:

  • Rotation
  • Translations
  • Scaling

I thought i would have to manually write the code to factor in these changes that could have occured to the overall body, so the shape positions turned out right. However when coding the Rotation part, i found after writing the manual code that even though i made Bodies Render() function only iterate through and render each shape without changing them, they somehow came out with the right orientation anyway. HOW CAN THIS BE?

I commented out the code i wrote and apparently didn't need, and i use the Draw() function to render. Please explain to me my own code! (God i feel retarded).

here's the class:

class Body : public sf::Drawable{ 

    public:
        Body(const sf::Vector2f& Position = sf::Vector2f(0, 0), const sf::Vector2f& Scale = sf::Vector2f(1, 1), float Rotation = 0.f, const sf::Color& Col = sf::Color(255, 255, 255, 255)){
            SetPosition(Position);
            SetScale(Scale);
            SetRotation(Rotation);
            SetColor(Col);
            RotVal=0;};

////////////////// Drawable Functions   ////////////////////
        void SetX(float X){
            MoveVal.x += X - GetPosition().x;
            Drawable::SetX(X);};

        void SetY(float Y){
            MoveVal.y += Y - GetPosition().y;
            Drawable::SetY(Y);};

        void SetRotation(float Rotation){
            RotVal+= Rotation-GetRotation();
            Drawable::SetRotation(Rotation);};
////////////////////////////////////////////////////////////

        bool AddShape(sf::Shape& S){
            Shapes.push_back(S); return true;};
        bool AddSprite(sf::Sprite& S){
            Sprites.push_back(S); return true;};

        void Draw(sf::RenderTarget& target){
            for(unsigned short I=0; I<Shapes.size(); I++){
                //Body offset
                Shapes[I].SetPosition( 
                    Shapes[I].GetPosition().x + MoveVal.x,
                    Shapes[I].GetPosition().y + MoveVal.y);

                // Aparrently Body shapes rotate on their own...
                //WWTFFFF>>>>??????????

                //Body Rotation
                //float px= GetPosition().x,
                //    py= GetPosition().y,
                //    x=  Shapes[I].GetPosition().x,
                //    y=  Shapes[I].GetPosition().y,
                //   rot= ConvToRad(RotVal);

                /*Shapes[I].SetPosition( 
                    px + ((x-px)*cos(rot)) - ((y-py)*sin(rot)),
                    py - ((x-px)*sin(rot)) + ((y-py)*cos(rot)));*/ //TODO: put this in a math header
                //Shapes[I].Rotate(RotVal);
            }

            target.Draw(*this); // draws each individual shape

            //Reset all the Change Values
            RotVal=0;
            MoveVal.x=0;
            MoveVal.y=0;
        };

    private:
        sf::Vector2f MoveVal;
        float         RotVal;
        std::vector<sf::Shape> Shapes;
        std::vector<sf::Sprite> Sprites;

        virtual void Render(sf::RenderTarget& target) const{                
            for(unsigned short I=0; I<Shapes.size(); I++){
                target.Draw(Shapes[I]);}
            for(unsigned short I=0; I<Sprites.size(); I++){
                target.Draw(Sprites[I]);}
        };
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

云胡 2024-11-26 04:32:10

SFML 源代码证实了我的猜测。

当您调用 target.Draw(*this) 时,它最终会调用 Drawable::Draw(RenderTarget& Target) const,它会设置一个渲染矩阵,该矩阵具有您指定的旋转通过 Drawable::SetRotation 调用给出它。然后调用您的虚拟渲染函数,并设置旋转环境。这意味着您的身体部位会旋转。

自己查看源码以获得更好的理解。 (;

My guess was confirmed by the SFML source code.

When you call target.Draw(*this) it eventually calls Drawable::Draw(RenderTarget& Target) const, which sets up a render matrix which has the rotation that you gave it with the Drawable::SetRotation call. Your virtual Render function is then called, with that rotation environment set up. This means that your body-parts get rotated.

Have a look at the source yourself to get a better understanding. (;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文