d创建面向对象的sfml包装器

原文
我正在试创建bindbc.sfml面向对象的包装器,因为我不喜欢CSFMLC风格语法.
我只是想用面向对象的包装器来扩展它,使之更接近C++SFML语法.
包装器,我创建了形状(Shape)类.它在原C++SFML实现中可见:

class Shape : Transformable, Drawable {
    void setTexture(sfTexture* texture, bool resetRect) {
        ptr.sfShape_setTexture(texture, resetRect);
    }

    void setTextureRect(IntRect rect) {
        ptr.sfShape_setTextureRect(rect.to_sfIntRect());
    }

    void setFillColor(Color color) {
        ptr.sfShape_setFillColor(color.to_sfColor());
    }

    void setOutlineColor(Color color) {
        ptr.sfShape_setOutlineColor(color.to_sfColor());
    }

    void setOutlineThickness(float thickness) {
        ptr.sfShape_setOutlineThickness(thickness);
    }

    const(sfTexture)* getTexture() {
        return ptr.sfShape_getTexture();
    }

    IntRect getTextureRect() {
        return ptr.sfShape_getTextureRect().toIntRect();
    }

    Color getFillColor() {
        return ptr.sfShape_getFillColor().toColor();
    }

    Color getOutlineColor() {
        return ptr.sfShape_getOutlineColor().toColor();
    }

    float getOutlineThickness() {
        return ptr.sfShape_getOutlineThickness();
    }

    size_t getPointCount() nothrow {
        return ptr.sfShape_getPointCount();
    }

    Vector2f getPoint(size_t index) nothrow {
        return ptr.sfShape_getPoint(index).toVector2f_noThrow();
    }

    FloatRect getLocalBounds() {
        return ptr.sfShape_getLocalBounds().toFloatRect();
    }

    FloatRect getGlobalBounds() {
        return ptr.sfShape_getGlobalBounds().toFloatRect();
    }

    private sfShape* ptr;
}

当前未初化,该sfShape形状指针.
形状(Shape)继承了可变形(Transformable)类和可画(Drawable)接口.匹配了SFML行为.
SFML.NET也有CSFMLC#的类似包装器.SFML.NET的伟大在,就像C++SFML,你甚至不知道在使用CSFML.
现在,我创建形状子类的矩形形状(RectangleShape):
顺便,谈到这些包装器时,我从SFML.NET中获得了很多灵感.

class RectangleShape : Shape {
    this(Vector2f size) {
        _size = size;
        setSize(_size);
    }

    Vector2f getSize() {
        return _size;
    }

    void setSize(Vector2f size) {
        _size = size;
    }

    override {
        size_t getPointCount() {
            return 4;
        }

        Vector2f getPoint(size_t index) {
            final switch (index) {
                case 0:
                    return Vector2f(0, 0);
                case 1:
                    return Vector2f(_size.x, 0);
                case 2:
                    return Vector2f(_size.x, _size.y);
                case 3:
                    return Vector2f(0, _size.y);
            }
        }
    }

    private Vector2f _size;
}

但,矩形类只覆盖取点数(getPointCount)取点(getPoint)方法.
这些是超类(基类)方法,形状用来构造对象,使其可绘画.
现在,添加以下代码形状,这样就可通过假设子类会提供了很好实现的这两个方法构造形状(Shape):

class Shape : Transformable, Drawable {
    this() {
        ptr = sfShape_create(&getPointCount, &getPoint, cast(void*)this);
    }

    extern(C) private static ulong getPointCount(void* data) nothrow {
        return (cast(Shape)data).getPointCount();
    }

    extern(C) private static sfVector2f getPoint(size_t index, void* data) nothrow {
        return (cast(Shape)data).getPoint(index).to_sfVector2f_noThrow();
    }

我听到你在问,为什么?
通过函数指针提供两个取点数取点方法的回调,并且传递当前对象data void*指针.有点难以理解,但是仔细阅读,你会懂的.

现在,创建新矩形,假设调用构造器后,会正确初化sf_shape(因为它会利用关键取点及取点数方法),一切都会好起来.
下面是测试代码:

void main() {
    loadSFML();

    RectangleShape rectangleShape = new RectangleShape(Vector2f(50, 50));
    rectangleShape.setPosition(Vector2f(50, 50));
    rectangleShape.setFillColor(Color.Blue);

    RenderWindow renderWindow = new RenderWindow(sfVideoMode(500, 500), "Tests", sfWindowStyle.sfDefaultStyle, null);
    sfEvent event;

    while (renderWindow.isOpen()) {
        while (renderWindow.pollEvent(&event)) {
            if (event.type == sfEventType.sfEvtClosed) {
                renderWindow.close();
            }
        }

        renderWindow.clear(Color.Yellow);
        renderWindow.ptr.sfRenderWindow_drawShape(rectangleShape.ptr, null);
        renderWindow.display();
    }
}

出于演示,我用渲染窗口(renderWindow)指针变量来绘画.
期望在屏幕上的50x50位置,弹出一个50x50蓝色填充矩形.

运行应用时,我什么也看不到,只是一个黄色屏幕.
很困惑,一切正常,但是很明显有个错误?

见参考
示例显示了在setter和构造器中调用了更新(update)().绑定它的D方法如下:

void sfShape_update(sfShape* shape);

你是个传奇,兄弟,它修好了.在矩形(Rectangle)构造器中调用:

class RectangleShape : Shape {
    this(Vector2f size) {
        _size = size;
        setSize(_size);

        ptr.sfShape_update();
    }

谢谢你.

posted @   zjh6  阅读(20)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示