講義メモ:ゲーム開発演習

:キーボードの状態を得る、画像の左右移動、簡易アニメーション など

テーマ24 背景画像のスクロール【再掲載】

・背景画像を2枚用意して、1枚目の描画開始位置を少しずつずらし、空いた部分にもう1枚をつながるように描画すれば、
 背景画像のスクロールが可能
・なお、C#のGDI+では描画位置を示す座標を負の数や描画範囲外にできる。これにより、画像の一部を表示することが可能
・画像全体が描画範囲の外になったら、描画対象から外すか、描画位置を変えると良い
・背景画像の縦スクロールの場合、描画開始位置が下端を超えたら0に戻すと良い
・背景画像は2枚になるが、画像オブジェクトは1つで良く、2つの参照変数で扱えば良い

提出フォロー:演習24 背景画像の縦スクロール

・背景画像のつなぎ目のY座標を示す変数backyを0で初期化しておき、タイマーによってインクリメントする
 (背景画像.Heightを超えたら0に戻す)
・背景画像の描画を2回に増やし、(0, backy)からと、(0, backy - 背景画像.Height)から描画する
・タイマーのインターバルは10ミリ秒に変更すると良い
・プレイ画面の背景もシームレスにスクロールしたいので、タイマーのインクリメントはシーンに限らず行うように変更

作成例

//テーマ24 背景画像のスクロール
using System; //C#標準クラス用
using System.Windows.Forms; //Application、Formクラス用
using System.Drawing; //Size、Graphics、Image、Penクラス、Color構造体用
class Program : Form { //Formクラスの派生クラス
    enum mode { TITLE, PLAY, OVER }; //タイトル画面、プレイ画面、ゲームオーバー画面
    mode scene = mode.TITLE; //シーンをタイトル画面とする
    Image backi; //画像ファイル用変数
    Timer t = new Timer(); //タイマーを生成
    int sec = 0; //経過秒数
    int backy = 0; //【追加】背景画像のつなぎ目のY座標
    protected override void OnPaint(PaintEventArgs e) { //描画処理のオーバライド
        //全画面に共通の描画処理
        base.OnPaint(e); //元のメソッドの内容を呼び出す
        e.Graphics.DrawImage(backi, 0, backy); //【変更】背景画像①を描画
        e.Graphics.DrawImage(backi, 0, backy - backi.Height); //【追加】背景画像②を①の直上に描画
        Font fm24 = new Font("メイリオ", 24, FontStyle.Bold); //フォントを生成
        Brush bcyan = new SolidBrush(Color.Cyan); //シアン色のソリッドブラシを生成
        switch (scene) { //シーンにより分岐
        case mode.TITLE: //タイトル画面?
            e.Graphics.DrawString("GAME", fm24, bcyan, 250, 200); //文字列を描画
            e.Graphics.DrawString("Hit Enter Key", fm24, bcyan, 200, 400); //文字列を描画
            break;
        case mode.PLAY: //プレイ画面?
            e.Graphics.DrawString("START", fm24, bcyan, 250, 200); //文字列を描画
            e.Graphics.DrawString("" + sec , fm24, bcyan, 0, 0); //【移動】経過秒数を描画
            break;
        }
    }
    public Program() { //コンストラクタ
        DoubleBuffered = true; //ダブルバッファリングを行う
        try { //例外処理対象
            backi = Image.FromFile("backb2.bmp"); //背景画像ファイルを読み込む
        } catch (Exception e) { //例外処理内容
            MessageBox.Show(e.ToString()); //内容をメッセージボックスに表示
        }
        KeyDown += new KeyEventHandler(OnKeyDown); //キー押し下げ時のメソッドを登録
        t.Tick += new EventHandler(OnTimer); //タイマーイベント時のメソッドを登録
        t.Interval = 10; //【変更】タイマー動作間隔を10ミリ秒指定
        t.Start(); //【移動】タイマー開始
    }
    void OnKeyDown(object o, KeyEventArgs e){ //キー押し下げ時に呼ばれるメソッド
        if (e.KeyCode.ToString() == "Escape") { //押されたキーのコードを文字列化したらEscape?
            Close(); //フォームアプリケーションを終了
        }
        if (e.KeyCode.ToString() == "Return") { //押されたキーのコードを文字列化したらReturn?
            scene = mode.PLAY; //シーンをプレイ画面とする
            sec = 0; //経過秒数をクリア
        }
        Invalidate(); //画面再描画を依頼
    }
    void OnTimer(object o, EventArgs e){ //タイマーイベント時に呼ばれるメソッド
        backy = (backy < backi.Height) ? backy + 1 : 0; //【追加】背景画像のつなぎ目のY座標をインクリメント
        sec++; //経過秒数インクリメント
        Invalidate(); //画面再描画を依頼
    }
    static void Main() { //実行用メソッド(publicはなくてOK)
        Program f = new Program(); //自クラスのインスタンスを生成
        f.Text = "Game"; //Form名を設定
        f.StartPosition = FormStartPosition.Manual; //「手動設定」を設定
        Point p = new Point(300,0); //X座標とY座標のPointインスタンスを生成
        f.Location = p; //インスタンスプロパティで初期位置を設定
        f.FormBorderStyle = FormBorderStyle.FixedSingle; //フォームサイズの固定化
        f.ControlBox = false; //コントールボックスの非表示
        f.ClientSize = new Size(640, 480); //クライアントサイズの幅と高さを指定
        Application.Run(f); //生成済のインスタンスを実行
    }
}

テーマ25 キーボードの状態を得る

・キー入力イベントを用いる手法は「キーを押している間、〇〇する」には向かない
・代わりにタイマーイベントを用いてキーボードの状態を得る処理を呼び出してもらうと良い
・これを実現するには、WindowsAPIを提供するDLL(動的リンクライブラリ)の一つである「user32.dll」を直接インポートする
・インポートの書式: [System.Runtime.InteropServices.DllImport("user32.dll")] ※セミコロン不要
・外部定義指定の書式: private static extern short GetKeyState(int nVirtKey);
 ※インポートと外部定義指定はクラス定義の先頭で行うこと
・これで、GetKeyStateメソッドが利用可能になり、引数としてKeys列挙子をint型にキャストして与えると、そのキーが押されていれば
 負の数が返される
・Keys列挙型については ⇒ https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.keys

演習25 キーボードの状態を得る

・タイマーで変数secを無条件にインクリメントするのではなく、上矢印キーが押されていたらインクリメントするようにしよう
・なお、上矢印キーのKeys列挙子は Keys.Up

提出:演習25 キーボードの状態を得る

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です