まずプロジェクトですが、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#)の最新記事】
- Replit : cs-list
- C# : Excel の新しいブックのデフォルトのシートのセルに直接値をセットして、オートフィルを Range オブジェクトから実行する
- C#( Form ) : ウインドウ枠の無い吹き出しの作成
- C# のタプル( Visual Studio 2017 でテスト )
- C# : インターネット上の JSON ファイルのフォーマットを クラスとして定義して1行でオブジェクト化して使用する
- C# の文法的文字列処理
- C# : System.Data.Odbc によるデータベースのテーブルからのデータ取得処理( サンプルの SQL は MySQL 用です )
- C# : Excel を データベースとして DataGridView に読み込む
- C# : dynamic 型 による Excel へのアクセス
- C# : フォームを表示せずに、通知領域にアイコンを表示させる常駐プログラム
- Microsoft Access に対してSQLを入力してその結果を DataGridView に表示する最も簡単なコード
- C# : System.Data.Odbc データ取得(SELECT)処理( MySQL ) : ※ using 無し( Dispose 実行 )
- C# : SQL 文を外部テキストにして、String.Format でデータ部分を置き換えて利用する
- C# コンソールアプリを AN HTTPD で実行
- C# : SQLServer( SQLExpress ) の SMO を使用してテーブルの CREATE TABLE 文 を取得する
- C# : DataGridView に TKMP.DLL の IMAP(POP3) で受信したメールを非同期に表示する( 添付ファイルも取得 )
- C# : TKMP.DLLを使った、メール送信テンプレート
- C# と VB.net : TKMP.DLL を使って IMAP でメール本文の一覧を取得する( コンソール )
- C# でDataTable と DataSource を使用して、DataGridView にデータを表示するテンプレート( 行をダブルクリックしてダイアログを表示して行データを処理 )
- (C#) / VS2010 または VS2012 : TKMP.DLL(3.1.2 または 3.1.8)を使った、『さくらインターネット』用メール送信テンプレート