アマゾンバナーリンク

ゲーム終了判定処理と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();
        }
    }
}

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