メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.594) CE14 CCEGridクラス  2005/08/01


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第594回 CE14 CCEGridクラス
 発行    2005年8月1日(月曜日)
 発行数   約2500

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

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

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

 とうとう、8月になってしまいました。

 夏ですね!

 今年の私の夏休みは、10日もあります。

 ちょっと多めで嬉しいです。

 その間に何をやろうかなぁと思いつつ、3冊の本を購入しまし
た。

・プログラマの数学(4-7-73-2973-4)

・ゲーム開発のための数学・物理学入門(4-7973-2907-6)

・3DRPGプログラミング(4-7973-3046-5)

 ちょっと、3Dを勉強したい気分になったのです。

 3Dは学生時代、驚くことに10年前、授業で基礎を習いました。

 DQ8の影響を受けて、それを思い出し、頭の中が3DRPGなのです。

 とにかくあのレベルのDQ3をプレイしたくて気が狂いそうです。

 でも、順番からすると次のリメイクは7でしょうか、7は
いらないのですが。。。

{magclick}
/*========================================================*/
 今回のお題  << CE14 CCEGridクラス >>
/*========================================================*/

 前回までに、ワーク領域までが表示されるバージョンを作成し
ました。

 その時点で、メインのパーツとワークのパーツに似通った点が
あることに気が付きました。

 どちらも方眼の形をしているということで、座標管理などが
ほとんど同じです。

 というわけで、リファクタリングです。

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

 2つを見比べると、まったく共通する関数が幾つかあります。

// セル座標から選択位置を求める
int CCEGrid::MakeSel( int xnum, int ynum )
{
    return ( xnum << 16 ) + ynum;
}

// 選択位置からセル座標を求める
int CCEGrid::SelX( int sel )
{
    return ( sel >> 16 ) & 0x0FFFF;
}

// 選択位置からセル座標を求める
int CCEGrid::SelY( int sel )
{
    return sel & 0x0FFFF;
}

 この3つはまったく同じでした。はい、共通化。

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

 方眼座標からグラフィック座標を求める関数。

// セルの座標取得
int CCEGrid::GetCellX2( int xnum )
{
    return GetCellX1( xnum + 1 ) - 1;
}

// セルの座標取得
int CCEGrid::GetCellY2( int ynum )
{
    return GetCellY1( ynum + 1 ) - 1;
}

 終点を求めるこの2つは、始点を求める関数を応用している
ため、まったく同じです。はい、共通化。

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

 始点を求める関数は、少々違いました。

 そもそもメインのほうは、セルごとの画面上の大きさが一定では
なかったため、特殊な計算をしていました。

 一定でいいじゃないか、というわけで、メインの座標管理を
ワークにあわせて、無理やり共通化しました。

// セルの座標取得
int CCEGrid::GetCellX1( int xnum )
{
    return xnum * m_cell_width + 2;
}

// セルの座標取得
int CCEGrid::GetCellY1( int ynum )
{
    return ynum * m_cell_width + 2;
}

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

 メインにはセルウィドスという考え方がなかったため、それを
仕込む必要があります。

// 1セルあたりのドット数
int CCEMain::GetCellWidth()
{
    return ( imgFile.GetWidth() + m_cell_size - 1 )
        / m_cell_size;
}

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

 座標管理が同じになると、ヒットチェックも共通化できます。

// ヒットチェック
int CCEGrid::HitCheck( POINT& pos )
{
    const int m = m_hit_mergin;    // マージン
    int xnum = GetXNum();
    int ynum = GetYNum();
    // マウス座標を表座標に変換、ヒスを使わず
    int xs = ( pos.x - 2 ) / m_cell_width;
    int ys = ( pos.y - 2 ) / m_cell_width;
    int sx1 = GetCellX1( xs ) + m;
    int sx2 = GetCellX2( xs ) - m;
    int sy1 = GetCellY1( ys ) + m;
    int sy2 = GetCellY2( ys ) - m;
    int s = MakeSel( xs, ys );
    if( xs >= m_cell_size || ys >= m_cell_size ||
        pos.x < sx1 || pos.x > sx2 ||
        pos.y < sy1 || pos.y > sy2 )    // 範囲外だったら、
    {
        s = m_sel; // 現在と同じ値を返す
    }
    return s;
}

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

 座標管理を同じにしたことで、背景描画を共通化できます。

// 背景描画
void CCEGrid::DrawBack( void )
{
    CCEImage::DrawBack();   // 背景色を黒で塗りつぶし
    int xnum = GetXNum();
    int ynum = GetYNum();
    CDC& dc = *CDC::FromHandle( img.GetDC() );
    int i, j;
    for( i = 0; i < ynum; i++ )
    {
        for( j = 0; j < xnum; j++ )
        {
            DrawCell( dc, j, i );
        }
    }
    img.ReleaseDC();
    
    // フレームの描画
    DrawFrame();
}

 セル描画の呼び出しが少々違いましたが、統一しました。

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

 座標管理を同じにしたことで、フレーム描画を同じにできます。

// フレームの描画
void CCEGrid::DrawCellFrame(
    CDC& dc, int xn, int yn, COLORREF col )
{
    int x1 = GetCellX1( xn ) - 1;
    int x2 = GetCellX2( xn ) + 1;
    int y1 = GetCellY1( yn ) - 1;
    int y2 = GetCellY2( yn ) + 1;
    dc.FrameRect(
        &CRect( x1, y1, x2, y2 ), &CBrush( col ) );
}

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

 というわけで、そんな感じのバージョンを固めました。

(VC++7.0プロジェクト)
http://ayusya.hp.infoseek.co.jp/Download/CE_050801_src.zip

 実行内容は同じですが、CCEGridクラスが新たに作成されて
います。

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

 山登りができるようにしてもらいたいですよね。

 8はちょっと段差があると進入できなくて、それが不満でした。

 気合でよじ登っていただきたいものです。

 あとジャンプ、ここまでやってしまうとマリオですが、

 そんな感じがいいです。

 8では乗り物はキラーパンサーのみでしたが、

 3では職業ごとにデフォルトで最初から使えると楽しそうです。

 勇者は馬。

 魔法使い(女)は魔法のほうき。

 魔法使い(男)は魔法の車椅子(遅いが、壁張り付き機能付き)

 武闘家は走る。武闘家だから。

 遊び人(女)はスケートボード。

 遊び人(男)は巨大一輪車(遅いが、楽しい)

 戦士は走る。ひび割れた壁を破壊できる!

 当然、レベルアップするとグレードアップするわけで、

 勇者はペガサス。

 魔法使い(女)は魔法のじゅうたん(恒例)。

 魔法使い(男)は魔法のベッド(点滴つき)。

 武闘家はもっと早く走る。山を越えて谷を飛ぶ!

 遊び人(女)はジェットボード(スピードアップ)

 遊び人(男)はパレードカー(派手さ倍増)

 戦士は走る。普通の壁や木等も破壊できる!

 あ、楽しい〜

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

 次回は8月3日(水曜日)に、第595回をお送りします。
 お題は「CE15 メインとワークの入出力」

 お絵かき機能をつけて、休み前の最後の配送とします。

 お楽しみに!

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

{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

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