d创建面向对象的sfml包装器
原文
我正在试创建bindbc.sfml
的面向对象的包装器
,因为我不喜欢CSFML
的C风格
语法.
我只是想用面向对象
的包装器来扩展它,使之更接近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();
}
谢谢你.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现