Comments
Description
Transcript
C言語 (+DXライブラリ)でお絵描きしてみよう 1. 始め方
C 言語 (+DX ライブラリ) でお絵描きしてみよう 情報システム学科 坂本 政祐 情報システム学科の IT 専攻では,2 年生になると必修のプログラミングの講義で C 言語をみっ ちり学びます。ただ,そこでやる C 言語は,文法からきっちり学ぶ関係上,楽しい例題とかはあん まりありません。 それが理由で,C 言語や,あまつさえプログラミングまで嫌いになってしまったら非常に悲しい ことです。そこで今回は,C 言語でもまあまあ楽しめる課題ということで,「C 言語でお絵描き」 ということをやってみようかと思います。 ただしできることは,せいぜい,線を引く,四角形・三角形を描く,円を描く,文字を描く,程 度ですが,これらを組み合わせれば簡単な造形のものは描けるでしょう。 ただし,実は C 言語にはもともと「グラフィックを描く」という機能は一切用意されていないの ディーエックス で,今回は「 DX ライブラリ」という,主にゲーム開発などで使われるライブラリの助けを借 ります。どこまでが標準の C 言語でどこからが DX ライブラリなのか,などについては区別つかな くても全く構いません1 。 1. 始め方 1. すぐに始められるテンプレートを坂本の方で用意しました。oekaki フォルダをデスクトップ などにコピーし,その中の 2. エディタ領域に以下のようなソースコードが現れます。 リスト 1 をダブルクリックして開いて下さい。 1: oekaki.cpp の一番最初 #include <DxLib.h> 2 3 4 #define HABA 480 #define TAKASA 480 5 6 7 8 9 int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR lpCL, int nCS) { SetOutApplicationLogValidFlag(false); ChangeWindowMode(TRUE); 10 11 SetMainWindowText("お絵描き"); SetGraphMode(HABA, TAKASA, 32); SetBackgroundColor(255, 255, 255); DxLib_Init(); 12 13 14 15 16 // こ こ の 下 に 作 っ て い く 17 18 WaitKey(); DxLib_End(); return 0; 19 20 21 3. 1 } このソースコードの「// ここの下に作っていく」というところに,後述の様々な関数を記述 していくことで絵を描いていきます。 なお, DX ライブラリの関数一覧は以下のページにあります。興味があったら参照してみて下さい。 http://homepage2.nifty.com/natupaji/DxLib/dxfunc.html 1 ▲ 4. この段階ではまだ何も表示されませんが,とりあえず ボタンで実行させてみましょう。 ビルドしますか?と聞いてきたら はい (Y) 2. 2.1 です。 線や円で四角でお絵描き 準備:ウィンドウの座標系 ウィンドウ上に線などを描く場合, 「どの点からどの点まで」のように指定することになります。 ということは,点の座標の指定が必要になってきます。ただし,数学でよく使う座標系とは異なり, 左上が原点で,y 軸は下向きが正なので注意してください(図 1)。 今回のプログラムではウィンドウサイズは 480 × 480 ピクセルにしてあります。以降ではこの 大きさを前提に話を進めます。ちなみに 3 行目∼4 行目の HABA の値と TAKASA の値を変えることで ウィンドウサイズは変更できますので,変更しても OK です。 (0,0) x (479,0) y (0,479) 図 2.2 1: (479, 479) ウィンドウの座標系 色の指定:GetColor(…) GetColor(赤成分 (0∼255), 緑成分 (0∼255), 青成分 (0∼255)) 以降で「色指定」が必要な部分については,GetColor(255,255,255) などのように書いてくださ い。3 つの数字はそれぞれ赤成分,緑成分,青成分で,いわゆる光の三原色です。例えば GetColor(255,0,0) なら真っ赤ということになります。 ただ,三原色をどのように混ぜあわせるとどんな色になるかって見当つかないですよね。という わけで,色見本を用意しました。以下にアクセスして下さい。 http://goo.gl/7wShr 2 直線を引く:DrawLine(…) 2.3 DrawLine(x1 , y1 , x2 , y2 , 色指定, 線の太さ); 始点 (x1 , y1 ) から終点 (x2 , y2 ) まで直線を引く関数です。 原点 x ( x1, y1 ) y ( x2, y2 ) 図 図 3 2: DrawLine() 関数 は,以下のような 2 本の線を引いてみた例です。 • DrawLine(100, 100, 240, 240, GetColor(255, 0, 0), 1); (赤い線) • DrawLine(100, 350, 400, 350, GetColor(0, 255, 0), 10); (緑の太い線) 図 3: DrawLine() 関数の実行例 3 四角形を描く:drawBox(…) 2.4 DrawBox(x1 , y1 , x2 , y2 , 色指定, 塗りつぶすか否か); DrawBox() は,左上を (x1 , y1 ) として,右下を (x2 , y2 ) とした2 四角形を描きます。 「塗りつぶすか否か」の部分には以下のどちらかを指定します。 • TRUE: 塗りつぶす • FALSE: 塗りつぶさない 原点 x ( x1, y1 ) y ( x2, y2 ) 図 図 5 4: DrawBox() 関数 は,以下のような 2 個の四角形を描いてみた例です。 • DrawBox(100, 100, 200, 200, GetColor(255, 0, 0), TRUE); (赤い四角形,塗りつ ぶし) • DrawBox(100, 350, 400, 380, GetColor(0, 0, 255), FALSE); (青の四角形,塗り つぶさない) 図 2 より正確には右下 5: DrawBox() 関数の実行例 +1 の座標ですが,ここではあまり気にしなくて良いです 4 2.5 円を描く:DrawCircle(…) DrawCircle(x1 , y1 , r , 色指定, 塗りつぶすか否か); DrawCircle() は,中心を (x1 , y1 ) として,半径を r とした円を描きます。塗りつぶすか否かは TRUE / FALSE です。 原点 x r y ( x1, y1 ) 図 2.6 6: DrawCircle() 関数 楕円を描く:DrawOval(…) DrawOval(x1 , y1 , rx , ry , 色指定, 塗りつぶすか否か); DrawOval() は,中心を (x1 , y1 ) として,横方向の半径を rx ,縦方向の半径を ry とした楕円を 描きます。塗りつぶすか否かは TRUE / FALSE です。 原点 x ry y rx ( x1, y1 ) 図 7: DrawOval() 関数 5 2.7 三角形を描く:drawTriangle() DrawTriangle( x1 , y1 ,x2 , y2 , x3 , y3 , 色指定, 塗りつぶすか否か); DrawTriangle() は,(x1 , y1 ),(x2 , y2 ),(x3 , y3 ),の 3 つの座標を頂点とした三角形を描きます。 塗りつぶすか否かは TRUE / FALSE です。 原点 x ( x1, y1 ) ( x3, y3 ) y ( x2, y2 ) 図 2.8 DrawTriangle() 関数 8: 文字列を描く:SetFontSize(), DrawString() フォントサイズ指定:SetFontSize(フォントサイズ); 文字列描画 :DrawString(x1 , y1 , "文字列", 色指定);| まず SetFontSize() でフォントのサイズを指定しておいてから,次に DrawString() で文字列 を描きます。 (x1 , y1 ) の位置から"文字列"を描画します。この座標は文字列の左上を意味します。 原点 x ( x1, y1 ) 文字列 y 図 9: DrawString() 関数 6 3. お絵描きの例 これまでに出て来た各種の関数を使って,一個絵を描いてみました。「時計」です。行数は多い ですが,単にこれまでのを組み合わせただけです。 リスト 1 2: 時計を描いてみた #include <DxLib.h> 2 3 4 #define HABA 480 #define TAKASA 480 5 6 7 8 9 int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR lpCL, int nCS) { SetOutApplicationLogValidFlag(false); ChangeWindowMode(TRUE); 10 11 SetMainWindowText("お絵描き"); SetGraphMode(HABA, TAKASA, 32); SetBackgroundColor(255, 255, 255); 12 13 14 DxLib_Init(); 15 16 17 // 時 計 の 外 枠:(240, 240) を 中 心 と し た 半径220 の 円 。 オ レ ン ジ 色 。 DrawCircle(240, 240, 220, GetColor(255, 99, 71), TRUE); 18 19 20 // 時 計 の 内 側:(240, 240) を 中 心 と し た 半径190 の 円 。 白 。 DrawCircle(240, 240, 190, GetColor(255, 255, 255), TRUE); 21 22 23 // 文 字 盤 の「 12 」 の 文 字 。 文 字 の 大 き さは 52 ピ ク セ ル 。 黒 。 SetFontSize(52); DrawString(210, 48, "12", GetColor(0, 0, 0)); 24 25 26 27 // 秒 針:(240, 240)と(192, 360) を 結 ぶ 直 線 。 DrawLine(240, 240, 192, 360, GetColor(105, 105, 105), 2); 28 29 30 // 短 針 : 三 角 形 ( 塗 り つ ぶ さ な い ) 。 DrawTriangle(240, 220, 340, 240, 240, 265, GetColor(0, 0, 255), FALSE); 31 32 33 // 長 針 : 三 角 形 ( 塗 り つ ぶ す ) 。 DrawTriangle(230, 240, 240, 85, 34 250, 240, GetColor(0, 255, 0), TRUE); 35 36 WaitKey(); DxLib_End(); return 0; 37 38 39 } 図 10: リスト 2 を実行してみた例 7 課題 • 何でも良いので自由に絵を描いて下さい(図 10 のように)。 あまり簡単なものにしないこと。 なお,座標を頭の中ですべて想像しながら描くのはなかなか難しいので,まずは紙など に「設計図」を書いてみるのが良いでしょう。というわけで方眼紙を配布します。 8