0

我是 AS3 和 Haxe 的新手,但希望找到一种方法来使用最终类(图形)中的方法,而不必总是为实例变量添加前缀。

而不是这样的:

var gr:Graphics = flash.Lib.current.graphics;

gr.clear();
gr.beginFill(0xffffff, 1);
gr.drawRect(0,0,400,400);

我希望得到类似 processing.org 的东西,但我想很多便利来自预处理。我查看了有关高级类型的 Haxe 参考资料,但到目前为止我还没有做任何事情。这可能是不可能的,因为图形是最终的,但我认为问它不会有什么坏处。如果我可以扩展 Graphics 似乎会很容易。无论如何,感谢您的阅读。

4

3 回答 3

1

使用可以尝试使用 mixin

例如创建一个类 GraphicHelper:

class GraphicHelper {
    inline public static function drawRect(sp:Sprite, x:Float, y:Float, w:Float, h:Float) {
        sp.graphics.drawRect(x,y,w,h);
    }
}

然后在你的 Sprite 类中:

using GraphicHelper;

class Square extends flash.display.Sprite {
    public function new():Void {
        super();
        drawRect(0,0,10,10); //this is GraphicHelper.drawRect(this,0,0,10,10); and since it is inline, actually is this.graphics.drawRect(0,0,10,10);
    }
}
于 2011-06-28T22:59:55.173 回答
1

使用'with'关键字有帮助吗?

var someSprite:Sprite = new Sprite();
with( someSprite.graphics )
{
    beginFill(0xC0FFEE, 1);
    drawRect( -10, -10, 20, 20 );
    endFill();
}
于 2011-06-29T05:20:18.330 回答
0

with() {...}好的,这是在 Haxe 上实现一个非常简单的仿真的代码:

//simple.hx
class Simple 
{

    @:macro public static function with(subject:Expr, block:Expr)
    {
        return with_impl(subject, block);
    }

    #if macro
    static function with_impl(subject:Expr, block:Expr)
    {
        function mk(e, pos) return { expr:e, pos:pos };

        //this is the main function here. It's going to find a variable  the expression so it uses our subject
        function changeIdent(identExpr:Expr, changeExpr)
        {
            return switch(identExpr.expr)
            {
                case EConst(c):
                switch(c)
                {
                    case CIdent(s):
                    mk(EField(changeExpr, s), identExpr.pos);

                    default:
                    identExpr;
                }

                case EField(e, f):
                mk(EField(changeIdent(e, changeExpr), f), identExpr.pos);

                case EType(e, f):
                mk(EType(changeIdent(e, changeExpr), f), identExpr.pos);

                default: //fallba
                identExpr;
            }
        }

        return switch(block.expr)
        {
            case EBlock(exprs):
            var newblock = [];
            for (statement in exprs)
            {
                switch(statement.expr)
                {
                    case ECall(e, params):
                    newblock.push(mk(ECall(changeIdent(e, subject), params), statement.pos));
                    default:
                    newblock.push(statement);
                }
            }

            mk(EBlock(newblock), block.pos);

            case EDisplay(e, iscall):
            mk(EDisplay(with_impl(subject, e), iscall), block.pos);

            default:
            changeIdent(block, subject);
        }
    }
    #end
}

你像这样使用它:

//Main.hx
class Main 
{

    static function main() 
    {
        Simple.with (Lib.current.graphics,
        {
            beginFill(0xC0FFEE, 1);
            drawRect( -10, -10, 20, 20 );
            endFill();
        });
    }

}

它不会改变作用域,而是寻找调用表达式,然后将函数(主题)的第一个参数添加到每个表达式中。所以上面的代码等价于:

{
    Lib.current.graphics.beginFill(0xC0FFEE, 1);
    Lib.current.graphics.drawRect( -10, -10, 20, 20 );
    Lib.current.graphics.endFill();
}

宏太有趣了!

于 2011-07-01T01:11:50.663 回答