|
/*========================================================*/ <<<あゆしゃの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 |