ファイヤープロジェクト
図形の表示と動画(Ming/C++)
2006-08-15T05:00+09:00   matsu
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コンテンツを作成することになるのだが,その手順は以下である.
  1. SWFMovieオブジェクトの作成
  2. 更新レート(fps)の指定
  3. フレームの描画
  4. 次のフレームに切替える
  5. 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を忘れると,線の軌跡で塗りつぶしのようになってしまうので注意.
matsu(C)
Since 2002
Mail to matsu