• Shapes


    系列文章

    SFML-windows 篇
    SFML-Events explained 篇
    SFML-Keyboard, mouse and joystick 篇
    SFML-Using OpenGL in a SFML window 篇
    SFML-Drawing 2D stuff 篇
    SFML-Shapes 篇
    SFML-Sprites and textures 篇

    一、Introduction


    SFML提供了一组表示简单形状实体的类。每种形状都是一个单独的类,但它们都来自同一基类,因此它们可以访问相同的公共特征子集。然后,每个类都添加了自己的细节:圆形类的半径属性、矩形类的大小、多边形类的点等。

    二、Common shape properties


    变换(位置、旋转、比例)

    这些属性对于所有SFML图形类都是通用的,因此在单独的教程:Transforming entities. 中对其进行了解释。

    颜色

    形状的基本属性之一是其颜色。您可以使用setFillColor函数进行更改。

    sf::CircleShape shape(50.f);
    
    // set the shape color to green
    shape.setFillColor(sf::Color(100, 250, 50));
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    轮廓

    形状可以有轮廓。可以使用SetOutlineHicknesssetOutlineColor函数设置轮廓的厚度和颜色。

    sf::CircleShape shape(50.f);
    shape.setFillColor(sf::Color(150, 50, 250));
    
    // set a 10-pixel wide orange outline
    shape.setOutlineThickness(10.f);
    shape.setOutlineColor(sf::Color(250, 150, 100));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    默认情况下,轮廓从形状向外挤出(例如,如果有一个半径为10、轮廓厚度为5的圆,则圆的总半径为15)。通过设置负厚度,可以使其向形状中心挤出。
    要禁用轮廓,请将其厚度设置为0。如果只需要轮廓,可以将填充颜色设置为sf::color::Transparent

    纹理

    shapes也可以有texture,就像 sprites一样。要指定要映射到形状的纹理的一部分,必须使用setTextureRect函数。它需要纹理矩形映射到形状的边界矩形。这种方法没有提供最大的灵活性,但比单独设置形状每个点的纹理坐标更容易使用。

    sf::CircleShape shape(50);
    
    // map a 100x100 textured rectangle to the shape
    shape.setTexture(&texture); // texture is a sf::Texture
    shape.setTextureRect(sf::IntRect(10, 10, 100, 100));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    请注意,轮廓没有纹理。

    重要的是要知道纹理是用形状的填充颜色调制(乘以)的。如果其填充颜色为sf::color::white,则纹理将显示为未修改。

    要禁用纹理,请调用setTexture(NULL)

    三、Drawing a shape


    绘制形状与绘制任何其他SFML实体一样简单:

    window.draw(shape);
    
    • 1

    四、Built-in shape types

    Rectangles

    要绘制矩形,可以使用sf::RectangleShape类。它只有一个属性:矩形的大小。

    // define a 120x50 rectangle
    sf::RectangleShape rectangle(sf::Vector2f(120.f, 50.f));
    
    // change the size to 100x100
    rectangle.setSize(sf::Vector2f(100.f, 100.f));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Circles

    圆由sf::CircleShape类表示。它有两个属性:半径和边数。边数是一个可选属性,它允许您调整圆的“质量”:圆必须由具有多条边的多边形近似(图形卡无法直接绘制完美的圆),该属性定义圆近似将具有多少条边。如果你画一个小圆圈,你可能只需要几个边。如果你画大圆,或者放大规则圆,你很可能需要更多的边。

    // define a circle with radius = 200
    sf::CircleShape circle(200.f);
    
    // change the radius to 40
    circle.setRadius(40.f);
    
    // change the number of sides (points) to 100
    circle.setPointCount(100);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    Regular polygons


    正多边形没有专用的类,事实上,您可以使用sf::CircleShape类表示具有任意边数的正多边形:由于圆由具有多条边的多边形近似,因此您只需调整边数即可获得所需的多边形。有3个点的sf::CircleShape是三角形,有4个点sf::CircleShape是正方形,等等。

    // define a triangle
    sf::CircleShape triangle(80.f, 3);
    
    // define a square
    sf::CircleShape square(80.f, 4);
    
    // define an octagon
    sf::CircleShape octagon(80.f, 8);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    Convex shapes


    凸形状sf::ConvexShape类是最终的形状类:它允许您定义任何凸形状。SFML无法绘制凹面形状。如果你需要画一个凹形,你必须把它分割成多个凸多边形。

    要构造凸形状,必须首先设置其应有的点的数量,然后定义点。

    // create an empty shape
    sf::ConvexShape convex;
    
    // resize it to 5 points
    convex.setPointCount(5);
    
    // define the points
    convex.setPoint(0, sf::Vector2f(0.f, 0.f));
    convex.setPoint(1, sf::Vector2f(150.f, 10.f));
    convex.setPoint(2, sf::Vector2f(120.f, 90.f));
    convex.setPoint(3, sf::Vector2f(30.f, 100.f));
    convex.setPoint(4, sf::Vector2f(0.f, 50.f));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    定义点的顺序非常重要。它们都必须按顺时针或逆时针顺序定义。如果以不一致的顺序定义它们,则形状的构造将不正确。
    在这里插入图片描述
    虽然sf::converxshape的名称意味着它只能用于表示凸形状,但它的要求稍微宽松一些。事实上,你的形状必须满足的唯一要求是,如果你继续画从重心到所有点的线,这些线必须以相同的顺序绘制。你不允许“跳到前一行后面”。在内部,凸形状是使用三角形扇形自动构造的,因此,如果形状可以由三角形扇形表示,则可以使用sf::ConvexShape。有了这个宽松的定义,您可以使用sf::converxshape绘制恒星。

    Lines


    线条没有形状类。原因很简单:如果你的线有一个厚度,它是一个矩形。如果没有,则可以使用线原语绘制。

    带厚度的线条:

    sf::RectangleShape line(sf::Vector2f(150.f, 5.f));
    line.rotate(45.f);
    
    • 1
    • 2

    在这里插入图片描述无厚度的线条:

    sf::Vertex line[] =
    {
        sf::Vertex(sf::Vector2f(10.f, 10.f)),
        sf::Vertex(sf::Vector2f(150.f, 150.f))
    };
    
    window.draw(line, 2, sf::Lines);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述要了解有关顶点和基本体的更多信息,可以阅读有关顶点阵列的教程。

    Custom shape types


    可以使用自己的形状类型扩展形状类集。为此,必须从sf::Shape派生并重写两个函数:

    getPointCount: return the number of points in the shape
    getPoint: return a point of the shape
    
    • 1
    • 2

    每当形状中的任何点发生更改时,还必须调用update()保护函数,以便通知基类并更新其内部几何体。

    下面是自定义形状类的完整示例:EllipseShape

    class EllipseShape : public sf::Shape
    {
    public :
    
        explicit EllipseShape(const sf::Vector2f& radius = sf::Vector2f(0.f, 0.f)) :
        m_radius(radius)
        {
            update();
        }
    
        void setRadius(const sf::Vector2f& radius)
        {
            m_radius = radius;
            update();
        }
    
        const sf::Vector2f& getRadius() const
        {
            return m_radius;
        }
    
        virtual std::size_t getPointCount() const
        {
            return 30; // fixed, but could be an attribute of the class if needed
        }
    
        virtual sf::Vector2f getPoint(std::size_t index) const
        {
            static const float pi = 3.141592654f;
    
            float angle = index * 2 * pi / getPointCount() - pi / 2;
            float x = std::cos(angle) * m_radius.x;
            float y = std::sin(angle) * m_radius.y;
    
            return sf::Vector2f(m_radius.x + x, m_radius.y + y);
        }
    
    private :
    
        sf::Vector2f m_radius;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    在这里插入图片描述

    Antialiased shapes


    没有选项可以反锯齿单个形状。要获得消除混叠的形状(即边缘平滑的形状),您必须在创建窗口时使用sf::ContextSettings结构的相应属性全局启用消除混叠。

    sf::ContextSettings settings;
    settings.antialiasingLevel = 8;
    
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML shapes", sf::Style::Default, settings);
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    请记住,消除混叠的可用性取决于图形卡:图形卡可能不支持消除混叠,或者在驱动程序设置中强制禁用消除混叠。

  • 相关阅读:
    粗俗解释C# 8.0+的变量后面有?问号是什么意思?
    SpringBoot中如何集成Servlet呢?
    2022 深度学习 & 计算机视觉 & 感知算法 面经整理 二十三(221 222 223 224 225 226 227 228 229 230)
    如何低门槛开发有趣实用的ZigBee产品?
    吴恩达机器学习week2实验答案Practice Lab Linear Regression【C1_W2_Linear_Regression】
    为什么工业设计要创新,工业设计创新的意义和作用
    程序员看看这是什么代码
    Docker 学习总结(79)—— Dockerfile 编写技巧总结
    声呐直线阵正交混频实验(HEU信息与信号处理创新实践项目一)
    计算机网络 —— 应用层(DNS域名系统)
  • 原文地址:https://blog.csdn.net/Phantom_matter/article/details/125560060