メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.638) 高さ演算を作成する2  2006/02/01


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第638回 高さ演算を作成する2
 発行    2006年2月1日(水曜日)
 発行数   約2500

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

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

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

 年が明けて、ふと、ファミ通を買おうと思い立ちました。

 いつもは購入しないのですが、毎年恒例、年間売り上げが
載っていたので、買いました。

 私がこの場を借りて「面白い」と宣言した、戦国Basara、
グランディア3、ワンダと巨像、ファイアーエンブレム、
バイハザ4などが100位内にランクインしており、何よりです。

 私がこの場を借りて「駄目だ」と酷評した、メトロイド、
ファミコンウォーズ、ファントムキングダムなどがランク外で、
何よりです。

 そんな中、ニンテンドーDSがすごく流行していることを、
初めて知りました。

 それはいけないと、早速買いに走ったのですが、

★SOLDOUT!

 。。。今の時代に、そんなまさかSOLDOUTなんて。。。

{magclick}
/*========================================================*/
 今回のお題  << 高さ演算を作成する2 >>
/*========================================================*/

ドラクエマップ
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

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

 前回の仕様を、ソースコードにして見ましょう。

 とりあえず、マップチップたちにENUMで名前をつけます。

enum {
    MAPTIP_HOLE,        // 穴
    MAPTIP_POISON,      // 毒の沼地
    MAPTIP_BUSH,        // 茂み
    MAPTIP_GRASS,       // 草原
    MAPTIP_FOREST1,     // 森
    MAPTIP_FOREST2,     // 森(誤植)
    MAPTIP_TOWER1,      // 塔(下)
    MAPTIP_VILLAGE,     // 村
    MAPTIP_TOWER2,      // 塔(上)
    MAPTIP_CAVE,        // 洞窟
    MAPTIP_HILL,        // 丘
    MAPTIP_TOWN2,       // 町(右)
    MAPTIP_SHRINE,      // 祠
    MAPTIP_CASTLE7,     // 城(左上)
    MAPTIP_TOWN1,       // 町(左)
    MAPTIP_CASTLE9,     // 城(右上)
    MAPTIP_MOUNT,       // 岩山
    MAPTIP_PYRAMID,     // ピラミッド
    MAPTIP_CASTLE1,     // 城(左下)
    MAPTIP_CASTLE3,     // 城(右下)
    MAPTIP_DESERT,      // 砂漠
    MAPTIP_BRIDGE1,     // 橋(縦)
    MAPTIP_AGROUND,     // 浅瀬
    MAPTIP_BRIDGE2,     // 橋(横)
    MAPTIP_SEA_BEGIN = 24,  // 海(範囲開始)
    MAPTIP_SEA_END = 41     // 海(範囲終了)
};

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

 それぞれのマップチップにしたがって、初期値を設定します。

const int H = DEF_MAP_DATA_HEIGHT;
const int W = DEF_MAP_DATA_WIDTH;
for( i = 0; i < H; i++ ) {
    for( j = 0; j < W; j++ ) {
        UINT r = arand( ( UINT )i * W + j );
        switch( map_data[ i ][ j ] ) {
        // 高さ0 海、穴、建造物
        default :
            height[ i ][ j ] = 0;
            break;
        case MAPTIP_POISON :
        case MAPTIP_BUSH :
        case MAPTIP_GRASS :
        case MAPTIP_DESERT :
            height[ i ][ j ] = 20 + ( r & 63 );
            break;
        case MAPTIP_FOREST1 :
        case MAPTIP_FOREST2 :
            height[ i ][ j ] = 50 + ( r & 127 );
            break;
        case MAPTIP_HILL :
            height[ i ][ j ] = 100 + ( r & 255 );
            break;
        case MAPTIP_MOUNT :
            height[ i ][ j ] = 200 + ( r & 511 );
            break;
        }
    }
}

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

 それぞれのマップチップにしたがって、アップダウンを設定
します。
 4回ほど実行すれば、染み渡るでしょうか。

for( n = 0; n < 4; n++ ) {
    for( i = 0; i < H; i++ ) {
        for( j = 0; j < W; j++ ) {
            UINT r = arand( ( UINT )i * 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 h5 = height[ i ][ j ];
            float sh = ( h8 + h4 + h6 + h2 ) * 0.25f; //平均
            switch( map_data[ i ][ j ] ) {
            case MAPTIP_HOLE : break; // 0固定
            case MAPTIP_POISON :
            case MAPTIP_BUSH :
            case MAPTIP_GRASS :
            case MAPTIP_DESERT :
                h5 = h5 * 0.6f + sh * 0.4f + ( r & 63 ) - 32;
                if( h5 < 0 ) h5 = 0; // 海より低くならない
                break;
            case MAPTIP_FOREST1 :
            case MAPTIP_FOREST2 :
                h5 = h5 * 0.6f + sh * 0.4f + ( r & 127 );
                break;
            // 建造物の土台は、きわめて平均的に
            case MAPTIP_TOWER1 :
            case MAPTIP_VILLAGE :
            case MAPTIP_TOWER2 :
            case MAPTIP_TOWN2 :
            case MAPTIP_SHRINE :
            case MAPTIP_CASTLE7 :
            case MAPTIP_TOWN1 :
            case MAPTIP_CASTLE9 :
            case MAPTIP_PYRAMID :
            case MAPTIP_CASTLE1 :
            case MAPTIP_CASTLE3 :
            case MAPTIP_BRIDGE1 :
            case MAPTIP_BRIDGE2 :
                h5 = sh;
                break;
            case MAPTIP_AGROUND :
                h5 = h5 * 0.6f + sh * 0.4f + ( r & 31 );
                break;
            case MAPTIP_HILL :
                h5 = h5 * 0.7f + sh * 0.3f + ( r & 255 );
                break;
            case MAPTIP_MOUNT :
                h5 = h5 * 0.8f + sh * 0.2f + ( r & 511 );
                break;
            case MAPTIP_CAVE :
                h5 = h5 * 0.3f + sh * 0.7f - ( r & 31 );
                if( h5 < 0 ) h5 = 0;
                break;
            default : // 海全版
                h5 = h5 * 0.2f + sh * 0.8f - ( r & 31 );
                if( h5 < 0 ) h5 = 0;
                break;
            }
        }
    }
    memcpy( height, height2, sizeof( height ) );
}

 こんな感じでしょうか。

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

h5 * 0.2f + sh * 0.8f

 このように、片方に重みをつけて平均をとる計算を「加重平均」
といいます、うんちくですが。

 ついでに、加重の係数を求める計算を「時定数」といいます、
これもうんちくですが。

 上記の加重係数は、適当です。これはうんちくではありません。

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

 今後の予定です。

 1月16日月曜日 第631回 DX14 回転演算 済
 1月18日水曜日 第632回 DX15 マップを移動する 済
 1月20日金曜日 第633回 DX16 太陽を回す 済
 1月23日月曜日 第634回 乱数生成アルゴリズム 済
 1月25日水曜日 第635回 ドラクエ3のマップを得る 済
 1月27日金曜日 第636回 マップチップデータの作成 済
 1月30日月曜日 第637回 高さ演算を作成する 済
 2月 1日水曜日 第638回 高さ演算を作成する2 済
 2月 3日金曜日 第639回 高さ演算を作成する3
 2月 6日月曜日 第640回 DX17 ドラクエ3 3D

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

 次回は2月3日(金曜日)に、第639回をお送りします。
 お題は「高さ演算を作成する3」

 実際に動作を検証してみます。

 お楽しみに!

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

{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

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