117ドット絵エディタ「EDGE2」、MIDI音楽編集ソフト「Domino」、楽曲などを配布している個人サイトです。AppWizardを使ってプロジェクトを作成すると、’C’+プロジェクト名+’App’という感じのクラスが作成されます。このクラスはCWinAppの派生クラスであり、アプリケーションを管理するクラスとなります。いろいろなクラスからデータを共有したい場合、グローバル変数を使用するのは嫌われるため、このCWinAppの派生クラスのメンバ変数として宣言します。*)AfxGetApp();pApp->m_・・・・とします。*)AfxGetApp())->m_・・・・でも良いですね。した事を何度も書いていると、ソースも見にくくなるし、面倒くさくなってきます。マクロを使うという手もありますが、今回は別の方法をご紹介します。MfcTestAppのソースファイルを覗いてみると、こんな記述があります。theApp;という事は、こいつをどこでも使えるようにすれば、手軽にCMfcTestAppクラスへアクセス出来るわけですね。いうわけで、externを使って、CMfcTestAppのヘッダーファイルの最後の方(クラス宣言が終わった次くらい)へ次のような文字列を埋め込みます。theApp;「CMfcTestApp」というは例なので、自分の派生クラス名にしてください。すれば、あとはどこでも、theApp.m_・・・という感じでメンバ変数へアクセス出来るようになるというわけです。演出・エフェクト編サンプルコードのダウンロードでは、まずサンプルコードをダウンロードし、解凍してください。C++でプロジェクトファイルを開いてください(「effec_08.dsw」をダブルクリックすれば開けます)。圧縮ファイルに含まれる「effec_08.exe」をダブルクリックし、実行してみてください(何かキーを押すと終了します)。Softの文字が徐々にデロ~ンと熔けて(?)いくと思います。いうわけで、今回は画像を溶かすような処理について説明していきたいと思います。サンプルコードの解説というわけで、今回も順番に説明していきまーす。略//DirectDraw開始StartDirectDraw(hw);//パレット設定LoadPalette("takabo.bmp");//ビットマップを作業用サーフェイスへ読み込むLoadBitmap(lpWork,"takabo.bmp",0,0,548,90);//46,195んで、まずメインループ内で使用するデータを初期化します。1)につき1つのデータを作成し、高さが90あるので、90個分のデータを作成します。「dy」はy座標、「dy_add」は(y座標の)毎ループ毎の増加量、「dy_count」は処理を開始するまでの残りカウントです。elsedy_count[i]--;}ここ(↑)でまずデータの座標を更新します。dy_addに適当な定数を加えていくことで「重力」っぽい処理が再現できます。{for(y=(int)dy[i];y<(int)dy[i+1];y++)if(y<480)Blt(lpBack,46,y,548,1,lpWork,0,i,FALSE);}}データの座標を更新し終えたら次は表示です。そのまま「dy」の示す座標に画像を貼り付けていくと、「穴」が空きます。その穴を埋めるようにfor文とかで間を補ってやります。演出・エフェクト編サンプルコードのダウンロードでは、まずサンプルコードをダウンロードし、解凍してください。C++でプロジェクトファイルを開いてください(「effec_07.dsw」をダブルクリックすれば開けます)。圧縮ファイルに含まれる「effec_07.exe」をダブルクリックし、実行してみてください(何かキーを押すと終了します)。Networkのロゴが左から徐々に粉々になり落ちていくと思います。いうわけで、今回は徐々に画像を粉々にする方法を紹介します。サンプルコードの解説というわけで、今回は順番に説明していきまーす。今回は、なんとなく構造体を使っています。left;//動作までの残りカウント}*dust=NULL;サンプルプログラムを実行すれば解ると思いますが、画像は左から段々と1ドットずつに分解され、それぞれが独立して動いています。1ドットにつき、1データ(上の構造体の場合たぶん28バイト)が必要となります。今回使用している画像サイズは612×145ですから、計612x145x28=2484720バイト必要となります。dust[145][612]」などとすると、VCの場合、実行時にエラー(スタックオーバーとかその辺)が出てしまい、正常に動作しません。「動的に確保」するようにします。*str=NULL){EndDirectDraw();if(str!=NULL)MessageBox(hw,str,"Message",MB_OK);if(dust)GlobalFree(dust);dust=NULL;exit(1);}んでもって、プログラム中に「_dust」構造体を動的に確保すると仮定した場合、プログラムを終了する前にデータを解放しなければなりません。_dust)*145*612);if(dust==NULL)Quit("メモリを確保出来ませんでした");ここでメモリを動的に確保しています。動的に確保する方法は「malloc」だとか「new」だとか色々ありますが、今回はなんとなく「GlobalAlloc」を使用します。これはAPIだったかな?まぁ、この関数についての詳細はヘルプを参照してください。「GlobalAlloc(GMEM_FIXED,データサイズ);」としてやれば、データサイズ分のメモリを確保し、確保したメモリの先頭アドレスを返してくれます。この関数で確保したメモリを解放するのが「GlobalFree(メモリの先頭アドレス);」です(Quit()関数内で使用)。*)desc.lpSurface;この辺から、先程確保した構造体を初期化します。ここで、画像を読み込んである作業用サーフェイスをロックしておきます。第12回」でやりました。(float)cos(angle*3.141592/180)*speed;dust[dust_max].y_add=-(float)sin(angle*3.141592/180)*speed;dust[dust_max].color=col;dust[dust_max].left=x/6+rand()%10;dust_max++;}}}上の方でも触れたように、画像の1ドット1ドット全てに対して1つのデータを作成します。画像の黒い部分「色番号0」は表示しないので、データは作成しません。あとはランダム値によって速度と角度を決め、そこから三角関数を使用してX、Yの増加値を決定します。第4回」でやりました。Quit();TranslateMessage(&msg);DispatchMessage(&msg);}}while(timeGetTime()<tim+1000/60);//60fps}return(FALSE);}データを作成してしまえば、あとは毎回各データのx,y座標にx,y増加量を足していき、画面に表示するだけです。今回はビデオメモリ(lpBack)を直接操作しているので、ビデオカードによっては「やたら遅い!」という事もあると思います。いった場合は、作業用バッファ(その2)としてオフスクリーンサーフェイスをシステムメモリ内に作成し、そこを直接操作してデータを書き込み、バックバッファへBltFastで転送、Flip・・・とすれば、多少は速くなると思いますのでやってみてください。演出・エフェクト編サンプルコードのダウンロードでは、まずサンプルコードをダウンロードし、解凍してください。C++でプロジェクトファイルを開いてください(「effec_06.dsw」をダブルクリックすれば開けます)。圧縮ファイルに含まれる「effec_06.exe」をダブルクリックし、実行してみてください(何かキーを押すと終了します)。Networkのロゴが下から徐々に表示されると思います。いうわけで、今回は徐々に画像を表示する方法を説明していきます。今回の主なコードはこれ。Quit();TranslateMessage(&msg);DispatchMessage(&msg);}}while(timeGetTime()<tim+33);//1000/30=33.333(30FPS)}return(FALSE);}今回のプログラムは簡単なので、すぐに解ると思います。演出・エフェクト編サンプルコードのダウンロードでは、まずサンプルコードをダウンロードし、解凍してください。C++でプロジェクトファイルを開いてください(「effec_05.dsw」をダブルクリックすれば開けます)。圧縮ファイルに含まれる「effec_05.exe」をダブルクリックし、実行してみてください(何かキーを押すと終了します)。?画面が切り替わり、写真が表示され、その明度が徐々に変わっていくのが解ると思います。明度のお勉強さて、明度を変更するというテクニックはよく見かけますよね?例えばゲームで何か表示していて、次のシーン(場面)に移りたい場合に、画面を段々暗くし(フェード・アウト)、画面が真っ暗な間に次の画像を読み込んでおき(まだ表示はしない)準備が終わったら段々明るくしていき(フェード・イン)新しいシーンが始まる・・・というのがあります。いったものは「パレットを操作」して明度を変更していると考えて良いでしょう。いうか、256色環境で明度を変更する方法はパレット操作以外まず無いです(近似色検索という解答は未定義)。パレットをどうやって変化させたらいいか、についでですが、簡単です。明るくしたければ各RGB値を増やしてやればいいし、暗くしたければRGB値を減らしてやればいいのです。RGB値が(100,25,30)だとして、1明るくしたいのなら各RGB値に1を足して(101,26,31)という感じ。ここで注意してもらいたいのが、各RGB値は0~255でなければならないと言うことです。255を越えた場合は255、0より小さくなった場合は0という風にです。あとはこの作業を256色パレット全てに行えばいい・・・はずですが、パレット0番と255番は白・黒固定色なので、それ以外を全て変更すればいいのです。今回はもうちょっと突っ込んでおきましょうかね。charred+=bright;if(red>255)red=255;if(red<0)red=0;というような事はしないようにしてくださいね。今回の主なコードはコレ。第6回」でやりました。第14回」でやりました。Quit();TranslateMessage(&msg);DispatchMessage(&msg);}}while(timeGetTime()<tim+16);//1000/60=16.666(60FPS)}return(FALSE);}見て解るとおり、一度画面に写真を表示したら、後はパレットを変更しているだけです。明度を変更する関数でマクロを使ってしまったので、初心者にはちょっと解りにくいかもしれませんが、これを機、マクロの勉強をしてみてください。マクロを使うとホント楽なので・・・あ、ちなみにビデオカードによっては、この「パレットを設定」する時間がやたらかかるものがあるので、「パレットを使えば高速に出来る!」とか思いこまないようにしてください。自作の「ドット絵」を投稿することができます。ドッターさん同士の交流の場としてご利用ください。書き込むことができます。blockworks.このサイトについてサイトマップRSSフィード。