FFの戦闘シーンへのカットインみたいな処理

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
YAMATO

FFの戦闘シーンへのカットインみたいな処理

#1

投稿記事 by YAMATO » 15年前

FFやテイルズの戦闘シーンへのカットインみたいな処理で
現在表示されている画像がガラスが用に砕け散るエフェクトはどのように行っているのでしょうか
研究の為に何回も見ていたのですが毎回違った割れ方をしており
プログラムの書き方の見当がつきません・・・。

Ma

Re:FFの戦闘シーンへのカットインみたいな処理

#2

投稿記事 by Ma » 15年前

環境を記載しましょう。

DXライブラリで、ですよね??

昔、似たようなスレがあったような気がします。
ただ、簡単ではなかったし、あまり高速な描画に向いていなかった気がしますが^^;

過去ログ紹介しようと思ったのですが、どうもみつからない・・・。

Justy

Re:FFの戦闘シーンへのカットインみたいな処理

#3

投稿記事 by Justy » 15年前


> 現在表示されている画像がガラスが用に砕け散るエフェクト

 一番簡単な方法は事前にある程度破片状に割ってある板の3Dモデルと割れるモーションを作って、
画面全体をテクスチャ化したものを貼り付けてあげればそんなかんじになりますね。
(必要なら光源とスペキュラも入れて)


 でも、望みのように毎回異なるようにしたいのなら、モデルだけ用意してモーションはソフト的に
つけた方がいいかも。
 その方が割れ始める位置、飛ばす強さ・方向・回転とか、ランダム性を入れたり自由にコントロール
できますし。

 割れる切れ目も毎回変えたいのなら、少し細かく割ったモデルにしておいて、ランダムで破片を
グループ化し、同じグループは1つの破片として動くように計算すればできるんじゃないでしょうか。

 面倒なら、切れ目を変えたモデルを複数用意してもいいですが。

Dixq (管理人)

Re:FFの戦闘シーンへのカットインみたいな処理

#4

投稿記事 by Dixq (管理人) » 15年前

私も何回か作りました。
中でもFFX-2の戦闘シーンにはいるエフェクトが好きだったので

これを何度も見てなるべくそっくりになるように作った覚えがあります。
その時々で適切な計算をさせるのはなかなか難しいです。
Justyさんが仰るようにいくつかパターンを用意すると良いと思います。
多少複雑に割れさせればいくつかのパターンがあることは解らないと思います。



う、FLASHのタグが入らない・・。
この前いろいろお願いした時に反映されないように対策されちゃったんでしょうかね・・。

山崎

Re:FFの戦闘シーンへのカットインみたいな処理

#5

投稿記事 by 山崎 » 15年前

"似たようなスレ"の主はもしかしたら私でしょうかな?
私も探せませんでした・・・。^^;

な、なるほど・・・。
割るたびに動的に破片の形を決めたいと思っていたのですが、
細かく割ったモデルを用意して、それを組み合わせれば十分に動的に割ったと見せられそうですね・・・。
質問者じゃないですが、非常に参考になりました。

管理人さんが作った「割り方」は、
Justyさんのおっしゃるような、破片のモデルを準備するやり方でしょうか?
それとも、ランダムに割れ方が決まるタイプでしょうか?
もしよろしければお聞きしたいです。


Dixq (管理人)

Re:FFの戦闘シーンへのカットインみたいな処理

#7

投稿記事 by Dixq (管理人) » 15年前

最初はランダムで作っていたのですが、パターンを作った方が断然楽だと思い、途中からパターンを作りました。
Justyさんの仰る破裂モデルタイプです。

山崎

Re:FFの戦闘シーンへのカットインみたいな処理

#8

投稿記事 by 山崎 » 15年前

管理人様
すばやいご返信誠にありがとうございます。
私も「破片モデル式」で再度チャレンジしてみようと思います。
・・・動的式はできなくて途中で頓挫していたので・・・。

質問者でもないのに途中から割って入って申し訳ないです・・・。

YAMATO

Re:FFの戦闘シーンへのカットインみたいな処理

#9

投稿記事 by YAMATO » 15年前

皆さんご回答ありがとうございます。
正直こんなにレスがつくとは思っていませんでした。

かなり難しそうですね・・・。
正直、言っている意味がよく理解できませんでした・・・。
こちらのサイトのおかげで最近シューティングが作れるようになってきていたので
調子に乗っておりました。申し訳ないです。

他にも皆様のお考えなどが御座いましたら
ご回答いただけますと助かります。

Dixq (管理人)

Re:FFの戦闘シーンへのカットインみたいな処理

#10

投稿記事 by Dixq (管理人) » 15年前

あらら^^;
最近Cを学び始めたばかりだとするとちょっとハードルが高かったかも知れません。
まずはガラスのように難しい割れ方じゃなく、長方形とかに分割してバラバラにするところから始めてみてはいかがでしょうか?

例えば
http://dixq.net/sakuhin.html
こちらで紹介しているRPGのサンプルでは画面をいくつかの長方形に分割して戦闘に突入します。
ハッキリ言ってすごく演出はダサくなってしまっていますが、
その分プログラムは本当に簡単です。

http://homepage2.nifty.com/natupaji/DxL ... html#R3N12
この関数を使えば好きな長方形に現在の描画先データから切り取ることが出来ます。
これで作った画像を好きなようにバラバラにすればいいのです。

まずは簡単なところからトライしてみてはいかがでしょう?

> 調子に乗っておりました。申し訳ないです。

欲張ってなんぼですよ!
私はいつも調子に乗ってます。何しろこのサイトはC言語の勉強を始めた年に作り始めたんですからね・・w
私のように調子に乗っても成長しない人はいますが、
臆病になってしまってはますます成長しないと思いますし、
常に色んなことに挑戦することはよいことだと思いますよ。


>>山崎さん

いえいえ、お気になさらず^^
少々他の話題が混ざったとしても色んな情報交換が出来た方が良いと思っています☆

kazuoni

Re:FFの戦闘シーンへのカットインみたいな処理

#11

投稿記事 by kazuoni » 15年前

個人的に興味があるので参戦させてください。
動的に割る方法として以下のように考えてみました。

1、前提として直角二等辺三角形がある。
2、直角から斜辺に対し垂直線を引き、二つの直角二等辺三角形をつくる(分割する)。
3、2を行うかどうかは、重み付きランダムで決める。
(例えば、割れる中心からの距離で近ければ重みが強くなる→分割されやすくなる)
4、2、3を最大規定回数以下まで各三角形ごとに繰り返す。

画面の大きさが640*480の場合、正三角形(160*160)を12個でき、
それを向かい合う頂点同士を結んで直角二等辺三角形を2つ作ります。

これを繰り返していけば、形は直角二等辺三角形ですが、
大きさはかなりランダムになります(なりました)

が、問題なのは、やはり速度ですね。
実際、再帰版、繰り返し版両方作ってみましたが、
割る中心を1つなら、まぁ重みしだいですけどとりあえずできます。が、
銃弾で撃たれた画面のように数点中心を決めるとものすごいことになり、
FPS=60はまずできないです。。

また、これに、おのおのの三角形が3Dの回転で飛んでいくなんて・・・厳しいです。。
重みを軽くして、分割数を減らすと、比較的大きな二等辺三角形がきれいにできてしまい、
とてもガラスには見えません。

うーん。。如何したものか。。

> Justyさん

とりあえず破片2Dの画像ができたとして、それを回転させるとしたら
三角形各頂点を三次元で回転させるっということですよね?
(DirectXで表現するとすれば、)どのような方針で書けばよいのでしょうか?
ただ単に各三角形の重心を原点として、各頂点を随時三次元的に回転して、
出力(座標セット)すればよいのでしょうか?
とりあえず、裏面は真っ黒で。
(本来なら裏は画像が反転してると「それっぽい」かななんて思いますが)

Justyさんの書かれたことを考えると、
・質量
・重心
・回転量
・飛ぶ方向のベクトル
・各頂点座標
が破片情報で、
・風向
・風量
が必要ということですよね?(まだあるかも・・・)

・・・破片が多くてもこの方針で通用するでしょうか?^^;

Justy

Re:FFの戦闘シーンへのカットインみたいな処理

#12

投稿記事 by Justy » 15年前


> 各頂点を随時三次元的に回転して出力(座標セット)すればよいのでしょうか

 基本的にはそんな感じです。
 ただ、各破片の位置とか姿勢はその情報をライブラリに渡せば、HW/ライブラリ側で
各頂点を移動・回転してくれますので、事前に各破片ごとにローカル座標系での頂点情報を
用意しておいて、破片の移動に際し各破片が今どこにあってどう回転しているかだけを
計算すればいいです。



> 破片が多くてもこの方針で通用するでしょうか

 項目はお好みで、ってところです。
 どういう移動をするのかで変わっていますので。
 
 強いて挙げるなら重力を追加で(風で代用してもいいですけど)、質量は微妙ってところです。
 破片同士の衝突とかあれば必要ですけど、ガラスが割れてくくらいのエフェクトなら
要らない気がしますね。

 あとは計算負荷とか描画負荷と相談です。

Ma

Re:FFの戦闘シーンへのカットインみたいな処理

#13

投稿記事 by Ma » 15年前

ちょっと時間があったので初挑戦でしたがサンプル作ってみました。
Justyさんのアイディアを基にしてみました。


http://masao.s5.pf-x.net/download2/glass.zip


が・・・、いろいろ問題が。。。
たとえば、回転の中心座標が破片の中心ではなく原点になってるところとか。←結構重要かも
あと、モデル作るの面倒ですね、これは・・・w

割れ方のパターンは一個しかありませんが、ここからさらに改良して破片のグループ化とかすれば(たぶん)何通りでも作れますとも。
(あれ、回転の中心座標が原点のおかげで、グループ化しても綺麗に回転してくれそう。)


ちょっと、これからグループ化とかに挑戦してみようと思いますお。




(追記)
矢印キーで移動、マウスでカメラ角度変更です。 画像

Ma

Re:FFの戦闘シーンへのカットインみたいな処理

#14

投稿記事 by Ma » 15年前

余分な機能がいろいろついちゃいましたが、改良版できました。
前のよりはちょっとソースが読みやすくなっていると思います。

http://masao.s5.pf-x.net/download2/glass2.zip

UIで可変になっていうのは破片数のみです。(1から25個)
これ以上増やす場合は、mqoデータとソースをちょこっとだけいじらないといけません。

これ以外のパラメータはソースコードをいじる必要がありますが、簡単に改造できるようになってますので、
これだけでもパラメータいじりで結構遊べます。


追記
そういえば、 FFの戦闘シーンへのカットイン は知らないので的外れなことになってたらすいません。 画像

ジャーニー

MakeGraphで作成した画像がちゃんと表示されない

#15

投稿記事 by ジャーニー » 15年前

お世話になってます.

http://www.play21.jp/board/formz.cgi?ac ... &rln=46714
で,文字列の回転表示が難しいとわかったので,MakeGraphで作成したハンドルにDrawStringで描画した文字列を画像にして取り込み表示させています.
しかし,例えばmain関数で複数のログを追加すると全く表示されなくなってしまいます.
1個だけログに追加した場合ちゃんと表示されます.
これはどういうことでしょうか.
もしわかる方教えてください.

Messageクラス 
ログの1つ1つのメッセージ管理クラス
Createメソッドで画像作成

Logクラス
Messageクラスを管理
Updateでログの表示時間を管理し,DrawObjectで描画しています.
継承しているObjectクラスはタスクに追加するための基底クラスです
/**************************************************************************
ログの1メッセージ
**************************************************************************/
class Message
{
private:
    int msg_handle;//メッセージ画像のハンドル
    int show_time;//表示している時間
    std::string msg;
    
public:
    Message(std::string str) : show_time(0)
    {
        msg = str;
    }

    //文字列画像の作成
    void Create(int font_handle)
    {
        //画面に文字列描画
        DrawStringToHandle(0,0, msg.c_str()
            , GetColor(255,255,255), font_handle, GetColor(150,150,150));

        //空画像ハンドル作成
        msg_handle = MakeGraph(360,15);

        //画面に描画している文字列を画像として所得
        GetDrawScreenGraph(0,0,360,15, msg_handle);

        //文字列隠し
        DrawBox(0,0,360,20,GetColor(0,0,0), TRUE);
    }

    void UpperCount()
    {
        show_time++;
    }

    int GetHandle(){return msg_handle;}
    int GetTime(){ return show_time;}
    std::string GetMessage(){ return msg; }

    ~Message()
    {
        //画像の削除
        DeleteGraph(msg_handle);
    }
};

/**************************************************************************
ログを表示するクラス
**************************************************************************/
//ログの表示限界
#define LOG_MAX 8

//ログの表示限界を超えたときの表示フレーム
#define LOG_TIME 90

#define LOG_OBJ_PRIORITY 200
#define LOG_DRAW_PRIORITY 25

class Log : public Object
{
private:
    std::vector<Message> message;//表示するログ
    int font_handle;//フォントハンドル
    int player_num;//プレイヤ番号
public:
    Log()
        : Object(LOG_OBJ_PRIORITY, LOG_DRAW_PRIORITY, "Log")
    {
        //フォントハンドルの作成
        font_handle = CreateFontToHandle("HG創英角ゴシックUB" , 15 , 2 , DX_FONTTYPE_ANTIALIASING_EDGE);
    }

    ~Log()
    {
        message.clear();
    }

    //メッセージの追加
    void SetMessage(std::string str)
    {
        message.push_back(Message(str));
        message.back().Create(font_handle);
    }

    void SetPlayerNumber(int p)
    {
        player_num = p;
    }

    void Update()
    {
        if( message.size() > 0 )
        {
            //0番目のログの表示フレーム更新
            message[0].UpperCount();

            //もじ表示限界個数を超えたならば
            if( message.size() > LOG_MAX )
            {
                //もし表示限界をこえたら
                if( message[0].GetTime() > LOG_TIME )
                {
                    //そのログを削除
                    message.erase(message.begin());
                }
            }
        }
    }

    void DrawObject()
    {
        //ログの個数を確認
        int temp = message.size();

        //もじ表示限界個数を超えているならば
        if( temp > LOG_MAX )
        {
            //表示する個数を表示限界個数にする
            temp = LOG_MAX;
        }
        
        DrawBox(0,360,130, 720, GetColor(255,255,255), TRUE);
        //ログ表示
        for( int i=0; i<temp; i++ )
        {
            /*
            DrawStringToHandle( 50 , 250 - (temp-i)*16, message.c_str() 
                , GetColor(255,255,255), font_handle , GetColor(150,150,150)) ;
            //DrawFormatVStringToHandle( 50 + (temp-i)*20 , 250, GetColor(255,255,255)
            //    , font_handle, message.c_str() , GetColor(150,150,150)) ;
            */

            if( player_num == 0 )
            {
                DrawRotaGraph((temp-i)*15, 560, 1.0, PI/2, message.GetHandle(), TRUE);
                //DrawString(50+i*20,100+i*20,message.GetMessage().c_str(), GetColor(255,255,255), GetColor(150,150,150));
            }
            else
            {
                DrawRotaGraph(PROGRAM_WIDTH-(temp-i)*15, 180, 1.0, -PI/2, message.GetHandle(), TRUE);
            }
        }
    }
};

kazuoni

Re:MakeGraphで作成した画像がちゃんと表示されない

#16

投稿記事 by kazuoni » 15年前

とりあえず、
・Objectクラスの実装
・main関数でのクラスLogの扱い方
を追記してください。

ジャーニー

Re:MakeGraphで作成した画像がちゃんと表示されない

#17

投稿記事 by ジャーニー » 15年前

<kazuoniさん

返信が遅くなりました申し訳ありません
あれから少しいじっていましたら

message.push_back(Message(str));
message.back().Create(font_handle);

message.push_back(new Message(str));
message.back().Create(font_handle);
に変えるとうまくいきました.

お手数おかけしました.

閉鎖

“C言語何でも質問掲示板” へ戻る