|
/*========================================================*/ <<<あゆしゃのC言語プログラミング>>> /*========================================================*/ 第586回 CE6 CCEPaletクラス 発行 2005年7月13日(水曜日) 発行数 約2600 {magclick} /*========================================================*/ はじめに ( 決り文句 ) /*========================================================*/ ・このメールマガジンは、主にまぐまぐさんから発行しています。 ・ジャンルは、マルチメディアのプログラム、C言語です。 ・横60文字で作成し、インデントは大抵半角スペース4つです。 ・ここで扱うプログラムは、C言語と半光年以内のものです。 ・登録解除は、メルマガのホームページでお願いします。 ・過去ログはバックナンバー(下欄参照)を活用して下さい。 ・内容は私が感じたもので、最新の技術も、へたれもあります。 ・わかりやすさを優先させる為、たまに嘘があるかもしれません。 ・セキュリティ突破のため、暗号化された単語があります。 /*========================================================*/ ご挨拶 /*========================================================*/ こんにちは。あゆしゃです。 今週は、最悪な日々です。 。。。ワンピースのないジャンプなんて。。。 ねぇ? {magclick} /*========================================================*/ 今回のお題 << CE6 CCEPaletクラス >> /*========================================================*/ 気を取り直して、CCEPaletクラスの作成です。 前回のCCEImageクラスを継承し、パレット処理を作成します。 class CCEPalet : public CCEImage { protected: enum { PAL_SIZE = 16 }; enum { PAL_HEIGHT = 32 }; COLORREF pal[ PAL_SIZE ]; public: virtual BOOL CheckResize( int width, int height ); virtual int HitCheck( POINT& pos ); virtual void DrawBack( void ); virtual void EraseSelect( void ); virtual void DrawSelect( void ); }; 。。。なんだかバーチャルばっかりですが。。。 各パーツごとよりも、CCEImageとして扱えたほうが便利かと 思い、仮想関数をいっぱい作ってみました。 /*========================================================*/ CheckResizeは、CCEImageの関数としちゃいましたが、パーツ ごとにサイズが違うということを忘れていました。 BOOL CCEPalet::CheckResize( int width, int height ) { // 幅は最大、縦の大きさは固定 return CCEImage::CheckResize( width, PAL_HEIGHT ); } /*========================================================*/ ヒットチェックは、マウスの位置と画像の位置から、現在の 選択位置を判定します。 忘れていましたが、スクリーン上に描画する位置とサイズは、 CCEImageが持っています、ということにします。 イメージそのものに合わさっているかどうかは、CCEImageのほう で大雑把に判定することにしましょう。 void CCEImage::CheckSelect( POINT& pos ) { if( pos.x > m_dx && // 始点より大きく、 pos.y > m_dy && pos.x < m_dx2 && // 終点より小さく、 pos.y < m_dy2 ) { int sel = HitCheck( pos ); if( sel != m_sel ) { m_selold = sel; m_sel = sel; } } } int CCEPalet::HitCheck( POINT& pos ) { const int m = 2; // マージン int x = pos.x - m_dx; // クライアント座標に変換 int y = pos.y - m_dy; int s = x / PAL_SIZE; // 選択位置に変換 int x1 = m_dx + GetPalX1( s ) + m; // 選択開始位置 int x2 = m_dx + GetPalX2( s ) - m; // 選択終了位置 if( x < x1 && x > y2 && y < m_dy + m && y > m_dy2 - m ) // 範囲外だったら、 { s = m_sel; // 現在と同じ値を返す } return s; } 1つのパレットの範囲は描画処理でも使用する計算なので、 別関数にしました。 int CCEPalet::GetPalX1( int no ) { return no * m_dw / PAL_SIZE; } int CCEPalet::GetPalX2( int no ) { return ( no + 1 ) * m_dw / PAL_SIZE - 1; } 境界線のところの判定がシビアだと不便になるので、少し マージンを入れています。 /*========================================================*/ 前回はDrawBallと書きましたが、選択を描画する前の処理全般、 ということにしてみました。 void CCEPalet::DrawBack( void ) { CCEImage::DrawBack(); // 背景色を黒で塗りつぶし CDC& dc = *CDC::FromHandle( img.GetDC() ); // DC取得 for( int i = 0; i < PAL_SIZE; i++ ) { DrawBall( dc, i ); // 描画処理 } img.ReleaseDC(); // DC開放 } 円を描く処理はEeraseSelectでも使用するので、別関数に しました。 void CCEPalet::DrawBall( CDC& dc, int palno ) { int x1 = palno * m_dw / PAL_SIZE; // 描画位置 int x2 = ( palno + 1 ) * m_dw / PAL_SIZE - 1; int cx = ( x2 + x1 ) / 2; int dx1 = cx - cr; int dx2 = cx + cr; int dy1 = m_dh / 4; // 描画位置 int dy2 = m_dh * 3 / 4; int cr = ( y2 - y1 ) / 2; // 円の半径 CBrush b( pal[ i ] ); CBrush* pb = dc.SelectObject( &b ); // 色指定 dc.Ellipse( dx1, dy1, dx2, dy2 ); // 描画実行 dc.SelectObject( pb ); } /*========================================================*/ 選択を消す処理は、その範囲を背景色で消して、丸を再描画 します。 void CCEPalet::EraseSelect( void ) { CDC& dc = *CDC::FromHandle( img.GetDC() ); // DC取得 int x1 = GetPalX1( m_selold ); int x2 = GetPalX2( m_selold ); dc.FillSolidRect( x1, 0, x2 - x1, PAL_HEIGHT, GetBackColor() ); DrawBall( dc, m_selold ); img.ReleaseDC(); // DC開放 } 選択は、現在位置を四角で囲いましょう。 void CCEPalet::DrawSelect( void ) { CDC& dc = *CDC::FromHandle( img.GetDC() ); // DC取得 int x1 = GetPalX1( m_selold ); int x2 = GetPalX2( m_selold ); dc.FillSolidRect( x1, 0, x2 - x1, PAL_HEIGHT, GetSelColor() ); img.ReleaseDC(); // DC開放 } {magclick} /*========================================================*/ さいごに /*========================================================*/ 雨も降るし、中途半端に。。 {magclick} /*========================================================*/ 次回予告 /*========================================================*/ 次回は7月15日(金曜日)に、第587回をお送りします。 お題は「CE7 キャラエディッタ1」 とりあえず、パレットの選択のできるバージョンを固めましょ う。 お楽しみに! /*========================================================*/ 最後の決り文句 /*========================================================*/ このメールマガジンは、まぐまぐさんから発行しています。 このメールマガジンを解除したい場合は、まぐまぐさんをご利用 ください。このメルマガのまぐまぐアイディーは最後にあります。 このメールマガジンには広告が挿入されていますか? このメールマガジンの内容に文面の引用はありませんか? めーらっくすの場合はめーらっくすの利用方に従ってください。 このメールマガジンの内容の、転用、流用、宣伝、リンク、 次回は金曜日ですよ! なんて大歓迎です。 {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 |