アマゾンバナーリンク

ディスプレイ広告

スポンサーリンク

ゲーム終了判定処理とDXライブラリで描画処理

2019年12月25日

描画する前の準備

プレイヤーと敵キャラの画像を設定して、 DrawBoxで描画してた部分を画像に差し替えましょう。
imageフォルダをrepos/プロジェクト名/bin/Debugとrepos/プロジェクト名/bin/Releseにコピーしましょう。 素材をダウンロードする。

プログラムを書き換える

CGameMainクラス

そして、CMainGame.csを以下の様に書き換えます。
画像を描画するには、LoadGraphで読み込んだグラフィックハンドルをDrawGraphで使用します。に関してはをDXライブラリのリファレンスを参照してください。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DxLibDLL;
using System.Windows.Forms;
namespace DxLibGame
{
public static class CMainGame
{
public const int MIN_X = 0;
public const int MAX_X = 8;
public const int MIN_Y = 0;
public const int MAX_Y = 8;
public static CPlayer Player;
public static CEnemy[] Enemy;
private static int State = 0;
private static int[] MapGraph = new int[3];
private static int[] Map = new int[]
{
1,1,1,0,0,1,1,1,
1,2,2,1,0,2,2,2,
1,2,0,0,0,2,0,1,
1,2,1,0,0,0,0,1,
1,2,2,2,0,0,0,1,
1,1,0,2,0,0,0,1,
1,0,0,2,0,0,0,1,
1,1,1,1,0,1,1,1
};
private static void DrawMap()
{
for(int i = 0; i < Map.Length; ++i)
{
DX.DrawGraph(i % MAX_X * 32,i/ MAX_Y * 32, MapGraph[Map[i]], 1);
}
}
public static void Initialize()
{
for(int i = 0; i < MapGraph.Length; ++i)
{
MapGraph[i] = DX.LoadGraph($"image/{i}.jpg");
}
MapGraph[1] = DX.LoadGraph("image/1.jpg");
Player = new CPlayer(x: 4, y: 7, hp: 10, image_name:"image/fighter.png");
Enemy = new CEnemy[] { new CEnemy(x: DX.GetRand(MAX_X), y: DX.GetRand(MAX_Y), hp: 1, image_name:"image/slime0.png"), 
new CEnemy(x: DX.GetRand(MAX_X), y: DX.GetRand(MAX_Y), hp: 1, image_name:"image/slime1.png")
,new CEnemy(x: DX.GetRand(MAX_X), y: DX.GetRand(MAX_Y), hp: 1, image_name:"image/slime2.png")
,new CEnemy(x: DX.GetRand(MAX_X), y: DX.GetRand(MAX_Y), hp: 1, image_name:"image/dragon.png")};
}
private static void MoveTask(CMover[] mover)
{
for (int i = 0; i < mover.Length; ++i)
{
if (!mover[i].Move())
{
mover[i].Show = false;
}
}
}
private static void DrawTask(CMover[] mover)
{
for (int i = 0; i < mover.Length; ++i)
{
mover[i].Draw();
}
}
public static void Move()
{
// ゲーム中
if(State == 0)
{
Player.Move();
MoveTask(Enemy);
int cnt = 0;
for (int i = 0; i < Enemy.Length; ++i)
{
if (Enemy[i].Show == false)
{
++cnt;
}
}
// 敵キャラ生存チェック
if (cnt == Enemy.Length)
{
MessageBox.Show("クリア");
State = 1;
}
}
else // ゲーム終了時
{
}
}
public static void Draw()
{
// ゲーム中
if (State == 0)
{
DrawMap();
Player.Draw();
DrawTask(Enemy);
}
else // ゲーム終了時
{
}
}
}
}

CMoverクラス

キャラの画像の読み込みは、基底クラスのCMoverでLoadGraphを使って読み込みます。
インスタンス化する先(MainGame.cs)でimage_nameを指定します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DxLibDLL;
namespace DxLibGame
{
public class CMover
{
public int X { get; set; }
public int Y { get; set; }
public int HP { get; set; }
public int ImageHandle { get; set; }
public bool Show { get; set; }
public CMover(int x, int y, int hp, string image_name)
{
X = x;
Y = y;
HP = hp;
Show = true;
ImageHandle = DX.LoadGraph(image_name);
if(ImageHandle == -1)
{
int a = 0;
}
}
public bool Hit(CMover mover)
{
if (X == mover.X && Y == mover.Y)
{
return true;
}
return false;
}
public virtual bool Move()
{
return true;
}
public virtual void Draw()
{
}
}
}

CPlayerクラス

プレイヤーの変更部分はDrawのみです。イメージハンドルを受け取ったら基底クラスにimage_nameを渡します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DxLibDLL;
namespace DxLibGame
{
public class CPlayer : CMover
{
int[] InputCnt = new int[] { 0, 0, 0, 0 };
public CPlayer(int x, int y, int hp, string image_name) : base(x, y, hp, image_name)
{
}
enum EInputState
{
KEY_INPUT_UP,
KEY_INPUT_DOWN,
KEY_INPUT_LEFT,
KEY_INPUT_RIGHT
}
;
void CheckHitKey(int key, int input_state)
{
if (DX.CheckHitKey(key) == 1)
{
InputCnt[input_state]++;
}
else
{
InputCnt[input_state] = 0;
}
}
public override bool Move()
{
CheckHitKey(DX.KEY_INPUT_UP, (int)EInputState.KEY_INPUT_UP); // 上キーを押したら
CheckHitKey(DX.KEY_INPUT_DOWN, (int)EInputState.KEY_INPUT_DOWN); // 下キーを押したら
CheckHitKey(DX.KEY_INPUT_LEFT, (int)EInputState.KEY_INPUT_LEFT); // 左を押したら
CheckHitKey(DX.KEY_INPUT_RIGHT, (int)EInputState.KEY_INPUT_RIGHT); // 右を押したら
// 上へ移動する
if(InputCnt[(int)EInputState.KEY_INPUT_UP] == 1)
{
--Y;
}
// 下へ移動する
if (InputCnt[(int)EInputState.KEY_INPUT_DOWN] == 1)
{
++Y;
}
// 左へ移動する
if (InputCnt[(int)EInputState.KEY_INPUT_LEFT] == 1)
{
--X;
}
// 右へ移動する
if (InputCnt[(int)EInputState.KEY_INPUT_RIGHT] == 1)
{
++X;
}
// 左へはみ出ないように調整
if (X < CMainGame.MIN_X)
{
X = CMainGame.MIN_X;
}
// 右へはみ出ないように調整
if (CMainGame.MAX_X-1 < X)
{
X = CMainGame.MAX_X-1;
}
// 上へはみ出ないように調整
if (Y < CMainGame.MIN_Y)
{
Y = CMainGame.MIN_Y;
}
// 下へはみ出ないように調整
if (CMainGame.MAX_Y-1 < Y)
{
Y = CMainGame.MAX_Y-1;
}
// プレイヤーに当たったらHPを減らす
for (int i = 0; i < CMainGame.Enemy.Length; ++i)
{
if (Hit(CMainGame.Enemy[i]))
{
--HP;
}
}
if(HP <= 0)
{
return false;
}
return true;
}
public override void Draw()
{
DX.DrawGraph(X * 32, Y * 32, ImageHandle, 1);
}
}
}

CEnemyクラス

敵クラスも同じく描画を書き換えます

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DxLibDLL;
using System.Diagnostics;
namespace DxLibGame
{
public class CEnemy : CMover
{
public CEnemy(int x, int y, int hp, string image_name) : base(x, y, hp, image_name)
{
X = x;
Y = y;
HP = hp;
_Stopwatch.Start();
}
Stopwatch _Stopwatch = new Stopwatch();
public override bool Move()
{
if (!Show)
{
return false;
}
if (500 < _Stopwatch.ElapsedMilliseconds)
{
X += DX.GetRand(2)-1;
Y += DX.GetRand(2)-1;
// 左へはみ出ないように調整
if (X < CMainGame.MIN_X)
{
X = CMainGame.MIN_X;
}
// 右へはみ出ないように調整
if (CMainGame.MAX_X-1 < X)
{
X = CMainGame.MAX_X-1;
}
// 上へはみ出ないように調整
if (Y < CMainGame.MIN_Y)
{
Y = CMainGame.MIN_Y;
}
// 下へはみ出ないように調整
if (CMainGame.MAX_Y-1 < Y)
{
Y = CMainGame.MAX_Y-1;
}
_Stopwatch.Restart();
}
if(Hit(CMainGame.Player))
{
--HP;
}
if (HP <= 0)
{
return false;
}
return true;
}
public override void Draw()
{
if (!Show) return;
DX.DrawGraph(X * 32, Y * 32, ImageHandle, 1);
}
}
}

マップのサイズを変更したので、Form1.csもClientSizeを変更します。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DxLibDLL;
namespace DxLibGame
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// ウィンドウが生成された時に1度だけ呼ばれる
private void Form1_Load(object sender, EventArgs e)
{
ClientSize = new Size(32*8, 32*8);
DX.SetUserWindow(this.Handle); //DxLibの親ウインドウをこのフォームウインドウにセット
DX.DxLib_Init();
// 描画先を裏画面に変更
DX.SetDrawScreen(DX.DX_SCREEN_BACK);
CMainGame.Initialize();
}
//ループする関数
public void MainLoop()
{
// 画面をクリア
DX.ClearDrawScreen();
CMainGame.Move();
CMainGame.Draw();
// 裏画面の内容を表画面に反映する
DX.ScreenFlip();
}
// ウィンドウが閉じた時に1度だけ呼ばれる
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
DX.DxLib_End();
}
}
}

以上でキャラ描画と終了までの処理が追加されました。次回はエンディングを追加します。