ゲーム実装で身に付くプログラミング 6

タイトル画面を表示する

タイトル画面を表示する

デバッグ時に書き出される実行ファイル(bin¥debug¥net10.0-windows¥colorCSForms.exe)からの相対パスで「Title.png」画像を読み込みます。「title」メソッドでゲーム状態をタイトル画面にし、マウスが押されたら「onClick2Start」関数を呼び出します。この関数ではマウスが押された時のトリガーを解除し、「init」関数でゲーム状態をメインループにします。

図2のようにタイトル画面では中央にタイトル画像を表示し、画面をマウスで押したら画像を消します。

図2:タイトル画面を表示

・サンプルコード「Forms1.cs」ファイル

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace colorCSForms
{
    public partial class Form1 : Form
    {
        Image[] img = new Image[4];
        enum GAME_STATE {TITLE,MAIN_LOOP,GAME_OVER,STAGE_CLEAR};
        GAME_STATE gameState;

        public Form1()
        {
            InitializeComponent();
            this.DoubleBuffered = true; // チラつき防止
            // 画像読み込み(パスは実行ファイルからの相対パス)
            img[3] = Image.FromFile(@"../../../images\Title.png");
            title();
        }

        void title()
        {
            gameState = GAME_STATE.TITLE;
            this.MouseDown += onClick2Start;
        }

        void onClick2Start(object sender, MouseEventArgs e)
        {
            this.MouseDown -= onClick2Start;
            init();
        }

        void init()
        {
            gameState = GAME_STATE.MAIN_LOOP;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            switch (gameState)
            {
                case GAME_STATE.TITLE:
                    int x = this.ClientSize.Width/2 - img[3].Width/4;
                    int y = this.ClientSize.Height/2 - img[3].Height/4;
                    e.Graphics.DrawImage(img[3], x, y);
                    break;
            }
        }
    }
}

【サンプルコードの解説】
「Form1」コンストラクタでタイトル画像を読み込みます。
「title」メソッドでゲーム状態を「GAME_STATE.TITLE」にし、マウスが押されたら「onClick2Start」メソッドをトリガーします。メソッド名はイニシャルが大文字ならpublic、小文字ならprivateです。
onClick2Startメソッドでマウスが押された時のトリガーを解除します。
「init」メソッドでゲーム状態を「GAME_STATE.MAIN_LOOP」にします。
「OnPaint」メソッドでタイトル画面で画像を表示します。

色ブロックを表示する

「Sprite.cs」ファイルをcolorCSForms内に「Add」→「New Item」メニューで新規作成します。タイトル画面でマウスを押したらゲーム画面に遷移し、色ブロックが複数表示されて移動し、画面外に出たら削除されましたね(図3)。

図3:色ブロックを表示

・サンプルコード「Sprite.cs」ファイル

using System.Reflection.Metadata;

namespace colorCSForms
{
    public class Sprite
    {
        public float X, Y;
        public float VX, VY;
        public Image Img;
        public int Col;
        Random rand = new Random();
 
        public Sprite(Size clientSize,Image[] img,int col)
        {
            X = rand.Next(0, clientSize.Width);
            Y = rand.Next(0, clientSize.Height);
            VX = rand.Next(-4, 4);
            VY = rand.Next(-4, 4);
            Col = col;
            Img = img[col];
        }

        public bool Update(Size clientSize)
        {
            X += VX;
            Y += VY;
            // 画面外なら削除
            if (X > clientSize.Width ||
                Y > clientSize.Height ||
                X + Img.Width < 0 ||
                Y + Img.Height < 0) return true;
            return false;
        }
    }
}

【サンプルコードの解説】
「Sprite」クラスで色ブロック1個ごとの座標(X,Y)プロパティ、移動量(VX,VY)プロパティ、色「Col」プロパティ、画像データ「Img」プロパティ、乱数「rand」プロパティを宣言します。イニシャルが大文字から始まるプロパティはpublicで、小文字から始まるプロパティはprivateです。
Spriteコンストラクタでランダムな座標と移動量とブロックの色と画像をセットします。
「Update」メソッドで色ブロックを移動し、画面外に出たらtrueを戻り値で返します。

・サンプルコード「Forms1.cs」ファイル

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace colorCSForms
{
    public partial class Form1 : Form
    {
        System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
        List<Sprite> sprites = new List<Sprite>();
        Random rand = new Random();
        Image[] img = new Image[4];
        int stage = 2;
        enum GAME_STATE {TITLE,MAIN_LOOP,GAME_OVER,STAGE_CLEAR};
        GAME_STATE gameState;

        public Form1()
        {
            InitializeComponent();
            this.DoubleBuffered = true; // チラつき防止
            // 画像読み込み(パスは実行ファイルからの相対パス)
            img[0] = Image.FromFile(@"../../../images\0.png");
            img[1] = Image.FromFile(@"../../../images\1.png");
            img[2] = Image.FromFile(@"../../../images\2.png");
            img[3] = Image.FromFile(@"../../../images\Title.png");
            title();
        }

        void title()
        {
            gameState = GAME_STATE.TITLE;
            timer.Tick -= update;
            timer.Stop();
            this.MouseDown -= onMouseDown;
            this.MouseDown += onClick2Start;
        }

        void onClick2Start(object sender, MouseEventArgs e)
        {
            this.MouseDown -= onClick2Start;
            init();
            // タイマー(10fps)
            timer.Interval = 100;
            timer.Tick += update;
            timer.Start();
            this.MouseDown += onMouseDown;
        }

        void init()
        {
            gameState = GAME_STATE.MAIN_LOOP;
            sprites.Clear();
            // 初期生成
            for (int i = 0; i < stage*3; i++) sprites.Add(new Sprite(this.ClientSize,img,i%3));
        }

        void update(object sender, EventArgs e)
        {
            for (int i = sprites.Count - 1; i >= 0; i--) if ( sprites[i].Update(this.ClientSize) ) sprites.RemoveAt(i);
            this.Invalidate(); // 再描画
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            switch (gameState)
            {
                case GAME_STATE.TITLE:
                    int x = this.ClientSize.Width/2 - img[3].Width/4;
                    int y = this.ClientSize.Height/2 - img[3].Height/4;
                    e.Graphics.DrawImage(img[3], x, y);
                    break;
                case GAME_STATE.MAIN_LOOP:
                    foreach (var s in sprites) e.Graphics.DrawImage(s.Img, s.X, s.Y);
                    break;
            }
        }

        void onMouseDown(object sender, MouseEventArgs e)
        {
		}
    }
}

【サンプルコードの解説】
Form1クラスで「sprites」プロパティをSpriteクラスのリストを宣言します。
img[0]~img[2]に赤緑青の色ブロックの画像を読み込んでインスタンスを代入します。
onClick2StartメソッドでTimerのタイマーを使って100ミリ秒ごと(10FPS)にupdateメソッドを呼び出します。titleメソッドではそれらを止め、マウスが押された時の処理のトリガーを付け替えます。
「init」メソッドで色ブロックをSpriteクラスのインスタンスでstageの3倍(3色ごと)追加します。
updateメソッドで色ブロックを移動し、画面外で削除して再描画します。
OnPaintメソッドでゲーム状態がメインループ時に色ブロックを表示します。

【コラム】せどりビジネス

安く中古品を買って高く転売するせどりビジネスがありますよね。それで考えたのが「せどり紹介システム」。読書管理サイトの読者に高く売れる古本があれば情報提供します。持ち物管理サイトの持ち主に高く売れる中古品があれば情報提供します。そうして売れたら情報提供料として売値の5%を貰えたらいいです。

この記事をシェアしてください

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored