図形の表示と動画(Ming/C++)
Ming(C++版)を使用して図形を表示するFlashコンテンツを作成してみる.今回は更に図形が変形するような動画にしてみる.
図形を描画し,さらにそれを時間とともに変形させるサンプルを以下にしめす.
Makefileはこれ.
ビルドしたサンプルで作成したswf.
サンプルでは,渦巻が回り,しばらくしたら,ゴムのように線が振動する.
今回のポイントは図形の描画と画像の更新の二点である.
まず,図形オブジェクトを作成する.
SWFShape *shape = new SWFShape();この図形オブジェクトに対し,関数呼出によって線を引くように指示していくわけであるが,まずその線の太さと色を指定する.
shape->setLine(LINE_WIDTH, LINE_COLOR_R,
LINE_COLOR_G, LINE_COLOR_B);
次に,ペンの場所(線を引かずに)を移動する.
shape->movePenTo(1, 0);あとは順次今ペンのある場所から,次の座標へと,線を引いていく. drawLineToを実行したあとは,引数の座標にペンの位置が移動する.
for (double i = DELTA; i < 2 * M_PI; i += DELTA) {
int x = (int)(i * RADIUS * cos(i * 10));
int y = (int)(i * RADIUS * sin(i * 10));
shape->drawLineTo(x, y);
}
ペンの移動や線の描画時に図表オブジェクトに指定される座標は,絶対的な(例えば親となるSWFMovieなどの)座標系における座標ではなく,その図表オブジェクト自身における座標系である点に注意.
とにかく以上で図形オブジェクトは,渦巻の描画情報を保持できた.
あとはこれをいつものようにMovieに設定し,Movieでの位置を指定する.
// 図形をSWFMovieに置く. SWFDisplayItem *item = movie->add(shape); // 置いた図形の位置を移動(XYセンタリング). item->moveTo(SHAPE_POSITION_X, SHAPE_POSITION_Y);moveToによって,図形オブジェクトの中心(図形オブジェクトの座標系で0,0)が,SWFMovieの座標系においてどの座標と合致するかが指定される. 上の例では,図形オブジェクトの(0,0)が,SWFMovieオブジェクトでの(SHAPE_POSITION_X, SHAPE_POSITION_Y)と合致するように配置される.
次に,作成した図形オブジェクトを回転させる.
これはつまり,動画Flashコンテンツを作成することになるのだが,その手順は以下である.
- SWFMovieオブジェクトの作成
- 更新レート(fps)の指定
- フレームの描画
- 次のフレームに切替える
- 3に戻る.
for (double f = 0; f < 90.0; f += ROTATE_DELTA) {
movie->nextFrame();
item->rotate(ROTATE_DELTA);
}
フレームの切替えはSWFMovie#nextFrame()である.
そして
SWFDisplayItem#rotate(float degrees)によって,dgrees度ずつ渦巻図形を回転させている. このように,フレームを次に切替えても,何もしないと前のフレームで配置した図形や画像などのオブジェクトはそのまま残る. 今回はそれを利用してただrotateするだけの処理だったのだが,逆に次のフレームでは前のフレームのオブジェクトは除去したい場合がある. その場合は,
SWFMovie#remove(SWFDisplayItem *item)を呼び出す.
movie->remove(item);以上で渦巻が回転する.
線の振動の描画には,
drawCurveTo(float cx, float cy, float ax, float ay)を使用する. この関数は,現在のペン位置から(cx, cy)を通過し(ax, ay)に至る滑らかな曲線を描画する. 線の振動を描画するには,フレーム毎に振幅がことなる図形を表示する必要があるので,今回はループの内部で図形オブジェクトの作成と描画を行っている.
for (double i = 0; i < M_PI / 4.0; i+= DELTA) {
SWFShape *shape = new SWFShape();
shape->setLine(LINE_WIDTH, LINE_COLOR_R,
LINE_COLOR_G, LINE_COLOR_B);
int l = (int)(RADIUS * sin(i * 20));
shape->movePenTo(-MOVIE_SIZE_X / 2, 0);
shape->drawCurveTo(0, l, MOVIE_SIZE_X / 2, 0);
// 図形をSWFMovieに置く.
SWFDisplayItem *item = movie->add(shape);
// 置いた図形の位置を移動(XYセンタリング).
item->moveTo(SHAPE_POSITION_X, SHAPE_POSITION_Y);
// 次のフレーム
movie->nextFrame();
// 前の図形を削除
movie->remove(item);
}
最後のremoveを忘れると,線の軌跡で塗りつぶしのようになってしまうので注意.

