プログラム3 画像表示

さて、ゲームのキモは、なんと言ってもグラフィックです。
文字だけのAVGでも、文字という立派な絵を表示しています。
まぁ、グラフィックを一切表示しないAVG(?)が昔、某ゲーム機で発売されましたが、世間
的にはほぼネタとして受け入れられていたように思えます。
少なくとも、私は1000円で売るっていたのを見て、ネタで買いました。
それはともかくとして、音ゲーといわれる音がメインのゲームでさえ、グラフィックが無
ければお話になりません。
と、いうわけで、まずは絵を表示させてみることにしましょう。

さて、絵を表示する、といっても幾つか方法があります。
一つは、PictureBoxを使う方法です。
とても簡単ですが、ゲームには向きません。
なぜなら、ゲームは幾つかの絵を重ね合わせをしたり、画面効果の為に直接画像データを
操作する必要があるからです。
PictureBoxでもやろうと思えば出来るのでしょうが、パフォーマンスの問題が残ります。
もう一つは、DirectGraphicsを使う方法です。
高速に描画出来、ゲームに特化されているため、とても使いやすいのですが、使う為には
DirectX SDKの導入(無料です)をしなければならず、導入しても使う為には多少の知識が
必要になってきます(といっても、それほど難解というわけではありません)
本勉強会でも使いたいのですが、DirectGraphicsの説明まで行うと、Windowsアプリケー
ションを作ろうという本勉強会の趣旨から大きく外れてしまう為、今回は見送り。
他にも色々あるのですが、ここはWindowsXP標準のAPIであるGDI+を使うことにしましょう。

GDI+というのは「Graphics Device Interface」の略です。
+が付いているのは、旧WindowsのAPIであるGDIの後継であるということのようです。
GDI+は、System.Drawing名前空間にまとめられています。
例えば、描画サーフェイスであるGraphicsクラスや、グラフィックデータ用のBitmapクラ
ス等です。

GDI+を使用してグラフィックを扱うには、Graphicsオブジェクトを作成する必要がありま
す。
グラフィックオブジェクトを作成するには大きく分けて3つの方法があります。
1)PaintイベントのパラメータであるPaintEventArgsから取得する方法です。
この方法がコントロールやフォームの描画を行う際最も一般的な方法です。
2)コントロールやフォームのGreateGraphicsメソッドを使用する方法です。
既に存在するコントロールやフォームに対して描画するときに使います。
3)Imageクラスを継承するオブジェクトからGraphicsオブジェクトを取得する方法で
す。PictureBox等で読み込んでいる画像をフォームに反映といった使い方をするときに
便利です。
本勉強会では一般的な使い方であるPaintイベントを用いることにします。

まず、例によって新規にプロジェクトを作成し、フォームのデザイン画面で、Paintイベ
ントを作成してください。
名前をつけてもかまいませんし、Wクリックして自動生成してもかまいません。
本来ならば、直線を引いたりすることから始めるのでしょうが、AVGにはそんな機能は必
要無いので、フォームに文字を表示してみることにします。
文字を表示するには、Font情報、Brush情報、Format情報が必要です。
フォントはフォームのフォントを使うとして、Brush情報とFormat情報は作成しなければ
なりません。
Brushというのは、画筆とかいった意味で、文字や線などの描画する色や塗りつぶしの方
法などを決定します。
Formatはテキストのレイアウト(右から左に書くとか)を決定します。

       private void Form1_Paint(object sender, PaintEventArgs e)
       {
           System.Drawing.SolidBrush drawBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
           System.Drawing.StringFormat drawFormat = new System.Drawing.StringFormat();
           e.Graphics.DrawString("Hellow World", this.Font, drawBrush, 0, 0, drawFormat);
           drawFormat.Dispose();
           drawBrush.Dispose();
       }

まず、単一色のブラシであるSolidBrushオブジェクトを作成しています。
Brush等のカラー指定は、System.Drawing名前空間にあるColor構造体を使用します。
ここでは名前を指定していますが、Argbメソッドを使うことで、RGBとアルファ値を直で
指定することも出来ます。
次に、フォーマットのオブジェクトを作成していますが、特に指定はしません。
それぞれ設定が終わったなら、DrawStringで文字を表示します。0,0は位置なので、ここ
を変えると好きな位置に表示できるので試してみましょう。
最後に、使用したオブジェクトをDisposeメソッドを使い開放します。

さて、文字を表示したなら次は絵です(?)
先ほども説明したとおり、よく見る画像フォーマットは殆ど対応されているので、表示
するだけなら特に難しくは無いのですけどね。
サンプル中の0001.bmpは、自分が表示したい画像名に変更してください。
画像なんて持ってないよ、って人は、ペイントかなんかで描いてみるなり、どこからか
落としてくるなりしましょう。

       private void Form1_Paint(object sender, PaintEventArgs e)
       {
           Bitmap bmp = new Bitmap("0001.bmp");
           e.Graphics.DrawImage(bmp, 0, 0);
           bmp.Dispose();
       }

ほらね、簡単でしょう?(Byボブ)
始めにビットマップオブジェクトを作成しています。コンストラクタで画像名を指定す
れば、読み込んでくれます。
次に、DrawImageで、先ほど読み込んだビットマップを描画します。0,0は例によって位
置。
eっていうのは、ペイントイベントのパラメータです。
e.Graphicsで、対象コントロールのGraphicsを参照できるようになっています。
つまり、フォームに画像が表示されることになります。
お約束、使い終わったら開放、ということでビットマップオブジェクトを開放します。

画像を表示できたら、次は合成です。
合成というのは、絵の上に絵を重ね合わせることです。
このとき、特定の色を透明色に設定して重ね合わせることにより、アニメのセルのよう
なことを行えます。
スプライト、なんて呼び方をすることもあります。
昔はは抜き型を作って、andして、orをする、などということをやっていたのですが、
勿論そんな面倒なことはしなくてもよく、BitmapクラスのMakeTranparentメソッドで、
透明色を指定してやれば出来てしまいます。
良い時代になったものです。
ペイントかなにかを開き、背景が白のなにかを描いてみましょう(絵の中に白は使えま
せん。R=254,G=255,B=255といった、限りなく白に近い色にしましょう)
面倒なら丸とか四角でかまいません。
それを保存して先ほどの画像に重ね合わせてみましょう。

       private void Form1_Paint(object sender, PaintEventArgs e)
       {
           Bitmap bmp1 = new Bitmap("0001.bmp");
           Bitmap bmp2 = new Bitmap("0002.bmp");

           e.Graphics.DrawImage(bmp1, 0 , 0 );

           bmp2.MakeTransparent(System.Drawing.Color.White);
           e.Graphics.DrawImage(bmp2, 0 , 0 ); 

           bmp1.Dispose();
           bmp2.Dispose();
       }


白で塗った部分が透明になって重ねあわされたはずです。
このサンプルでは単純に、ビットマップオブジェクトの透過色を設定しているだけです。
MakeTransparentメソッドは、パラメータに色を指定します。
渡すのはColor構造体なので、文字を表示したときと同様に、RGBの指定も出来ます。

さて、絵を表示するようになって、それらしくなってきたような感じがしませんか。

実はこのサンプル、あんまり良くなくて、Paintイベントは何度も呼ばれる為、呼ばれる
度に画像データを読み出してしまいます。
まぁ、キャッシュされているのでディスクから読み出すことは無いと思いますが。
次回はそのあたりを解消して、文字を表示、紙芝居っぽいのを作ってみたいと思います。
最終更新:2007年11月22日 12:44
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。