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

:背景画面のスクロール、キーボードの状態を知る など

テーマ27 背景画像のスクロール

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

演習23 背景画像の縦スクロール

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

作成例

//演習23 背景画像の縦スクロール
using System; //フォームアプリケーションに必須
using System.Windows.Forms; //フォームアプリケーションに必須
using System.Drawing; //Image用
class Program : Form { //Formクラスを継承
    Image backb = Image.FromFile("backb.bmp"); //背景画像の読込
    Image enemy = Image.FromFile("enemy.gif"); //アイテム画像の読込
    Image burn = Image.FromFile("burn.gif"); //効果用画像の読込
    Pen mypen = new Pen(Color.Red, 2); //ペンを生成(初期値は赤、2)
    Brush bred = new SolidBrush(Color.FromArgb(63, 255, 0, 0)); //ブラシを生成(赤の透明色)
    Brush byel = new SolidBrush(Color.Yellow); //ブラシを生成(黄色)
    Font f20 = new Font("メイリオ", 20, FontStyle.Bold); //フォントを生成(メイリオ20P太字)
    Font f80 = new Font("メイリオ", 80, FontStyle.Bold); //フォントを生成(メイリオ80P太字)
    int gamemode = 0; //0:スタート画面、1:プレイ画面
    int score = 0; //スコア
    int backy = 0; //【追加】背景画像のつなぎ目のY座標
    Timer timer = new Timer(); //タイマーを生成
    void DrawCircle(PaintEventArgs e, Pen p, int x, int y, int r) { //ペン、中心座標、半径を指定して円を描画
        e.Graphics.DrawEllipse(p, x - r, y - r, 2 * r, 2 * r); //円の描画を呼ぶ
    }
    protected override void OnPaint(PaintEventArgs e) { //Formのメソッドをオーバーライド
        base.OnPaint(e); //まず、Formクラスにおけるメソッドの内容(基本再描画処理)を実行
        e.Graphics.DrawImage(backb, 0, backy); //【変更】背景画像を(0,つなぎ目)から描画
        e.Graphics.DrawImage(backb, 0, backy - backb.Height); //【追加】背景画像をその上に描画
        if (gamemode == 0) { //スタート画面
            e.Graphics.DrawString("GAME1", f80, byel, 100, 100); //タイトルの描画
            e.Graphics.DrawString("Hit Enter to Start", f20, byel, 200, 300); //メッセージの描画
        } else if (gamemode == 1) { //プレイ画面
            e.Graphics.FillRectangle(bred, 78, 411, 485, 64); //判定エリアを透明赤で塗りつぶす
            e.Graphics.DrawRectangle(mypen, 78, 411, 485, 64); //判定エリアの描画
            string s = String.Format("SCORE:{0:000,000}", score); //スコア文字列を編集
            e.Graphics.DrawString(s, f20, byel, 400, 10); //スコア文字列の描画
        }
    }
    void OnKeyDown(object o, KeyEventArgs e) { //キーボードが押された時に呼ばれるメソッド
        if(e.KeyCode.ToString() == "Escape") { //Escキーが押されたら
            Close(); //フォームアプリケーション終了
        }
        if(gamemode == 0 && e.KeyCode.ToString() == "Return") { //スタート画面でEnterキーが押されたら
            gamemode = 1; //プレイ画面に切り替える
            timer.Start(); //タイマー開始
            Invalidate(); //画面再描画を依頼する
        }
    }
    void Play(object o, EventArgs e) { //タイマーから呼ばれるメソッド
        score++; //スコアアップ
        backy = (backy < backb.Height) ? backy + 1 : 0; //【追加】背景画像のつなぎ目を下げる
        Invalidate(); //画面再描画を依頼する
    }
    Program() { //コンストラクタ
        DoubleBuffered = true; //ダブルバッファリングの導入
        KeyDown += new KeyEventHandler(OnKeyDown); //キーボードが押された時に呼ばれるメソッドを登録
        timer.Tick += new EventHandler(Play); //タイマーから呼ばれるメソッドを登録
        timer.Interval = 10; //【変更】タイマーの間隔
    }
    static void Main() { //publicの指定は任意
        Program p = new Program(); //継承したフォームのインスタンスを生成
        p.Width = 660; //インスタンスのWidthプロパティに幅を代入
        p.Height = 520; //インスタンスのHeightプロパティに高さを代入
        p.Text = "Game"; //インスタンスのTextプロパティにフォーム名を代入
        p.ControlBox = false; //ControlBoxを非表示にする
        p.FormBorderStyle = FormBorderStyle.Fixed3D; //フォームサイズ変更を禁止
        Application.Run(p); //インスタンスを画面に出す
    }
}

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

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

演習24 上矢印キーが押されていたらスコアアップ

・上矢印キーのKey列挙子はKeys.Up
・これを用いて、Playメソッド内で、上矢印キーが押されているかチェックし、押されていたらスコアをインクリメントしよう

提出:演習23または24(未完成でもOK)

コメントを残す

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