メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.632) DX15 マップを移動する  2006/01/18


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第632回 DX15 マップを移動する
 発行    2006年1月18日(水曜日)
 発行数   約2500

{magclick}
/*========================================================*/
 はじめに ( 決り文句 )
/*========================================================*/
・このメールマガジンは、主にまぐまぐさんから発行しています。
・ジャンルは、マルチメディアのプログラム、C言語です。
・横60文字で作成し、インデントは大抵半角スペース4つです。
・ここで扱うプログラムは、C言語と半光年以内のものです。
・登録解除は、メルマガのホームページでお願いします。
・過去ログはバックナンバー(下欄参照)を活用して下さい。
・内容は私が感じたもので、最新の技術も、へたれもあります。
・わかりやすさを優先させる為、たまに嘘があるかもしれません。

/*========================================================*/
 ご挨拶
/*========================================================*/

 こんにちは、あゆしゃです。

 お正月休みの間、ツタヤでDVDを借りました。

 バットマンビギンズ。

 前半はバットマンになるまでのお話、

 後半は新人バットマンが悪戦苦闘するお話。

 なぜバットなのか、なぜバットマンは強いのかが語られていて、
その当たりの秘密が明かされていくわけですが、

 ストーリー展開が淡々としていて、盛り上がりにかけます。

 ストーリーに目的がまったくないため、途中で飽きてしまうのは
私だけでしょうか?

{magclick}
/*========================================================*/
 今回のお題  << DX15 マップを移動する >>
/*========================================================*/

 前回の内容に、誤植がありました。

誤 90度だと1.07ラジアン、

正 90度だと1.57ラジアン、

 3.14の半分は、1.57です。

 やはり、あゆしゃは数学が苦手のようです。

/*========================================================*/

 前回までに、32*32のマップ(といっても平面でが)を表示
しました。

http://ayusya.hp.infoseek.co.jp/Image/DirectXSample_060113_3.png

 そして前回、回転演算について方法を紹介しました。

 今回は、実際にマップを移動できるようにしましょう。

/*========================================================*/

 今まで、簡略化のために関数を1つ作ってその中ですべてを
行っていました。

 今回はリアルタイム処理が必要なため、その関数を3つに
分けます。

1.DX_Init
2.DX_Draw
3.DX_End

 初期化、描画処理、そして終了処理の3つです。

 描画処理用の関数はタイマープロックから33ミリ秒ごとに実行
されるようにしましょう。

/*========================================================*/
★タイマープロックの登録

 InitInstance にて、以下のように登録します。

SetTimer( hWnd, 33, 33, ( TIMERPROC )DX_Timer );

 MFCを使用していないので、純水なAPIを使用します。

 33は、左がIDで右が時間(ミリ秒)ですが、どっちでも
いいです。

 タイマープロックは、次のように定義します。

void DX_Timer( HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime )

 いろいろと引き数がわたってきますが、ほとんど使いません。

 タイマープロック内部には、

1.初期化
2.キー入力
3.DX_Draw呼び出し

 この3つを行います。

 タイマーの中に初期化があるのは、リサイズによってDXを
初期化する必要があるためです。

/*========================================================*/
★キー入力定義の決定

 キーは次のように使いましょう。

・十時キー    前後左右の平行移動
・テンキー【4】 左回転
・テンキー【6】 右回転

// 入力処理
if( GetKeyState( VK_UP ) < 0 ) {
    DX_Move( D3DXVECTOR3( 0, 0, 1 ) );
}
if( GetKeyState( VK_DOWN ) < 0 ) {
    DX_Move( D3DXVECTOR3( 0, 0, -1 ) );
}
if( GetKeyState( VK_LEFT ) < 0 ) {
    DX_Move( D3DXVECTOR3( -0.5, 0, 0 ) );
}
if( GetKeyState( VK_RIGHT ) < 0 ) {
    DX_Move( D3DXVECTOR3( 0.5, 0, 0 ) );
}
if( GetKeyState( VK_NUMPAD4 ) < 0 ) {
    DX_Rotate( -0.01f );
}
if( GetKeyState( VK_NUMPAD6 ) < 0 ) {
    DX_Rotate( 0.01f );
}

 DX_MoveとDX_Rotateは、次のようにします。

// ========================================
// カメラ移動
void DX_Move( D3DXVECTOR3& move )
{
    D3DXMATRIX m;
    D3DXMatrixRotationY( &m, ViewRot );
    D3DXVec3TransformCoord( &move, &move, &m );
    ViewFrom += move;
    ViewTo   += move;
    D3DXMatrixLookAtLH( &ViewMat, &ViewFrom, &ViewTo, &ViewUp );
    pDev->SetTransform( D3DTS_VIEW, &ViewMat );
}

// ========================================
// カメラ回転
void DX_Rotate( float radi )
{
    ViewRot += radi;
    D3DXMATRIX m;
    D3DXMatrixRotationY( &m, ViewRot );
    D3DXVECTOR3 sa( 0, 0, 0.5f );
    D3DXVec3TransformCoord( &ViewTo, &sa, &m );
    ViewTo += ViewFrom;
    D3DXMatrixLookAtLH( &ViewMat, &ViewFrom, &ViewTo, &ViewUp );
    pDev->SetTransform( D3DTS_VIEW, &ViewMat );
}

 処理の内容については、前回説明したとおりです。

 ViewFromとViewToとViewRotは、間単に
グローバル変数としましょう。

// ========================================
// カメラ情報
D3DXVECTOR3 ViewFrom( 0, 1, 0 );// 高さ1メートル、XZが座標
D3DXVECTOR3 ViewTo( 0, 0, 5 );  // 向いている方角へ
D3DXVECTOR3 ViewUp( 0, 1, 0 );  // カメラの背中の方向
float ViewRot( 0.5f );    // カメラの方向(最初は北の方向)

/*========================================================*/

 以上を実装すると、マップ上を移動できるようになります。

 ウィンドウをリサイズすると、DirectXも再初期化され
て、新しいサイズで描画されます。

 今回のソースです。VC++7.0以上でコンパイルできます。
http://ayusya.hp.infoseek.co.jp/Source/DX9Sample_060118.cpp

 実行結果の画像です。
http://ayusya.hp.infoseek.co.jp/Image/DirectXSample_060118.png

/*========================================================*/

 前々回のサンプルコードをアップし忘れていたようです。
失礼しました。

http://ayusya.hp.infoseek.co.jp/Source/DX9Sample_060113.cpp

{magclick}
/*========================================================*/
 さいごに
/*========================================================*/

 今後の予定です。

 1月 9日月曜日 第628回 2006年 済
 1月11日水曜日 第629回 マグクリック報告 済
 1月13日金曜日 第630回 DX13 マップを描画 済
 1月16日月曜日 第631回 DX14 回転演算 済
 1月18日水曜日 第632回 DX15 マップを移動する 済
 1月20日金曜日 第633回 DX16 太陽を回す
 1月23日月曜日 第634回 乱数生成アルゴリズム

{magclick}
/*========================================================*/
 次回予告
/*========================================================*/

 次回は1月19日(金曜日)に、第633回をお送りします。
 お題は「DX16 太陽を回す」

 光源が原点を中心にぐるぐる回るようにしましょう。

 昼と夜の明暗が良くわかります。

 お楽しみに!

/*========================================================*/
 最後の決り文句
/*========================================================*/
 このメールマガジンは、まぐまぐさんから発行しています。
 このメールマガジンを解除したい場合は、まぐまぐさんをご利用
ください。このメルマガのまぐまぐアイディーは最後にあります。
 このメールマガジンには広告が挿入されていますか?
 このメールマガジンの内容に文面の引用はありませんか?
 めーらっくすの場合はめーらっくすの利用方に従ってください。
 このメールマガジンの内容の、転用、流用、宣伝、リンク、
がきーん なんて大歓迎です。

{magclick}
/*========================================================*/
 
/*========================================================*/

発行者 あゆしゃ

ホームページ::あゆしゃの世界
http://ayusya.hp.infoseek.co.jp/

ご意見・ご感想・ご質問メール
mailto:ayusya@flamenco.plala.or.jp

まぐまぐ::アイディー
0000020674

まぐまぐ::登録と解除
http://www.mag2.com/m/0000020674.htm

まぐまぐ::バックナンバー
http://jazz.tegami.com/backnumber/frame.cgi?id=0000020674

めーらっくす::アイディー
MM3E1AEE285AB4F

めーらっくす::登録と解除
http://www.mailux.com/mm_dsp.php?mm_id=MM3E1AEE285AB4F

めーらっくす::バックナンバー★最近のものならこちらが便利★
http://www.mailux.com/mm_bno_list.php?mm_id=MM3E1AEE285AB4F

ブラウザの閉じるボタンで閉じてください。