SQLの窓

2017年11月25日


C# でDXライブラリを使って簡単なシューティングをクラス化して標準化 / メインループとプレイヤー (1)



まずプロジェクトですが、DXライブラリのダウンロードから、C# 用をダウンロードしてそのまま動作する場合はそれでもいいですが、Visual Studio の 2010 では動かないので普通にプロジェクトを Windows アプリケーションで作成します。

次に、bin の下の実行場所に DxLib.dll と DxLib_x64.dll と DxLibDotNet.dll をコピーして、DxLibDotNet.dll を参照すれば使えるようになります。



以下のソースコードに関しては、player.png が必要ですが、シューティングゲーム用ドット絵フリー素材よりダウンロードして作成しました。


(DxLib.dll と同じ場所に保存します)

こちらはクラス化した C# テンプレートです。プロジェクトをテンプレートで作成したら、DxLib.dll と DxLib_x64.dll と DxLibDotNet.dll と player.png をコピーして DxLibDotNet.dll を参照します


クラス化なしのベタコード

このコードで、自機が左矢印キーと右矢印キーで左右に移動します。
using DxLibDLL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DX_001 {

	static class Program {

		[STAThread]
		static void Main() {

			// ウインドウモードで起動( コメントにするとフルスクリーン )
			DX.ChangeWindowMode(DX.TRUE);

			// スクリーンサイズ
			int screen_w = 800, screen_h = 600;
			DX.SetGraphMode(screen_w, screen_h, 32);

			// DXライブラリの初期化
			if (DX.DxLib_Init() < 0) {
				return;
			}

			// 描画先を裏画面に変更
			DX.SetDrawScreen(DX.DX_SCREEN_BACK);

			// 画像の読み込み
			int player = DX.LoadGraph("player.png");

			// 画像のサイズを取得
			int player_graph_w, player_graph_h;
			DX.GetGraphSize(player, out player_graph_w, out player_graph_h);

			// プレーヤーの初期位置
			int x = screen_w / 2 - player_graph_w / 2, y = screen_h - 70;

			int payer_move_offset = 5;

			// メインループ
			while (DX.ProcessMessage() != -1) {

				// ESC で終了
				if (DX.CheckHitKey(DX.KEY_INPUT_ESCAPE) == 1) {
					break;
				}

				// 右矢印キー
				if (DX.CheckHitKey(DX.KEY_INPUT_RIGHT) == 1) {
					x += payer_move_offset;
					if (x + player_graph_w > screen_w) {
						x = screen_w - player_graph_w;
					}
				}
				// 左矢印キー
				if (DX.CheckHitKey(DX.KEY_INPUT_LEFT) == 1) {
					x -= payer_move_offset;
					if (x < 0) {
						x = 0;
					}
				}
				// 上矢印キー
				if (DX.CheckHitKey(DX.KEY_INPUT_UP) == 1) {
				}
				// 下矢印キー
				if (DX.CheckHitKey(DX.KEY_INPUT_DOWN) == 1) {
				}
				// スペースキー
				if (DX.CheckHitKey(DX.KEY_INPUT_SPACE) == 1) {
				}

				// 画面をクリア
				DX.ClearDrawScreen();

				// プレイヤーを描画
				DX.DrawGraph(x, y, player, DX.TRUE);

				// 裏画面の内容を表画面に反映する
				DX.ScreenFlip();
			}

			// DXライブラリの後始末
			DX.DxLib_End();
		}
	}

}


このままいろいろ機能を実装して行くと、とてもメンテしにくいコードになるので、まずゲームの本体である初期化とメインループをクラス化し、メインループ用の start メソッドの引数の無名処理を呼び出すようにしました。

Game クラスを作成して使用
	static class Program {

		[STAThread]
		static void Main() {

			// メインゲームインスタンス作成
			Game game = new Game(800, 600);

			// 初期化
			game.init();

			// 画像の読み込み
			int player = DX.LoadGraph("player.png");

			// 画像のサイズを取得
			int player_graph_w, player_graph_h;
			DX.GetGraphSize(player, out player_graph_w, out player_graph_h);

			// プレーヤーの初期位置
			int x = game.screen_w / 2 - player_graph_w / 2, y = game.screen_h - 70;

			int payer_move_offset = 5;

			game.start(
				// *******************
				// 主処理
				// *******************
				(int counter) => {

					// 右矢印キー
					if (DX.CheckHitKey(DX.KEY_INPUT_RIGHT) == 1) {
						x += payer_move_offset;
						if (x + player_graph_w > game.screen_w) {
							x = game.screen_w - player_graph_w;
						}
					}

					// 左矢印キー
					if (DX.CheckHitKey(DX.KEY_INPUT_LEFT) == 1) {
						x -= payer_move_offset;
						if (x < 0) {
							x = 0;
						}
					}

				},
				// *******************
				// 描画処理
				// *******************
				() => {

					DX.DrawGraph(x, y, player, DX.TRUE);

				}

			);



		}
	}


Game クラス

public void start(main_action call, draw_action draw) として定義されているので、内側から call と draw を呼び出して呼び出し元のコードを実行させます。

こうする事によって、ループ処理の中をキー処理と描画処理を分けて解りやすく記述できるようになります。

呼び出し元は、ラムダ式で単純なブロックを作成して記述が可能です。
class Game {

	// 外部呼出し用
	public delegate void main_action(int counter);
	public delegate void draw_action();

	// メインループカウント
	private int loopCount = 0;

	// スクリーンサイズ
	public int screen_w;
	public int screen_h;

	// *******************
	// コンストラクタ
	// *******************
	public Game(int w, int h) {
		screen_w = w;
		screen_h = h;
	}

	// *******************
	// 初期化
	// *******************
	public void init() {

		// ウインドウモードで起動( コメントにするとフルスクリーン )
		DX.ChangeWindowMode(DX.TRUE);

		// スクリーンサイズ
		DX.SetGraphMode(screen_w, screen_h, 32);

		// DXライブラリの初期化
		if (DX.DxLib_Init() < 0) {
			return;
		}

		// 描画先を裏画面に変更
		DX.SetDrawScreen(DX.DX_SCREEN_BACK);

	}

	// *******************
	// メインループ開始
	// *******************
	public void start(main_action call, draw_action draw) {


		// メインループ
		while (DX.ProcessMessage() != -1) {

			// ESC で終了
			if (DX.CheckHitKey(DX.KEY_INPUT_ESCAPE) == 1) {
				break;
			}

			// 外部を呼び出し
			call(loopCount);
			loopCount++;
			if (loopCount > 100000) {
				loopCount = 0;
			}

			// 画面をクリア
			DX.ClearDrawScreen();

			// 外部を呼び出し(描画処理用)
			draw();

			// 裏画面の内容を表画面に反映する
			DX.ScreenFlip();

		}

		// DXライブラリの後始末
		DX.DxLib_End();

	}

}


関連する記事

C# でDXライブラリを使って簡単なシューティングをクラス化して標準化 / メインループとプレイヤー (2)


【VS(C#)の最新記事】
posted by lightbox at 2017-11-25 22:07 | VS(C#) | このブログの読者になる | 更新情報をチェックする
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり