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();
}
谢谢你.
浙公网安备 33010602011771号