トップページ > 過去ログ > 記事閲覧
回転エフェクト
名前:ココア 日時: 2007/01/04 11:10

はじめまして。 DxLibを使ってカードゲームを作っております。 裏向きのカードを表向きにめくるような(カード中央でのY軸の回転) アニメーションエフェクトを作成したいのですが、 どう実装したものか思いつきません。何か良い実装方法はないでしょうか。 カード種が多いので、できれば裏と表の2画像のみで実現できると良いのですが。

Page: 1 |

Re: 回転エフェクト ( No.1 )
名前:キーチック 日時:2007/01/04 15:47

カード4隅の座標をy軸回りに10度か20度くらいずつ回転の座標変換させて,その4点で囲まれたところに画像を張り付けるのではだめですか? 回転が90度越えるまでは表画像,90度越えたら裏画像とかすればひっくれ返るように見えると思います.
Re: 回転エフェクト ( No.2 )
名前:管理人 日時:2007/01/05 02:35

 ココアさん始めまして、DXライブラリの管理人です。  カードがY軸回転しているように見えるサンプルを組んでみました。 宜しければご覧になってみて下さい。m(_ _)m http://homepage2.nifty.com/natupaji/temp/Card.zip
Re: 回転エフェクト ( No.3 )
名前:ココア 日時:2007/01/05 09:12

管理人さん、キーチックさんありがとうございます。 回転している時、遠い辺は小さく、近い辺は大きく見えるので 投影された画像は台形になるハズ、と思い以下の手順で試行錯誤していました。  1.各頂点座標を三次元回転する。  2.各頂点をZ面に投影変換する。  3.得られた台形に画像を描画する。 1、2について式に自信がない、良くわからないという問題があり、 3についてDrawModiGraphを試したところうまく表示されないという状態でした。 今はDrawPolygon3Dを使用して三次元回転の勉強をしながら実験をしていました。 しかし、管理人さんのサンプルの方法でもそれらしく見えるものですねorz 画面内の全てのカードをポリゴンで扱うのはコスト的に問題がある(?)のかな とも思っていたので、サンプルの方法でいこうと思います。ありがとうございました。
Re: 回転エフェクト ( No.4 )
名前:管理人 日時:2007/01/06 01:25

 サンプルはプログラムを短く纏める為に拡大描画関数を使用した 簡易的なものにしましたが、数十枚位であれば全てのカードを ポリゴンで扱っても処理速度に問題はないと思います。
Re: 回転エフェクト ( No.5 )
名前:ココア 日時:2007/01/09 10:10

お世話になっております。 サンプルの方法で実装してみたところやはり違和感があり、またポリゴンでも 処理速度的に問題はないという話ですので、DrawPolygon3Dを使用して 試作してみました。 一応それらしく回転するようにはできたのですが、表裏判定がうまくいきません。 90°で判定すると画面中央での描画ではうまくいきますが、左右位置がずれると おかしくなります。 頂点の設定の仕方か、表裏判定かが問題だと思うのですが良くわかりません。 ご助言を頂けないでしょうか。
Re: 回転エフェクト ( No.6 )
名前:ココア 日時:2007/01/09 10:10

以下は3枚のカードを回転描画するサンプルです。 #include "DxLib.h" #include <math.h> #define PI 3.1415926535897932384626433832795 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode(TRUE); int handle[2], i; int cx, cy; float angle = 0.0f; VERTEX_3D Vertex[6]; if( DxLib_Init() == -1 ) return -1; SetDrawScreen( DX_SCREEN_BACK ) ; handle[0] = LoadGraph("TestTex1.jpg");//表 handle[1] = LoadGraph("TestTex2.jpg");//裏 for(i = 0; i < 6; ++i) { Vertex[i].r = Vertex[i].g = Vertex[i].b = 255 ; Vertex[i].a = 255 ; } while( CheckHitKeyAll() == 0 ) { if( ProcessMessage() != 0 ) break ; ClearDrawScreen() ; for (cx = 100; cx < 640; cx += 220) { cy = 240; // (cx,cy)を中心に幅・高さ100で描画 angle += 0.005F; if (angle > (float)(2 * PI)) angle = 0.0F; Vertex[0].pos.x = cx - 50 * cos(angle); Vertex[0].pos.y = cy + 50.0F; Vertex[0].pos.z = -(-50 * sin(angle)); Vertex[0].u = 0.0F; Vertex[0].v = 0.0F; Vertex[1].pos.x = cx + 50 * cos(angle); Vertex[1].pos.y = cy + 50.0F; Vertex[1].pos.z = -(50 * sin(angle)); Vertex[1].u = 1.0F; Vertex[1].v = 0.0F; Vertex[2].pos.x = cx - 50 * cos(angle); Vertex[2].pos.y = cy - 50.0F; Vertex[2].pos.z = -(-50 * sin(angle)); Vertex[2].u = 0.0F; Vertex[2].v = 1.0F; Vertex[3].pos.x = cx + 50 * cos(angle); Vertex[3].pos.y = cy - 50.0F; Vertex[3].pos.z = -(50 * sin(angle)); Vertex[3].u = 1.0F; Vertex[3].v = 1.0F; Vertex[4] = Vertex[2]; Vertex[5] = Vertex[1]; //表裏判定 if( angle < PI / 2.0f || angle > PI / 2.0f + PI ) { DrawPolygon3D( Vertex, 2, handle[0], FALSE ); } else { DrawPolygon3D( Vertex, 2, handle[1], FALSE ); } } ScreenFlip(); } DxLib_End() ; return 0 ; }
Re: 回転エフェクト ( No.7 )
名前:管理人 日時:2007/01/12 11:48

 ココアさんどうも、DXライブラリの管理人です。  成る程、DrawPolygon3D を使用する場合はカードを描画する座標によって 表裏が入れ替わる角度が違うので角度だけで判定することが出来ないのですね・・・ (視点の位置を考慮に入れた計算をすれば理論上は判定可能ですが・・・)  手っ取り早い方法としてポリゴンのカリング機能(画面に投影されたポリゴンの 頂点座標を順番に追った時に左回転になるか右回転になるかによって描画するか しないかを判断する機能)を使用する方法がありますので、追加しました。 宜しければこちらをダウンロードしてください。m(_ _)m http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe //VC用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe //BCC用 (中身を既存のライブラリのファイルに上書きして下さい)  こちらのバージョンには以下の関数が追加されています。 // カリングの有効、無効を変更する int SetUseCullingFlag( int Flag );  TRUE を渡して呼び出すと、画面に投影されたポリゴンの頂点座標を順番に 追っていった時に左回転の場合は描画されなくなります。  この機能を利用して、表面と裏面の回転が逆になるような座標にして描画 すると、常に裏表どちらの面を描画していても必ず片方の面はカリングに よって描画されないので、裏表判定をする必要がなくなります。  この関数を使用してココアさんが書き込まれたサンプルプログラムを変更 させて頂いたプログラムを以下に載せておきますので、宜しければご覧下さい。m(_ _)m #include "DxLib.h" #include <math.h> #define PI 3.1415926535897932384626433832795 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode(TRUE); int handle[2], i; int cx, cy; float angle = 0.0f, f; VERTEX_3D Vertex[12]; if( DxLib_Init() == -1 ) return -1; SetDrawScreen( DX_SCREEN_BACK ) ; handle[0] = LoadGraph("TestTex1.jpg");//表 handle[1] = LoadGraph("TestTex2.jpg");//裏 for(i = 0; i < 12; ++i) { Vertex[i].r = Vertex[i].g = Vertex[i].b = 255 ; Vertex[i].a = 255 ; } SetUseCullingFlag( TRUE ); while( CheckHitKeyAll() == 0 ) { if( ProcessMessage() != 0 ) break ; ClearDrawScreen() ; for (cx = 100; cx < 640; cx += 220) { cy = 240; // (cx,cy)を中心に幅・高さ100で描画 angle += 0.005F; if (angle > (float)(2 * PI)) angle = 0.0F; Vertex[0].pos.x = cx - 50 * cos(angle); Vertex[0].pos.y = cy + 50.0F; Vertex[0].pos.z = -(-50 * sin(angle)); Vertex[0].u = 0.0F; Vertex[0].v = 0.0F; Vertex[1].pos.x = cx + 50 * cos(angle); Vertex[1].pos.y = cy + 50.0F; Vertex[1].pos.z = -(50 * sin(angle)); Vertex[1].u = 1.0F; Vertex[1].v = 0.0F; Vertex[2].pos.x = cx - 50 * cos(angle); Vertex[2].pos.y = cy - 50.0F; Vertex[2].pos.z = -(-50 * sin(angle)); Vertex[2].u = 0.0F; Vertex[2].v = 1.0F; Vertex[3].pos.x = cx + 50 * cos(angle); Vertex[3].pos.y = cy - 50.0F; Vertex[3].pos.z = -(50 * sin(angle)); Vertex[3].u = 1.0F; Vertex[3].v = 1.0F; Vertex[4] = Vertex[2]; Vertex[5] = Vertex[1]; DrawPolygon3D( &Vertex[0], 2, handle[0], FALSE ); Vertex[6] = Vertex[0]; Vertex[7] = Vertex[1]; Vertex[8] = Vertex[2]; Vertex[9] = Vertex[3]; Vertex[6].pos = Vertex[1].pos; Vertex[7].pos = Vertex[0].pos; Vertex[8].pos = Vertex[3].pos; Vertex[9].pos = Vertex[2].pos; Vertex[10] = Vertex[8]; Vertex[11] = Vertex[7]; DrawPolygon3D( &Vertex[6], 2, handle[1], FALSE ); } ScreenFlip(); } DxLib_End() ; return 0 ; }
Re: 回転エフェクト ( No.8 )
名前:ココア 日時:2007/01/15 09:02

用意して頂いたカリング機能を使用して、期待通りの結果を得ることができました。 管理人さんの迅速な個別対応には頭が下がります。 ありがとうございました。

Page: 1 |