lineTo と moveTo あたりのケーススタディ

前回に引き続き、今度は Graphics クラスの lineTo と lineStyle あたりの挙動と、beginFill のからみを調べてみた。

今回も環境は AS3 だけど、最後に AS2 で試した場合の補足をつけておいた。

Case 1: 普通に線を描画

package
{
    import flash.display.*;

    public class Test extends Sprite
    {
        public function erase()
        {
            graphics.lineStyle(3, 0xff0000);

            graphics.moveTo(100, 0);
            graphics.lineTo(0, 50);
            graphics.lineTo(100, 100);

            graphics.moveTo(150, 100);
            graphics.curveTo(240, 50, 150, 0);
        }
    }
}

lineStyle で線の色と太さを設定して、moveTo で現在の位置を移動、lineTo および curveTo で描画してる。

Case 2: beginFill と endFill の効果

左側の図形描画を beginFill と endFill を挟んでみた。

graphics.beginFill(0xffffcc);
graphics.lineStyle(3, 0xff0000);

graphics.moveTo(100, 0);
graphics.lineTo(0, 50);
graphics.lineTo(100, 100);
graphics.endFill();

graphics.moveTo(150, 100);
graphics.curveTo(240, 50, 150, 0);

始点と終点が結ばれて、内側が beginFill で指定した色で塗られた。

endFill のあとも、線のスタイルは変化していない点に注意したい。塗りの情報と線の情報は独立のようだ。

塗りの情報は endFill を呼び出せば初期化される。では、線のスタイルを初期化するにはどうするかというと、lineStyle メソッドを引数なしで呼び出せばよい。

例えば、次のように endFill の前に線のスタイルを初期化してみると…。

graphics.beginFill(0xffffcc);
graphics.lineStyle(3, 0xff0000);

graphics.moveTo(100, 0);
graphics.lineTo(0, 50);
graphics.lineTo(100, 100);
graphics.lineStyle();
graphics.endFill();

こうなった。

パスを閉じる線が太さ0で初期化されているのが分かる。

Case 3: beginFill しっぱなしで、endFill しない

最初に beginFill して、endFill しない。

graphics.beginFill(0xffffcc);
graphics.lineStyle(3, 0xff0000);

graphics.moveTo(100, 0);
graphics.lineTo(0, 50);
graphics.lineTo(100, 100);

graphics.moveTo(150, 100);
graphics.curveTo(240, 50, 150, 0);

両方塗られる。

moveTo すると、その時点でパスが閉じられて、塗られるようだ。

注目すべきは、右の図形も同じ色で塗られているところ。moveTo は、塗りを発生させるが、塗りの情報は維持されたまま、次の図形にも適用されるようだ。

Case 2 では、右の図形が塗られていないところと比較すると面白い。

Case 4: 2つ目のみ beginFill

moveTo のあとに beginFill で塗りを設定。

graphics.lineStyle(3, 0xff0000);

graphics.moveTo(100, 0);
graphics.lineTo(0, 50);
graphics.lineTo(100, 100);

graphics.moveTo(150, 100);
graphics.beginFill(0xffffcc);
graphics.curveTo(240, 50, 150, 0);

想像通り。

でも、moveTo の前に beginFill を持ってくると…

graphics.lineStyle(3, 0xff0000);

graphics.moveTo(100, 0);
graphics.lineTo(0, 50);
graphics.lineTo(100, 100);

graphics.beginFill(0xffffcc);

graphics.moveTo(150, 100);
graphics.curveTo(240, 50, 150, 0);

ナニコレ。

謎だ。

どうも beginFill せずに描画したパスに対して、途中で beginFill を呼び出すとこうなるようだ。beginFill の手前で moveTo を挟んで、パスをいったん閉じるとバグらなくなった。endFill を挟んでも解決しなかったので、endFill は beginFill したときにしか機能しないんだろうと想像できる。

補足: AS2 で試してみた

AS2(Flash MX 2004)で試してみたら、Case 3 と Case 4 の1つ目で、右側が黒くなるバグが発生した。コードの最後に、ちゃんと endFill してやれば、AS3 と全く同じ見た目になった。

描画部分は、AS1 の時代からほとんど変わってないんだろうな。

まとめ

  • lineStyle は塗りの情報とは独立。好きなときに呼び出してよい。
  • endFill はパスを閉じて、領域を塗る。塗りの情報は初期化される。
  • moveTo はパスを閉じて、領域を塗る。塗りの情報は維持される(初期化されない)。
  • beginFill してないパスは、moveTo で閉じてから、beginFill を呼べ