ページ 11

エフェクトと背景の描画

Posted: 2010年7月04日(日) 01:36
by やっくん
前に2Dエフェクトツール作成で質問をし、完成させることができました。

限度はありますが、自分で好きなように作ったエフェクトデータをテキストファイルに出力し、プログラム側ではそのデータを読み込むだけでエフェクトが描画されるというものです。

使用言語はCとC++(便利な部分を)、コンパイラはVC++です。
ライブラリとしてDXライブラリを使用しています。

『エフェクトをテキストを読み込めば描画してくれる』という処理をクラスを用い3手順で使えるようにしました。

①インスタンス宣言
②各種データをセットのメソッドを使用
③エフェクト呼び出しのメソッドを使用

以上の3手順なんですが、③のエフェクト呼び出しを行うと、画面をクリアしながらの描画するので、背景などを描画することができません。

しかし、汎用性を持たせたいためメソッドの中に直接、背景の描画処理を書きたくはありません。

あいまいな質問ですが何かすっきりするような処理の書き方は無いでしょうか。

現在、考えている物としてエフェクト描画の際に関数を1つ引数から受け取り、その中での背景やキャラの描画をエフェクト描画をするときに一緒に描画してしまう、というものです。こちらも汎用性があまり無いような気がして悩んでおります。
もう一つとして単純にメソッドの引数に背景画像のハンドルとキャラ画像のハンドルを渡し、それを一緒に描画すると言う方法です。

ですが、出来る限りメソッドはあくまでもエフェクトを描画するだけ!としたいのですがこれは無理でしょうか?

Re:エフェクトと背景の描画

Posted: 2010年7月04日(日) 01:45
by Justy
>何かすっきりするような処理の書き方は無いでしょうか
 画面のクリアはメインループの定型処理に任せ、背景は背景のクラス(?)に任せ、
エフェクトクラスはエフェクトの処理・描画だけに専念すればいいと思います。

Re:エフェクトと背景の描画

Posted: 2010年7月04日(日) 07:59
by やっくん
Justyさん、返信ありがとうございます。

書き忘れていましたがエフェクトの描画データ部分は
{座標,画像No,拡大率,角度,反転,透過}
などが書かれており、これを1行ずつ読み込み描写していくことでエフェクトを作っています。

>エフェクトクラスはエフェクトの処理・描画だけに専念すればいいと思います。
手法としてファイルオープンをエフェクトメソッドを呼び出す前に行い、メソッドに引数としてファイルポインタを与えるというものを考えました。この処理を行うためのイメージを下記にCで作ってみました。良ければ批評をお願いします。
#include <stdio.h>

int f(FILE *fp)// 描画メソッドにあたる関数。
{
  char buff[256];

  if(fgets(buff, 256, fp) == NULL) return -1;;

  printf("%s", b);

  return 1;
}


int main(void)
{
  FILE *fp;

  fp = fopen("test.txt", "r");
  if(fp == NULL){
    // エラー処理
  }

  while(1){  // メインループ
 
   /* 
      背景描画
    */

    if(f(fp) == -1){// もし、何も読み込めなかったら描画終わり。
      fclose(fp);
      break;
    }
  }
  return 0;

}

Re:エフェクトと背景の描画

Posted: 2010年7月04日(日) 11:21
by Justy
>メソッドに引数としてファイルポインタを与えるというものを考えました
 つまりこのエフェクトシステムは挙動を記述したファイルを毎ループ1行ずつ読み込みながら描画を行う
わけですね。


 んー、問題がいろいろありそうです。

・ 同時に使えるエフェクト数
 Visual C++の同時に fopenできる数は決まっています。そうなるとこのエフェクトが
同時に使用できる数に限られてしまいます。

_setmaxstdio (CRT)
http://msdn.microsoft.com/ja-jp/library/6e3b887c(VS.80).aspx

 上記ページによると 512もあるので大抵の場合大丈夫だろうとは思いますが、
このエフェクトがこの数に縛られるというのは何か違う感じがしませんか?


・ ディスクアクセス
 描画する度にディスクアクセスが発生するということはアクセスの遅いメディア(CD/フロッピーとか)上に
ファイルがあった場合その都度処理が止まる可能性があります。
 複数同時にエフェクトが発生していた場合さらに酷いことになりそうです。

 実際にはハード・OS側で読み込みを高速化する仕組みがあるので考えている以上に酷いことに
ならないかもしれませんが、初回のアクセスは止まってしまうかもしれません。


・ ループ・再利用
 エフェクトをループしたり、後から再利用したい場合、再度ファイルアクセスが必要になります。
 1フレーム前に戻りたいとか逆再生したい場合、ちょっと面倒な処理が必要になりそうです。


・ メモリからの読み込み
 既にあったらこれは無視してください。
 fopenでは開けない何らかのアーカイバからの読み込みとかソースコードにエフェクト情報を
記述する場合とかも考えて、メモリからの読み込み対応もあった方がよくないでしょうか?


 ざっと思いつくのはこんなところです。

Re:エフェクトと背景の描画

Posted: 2010年7月04日(日) 11:26
by Justy
 私は普通のこんな感じのをイメージしていました(C++)。
[color=#d0d0ff" face="monospace"> Effect eff1("test1.eff"); // 一つ目のエフェクト、エフェクトファイル読み込み
Effect eff2; // 二つ目のエフェクト

eff2.Load("test2.eff"); // 後からエフェクトファイル読み込み
eff2.SetLoop(true); // ループ指定をつける

if(eff1.IsFailed() || eff2.IsFailed()) // 読み込みが正常に行われたかどうかのチェック
return -1;

while(1)
{
...; // ループのプロローグ処理、背景などいろいろ描画

if(!eff1.IsEnd()) // 1つ目は全フレーム再生するまで表示する
{
eff1.Update(1); // 1つ目のエフェクト、1フレーム進める
eff1.Draw(); // 1つ目のエフェクト描画
}

eff2.Update(1); // 2つ目のエフェクト、1フレーム進める
// 最後まで再生したら自動で頭から再生)
eff2.Draw(); // 2つ目のエフェクト描画

...; // いろいろ描画、ループエンディング処理

}
[/color]

 Effectクラスのコンストラクタ、ないしは Loadメソッドでファイルを読み込みます
(メモリからの読み込みメソッドも作っておけば尚良しです)。
 このメソッドでそのエフェクトの全フレーム分のデータ読み込み、データをクラス内で保持します。

 あとはメインループ内で Updateメソッドで1フレーム進め(位置など描画に必要な情報を更新)、
Drawメソッドで表示を行います。

 これなら、画面のクリアや背景描画はエフェクトの外に記述できますし、シンプルにエフェクトを
使えるのではないでしょうか。

Re:エフェクトと背景の描画

Posted: 2010年7月04日(日) 15:17
by やっくん
ソースコードまで示していただきありがとうございます><

>同時に使えるエフェクト数
そういう縛りがあったのですね・・・
これも記述してなかったのですが、エフェクトを使う用途はRPGの戦闘部分です。(演出でも少し使います)
エフェクトの同時描画はツールの方で出来るような仕様ですので、あくまでもfopenしているファイルは1つ(多くても2桁は行かない)です。

>ディスクアクセス
私が↑で書いたのソースはやはりここら辺で引っ掛かるんですね(^^;

>メモリからの読み込み
この対応は作ってないので考察してみます。


>このメソッドでそのエフェクトの全フレーム分のデータ読み込み、データをクラス内で保持します。
メモリをあまり使いたくないという理由で現在の手法(1行ずつ読み込んで出力)という形を取っていましたが、総合的に見たらこちらの方が良さそうですね。Justyさんが示してくださった手法で進めて行こうと思いますm(__)m

Justyさん、ありがとうございました!

Re:エフェクトと背景の描画

Posted: 2010年7月04日(日) 15:17
by やっくん
解決押し忘れました。