メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.642) DX19 高さ演算の再検証  2006/02/10


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第642回 DX19 高さ演算の再検証
 発行    2006年2月10日(金曜日)
 発行数   約2500

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

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

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

 先日、とんでもない事件がおきました。

 プリウスのドアミラーのモーターが回りっぱなしで、とまらなく
なってしまったのです。

 車が動くのに支障はないのですが、

ヴぃぃーーーーーーーーん

 バッテリーがなくなるのではないかと思ったのですが、

ヴぃぃーーーーーーーーん

 さほどでもなく、

ヴぃぃーーーーーーーーん

 とにかく、

ヴぃぃーーーーーーーーん


★うるさい。。!


 というわけで、修理に出しました。

 しばらくプリウスとお別れです。


 モーターが回りっぱなしになるということは、マイコンで制御
されているわけではないということですね。

 マイコンで制御している場合、モーターが回り続けていれば、

★喜んで異常を検出しますとも。

 意外にハードウェア駆動なのですね。

{magclick}
/*========================================================*/
 今回のお題  << DX19 高さ演算の再検証 >>
/*========================================================*/

ドラクエマップ
http://xb_lim.at.infoseek.co.jp/dq/

マップチップ
http://ayusya.hp.infoseek.co.jp/Image/dq3maptipitems.png

マップデータソース
http://ayusya.hp.infoseek.co.jp/Source/dq3mapdata.h

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

 前回、マテリアルで色をつけました。

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

 しかしアップダウンが激しすぎて、何がなんだかわかりません。

 そこで、高さ演算について、再検討します。

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

 構造体を1つ作りましょう。

 高さ演算について、マップチップ番号をスイッチで分岐させて
いましたが、

 今後、BGを階層化するときに、スイッチで実装されていては
面倒です。

 構造体にデータを一生懸命入力して、処理を一括で実行できる
ようにします。

 構造体には、初期値として使うものと、高さ演算で使うものを
用意します。

 それぞれに基準値と上下幅を用意します。

 周囲の平均値に対して基準値を足し、さらに上下幅を足すという
計算になります。

struct updn_t
{
    // セルサイズを1とする比率を指定
    float init_base;        // 初期値の基準値
    float init_range;       // 初期値の上下幅*位置乱数
    float updn_base;        // 上下幅のベース
    float updn_range;       // 上下幅の上下幅*位置乱数
} updn[ DEF_MAP_TIP_NUM ] = {
    +0.0f,+0.0f,-1.0f,+0.0f,// 穴
    +0.1f,+0.0f,-0.1f,+0.0f,// 毒の沼地
    +0.1f,+0.0f,-0.1f,+0.2f,// 茂み
    +0.1f,+0.0f,-0.1f,+0.3f,// 草原
    +0.2f,+0.0f,+0.0f,+0.2f,// 森
    +0.2f,+0.0f,+0.0f,+0.2f,// 森(誤植)
    +0.1f,+0.0f,+0.0f,+0.0f,// 塔(下)
    +0.1f,+0.0f,+0.0f,+0.0f,// 村
    +0.2f,+0.0f,+0.0f,+0.0f,// 塔(上)
    +0.0f,+0.0f,-0.0f,+0.0f,// 洞窟
    +0.3f,+0.0f,+0.2f,+0.2f,// 丘
    +0.1f,+0.0f,+0.0f,+0.0f,// 町(右)
    +0.1f,+0.0f,+0.0f,+0.0f,// 祠
    +0.1f,+0.0f,+0.0f,+0.0f,// 城(左上)
    +0.1f,+0.0f,+0.0f,+0.0f,// 町(左)
    +0.1f,+0.0f,+0.0f,+0.0f,// 城(右上)
    +0.5f,+0.0f,+0.5f,+1.5f,// 岩山
    +0.1f,+0.0f,+0.0f,+0.0f,// ピラミッド
    +0.1f,+0.0f,+0.0f,+0.0f,// 城(左下)
    +0.1f,+0.0f,+0.0f,+0.0f,// 城(右下)
    +0.1f,+0.0f,-0.1f,+0.3f,// 砂漠
    +0.1f,+0.0f,+0.0f,+0.0f,// 橋(縦)
    +0.0f,+0.0f,+0.0f,+0.0f,// 浅瀬
    +0.1f,+0.0f,+0.0f,+0.0f,// 橋(横)
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.0f,+0.0f,-0.1f,-0.1f,// 海
    +0.5f,+0.0f,-0.3f,+1.7f,// 氷
};

 。。。ふぅ。

 マップの初期化も、それに伴い修正しますが、

 配列にしたおかげで、こちらはシンプルになります。

int i, j, n;
const int H = DEF_MAP_DATA_HEIGHT;
const int W = DEF_MAP_DATA_WIDTH;
float height2[ H ][ W ];
UINT cs = ( UINT )cellsize;
for( i = 0; i < H; i++ ) {
    for( j = 0; j < W; j++ ) {
        UINT R = ( UINT )( ( i * W + j ) * cellsize );
        float r = ( float )arand( R ) / 0xFFFFFFFF;
        updn_t& u = updn[ map_data[ i ][ j ] ];
        height[ i ][ j ] =
            u.init_base + u.init_range * r * cellsize;
    }
}
const int N = 8;
for( n = 0; n < N; n++ ) {
    for( i = 0; i < H; i++ ) {
        for( j = 0; j < W; j++ ) {
            // 上下左右の値を取得
            float h8 = height[ ( i + H + 1 ) % H ][ j ];
            float h4 = height[ i ][ ( j + W + 1 ) % W ];
            float h6 = height[ i ][ ( j + 1 ) % W ];
            float h2 = height[ ( i + 1 ) % H ][ j ];
            float sh = ( h8 + h4 + h6 + h2 ) * 0.25f; //平均
            // 乱数決定
            UINT R = ( UINT )( ( i * W + j ) * cellsize );
            float r = ( float )arand( R ) / 0xFFFFFFFF;
            // データ設定
            updn_t& u = updn[ map_data[ i ][ j ] ];
            float h = sh + u.updn_base/N*cellsize
                + u.updn_range * r/N * cellsize;
            if( h < 0 ) h = 0;
            height2[ i ][ j ] = h;
        }
    }
    memcpy( height, height2, sizeof( height ) );
}

 この、上下左右の値を平均化するときに、自分自身の座標を
入れてしまっていました。

 これによって座標が再帰的に爆発してしまい、前回のような
面白厳しいアップダウンになってしまっていました。

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

 乱数の初期値を変更しています。

 いままではマップデータの座標で行っていましたが、それを
メートルに変えました。

 そうしないと、今後、BGを階層化したときに困るのです。

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

 なじみの塔から北側の川を眺めた様子です。

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

 アップダウンが落ち着いて、それらしくなりました。

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

 今後の予定です。

 1月30日月曜日 第637回 高さ演算を作成する 済
 2月 1日水曜日 第638回 高さ演算を作成する2 済
 2月 3日金曜日 第639回 高さ演算を作成する3 済
 2月 6日月曜日 第640回 DX17 ドラクエ3 3D 済
 2月 8日水曜日 第641回 DX18 マテリアルの設定 済
 2月10日金曜日 第642回 DX19 高さ演算の再検証 済
 2月13日月曜日 第643回 DX20 キーボード操作
 2月15日水曜日 第644回 DX21 座標変更
 2月17日金曜日 第645回 DX22 当たり判定
 2月20日月曜日 第646回 DX23 BGの階層化

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

 次回は2月13日(月曜日)に、第643回をお送りします。
 お題は「DX20 キーボード操作」

 キーボードの操作が、結構複雑になりそうです。

 まとめておきましょう。

 お楽しみに!

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

{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

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