プログラミングを春休みの自由研究にしてみる 10、11、12日目

六花です。
https://komochiduki.net/ikupro/2020/03/11/263/の続き、10、11、12日目です。

シリーズリスト :
1日目 : https://komochiduki.net/ikupro/2020/03/01/234/
2日目 : https://komochiduki.net/ikupro/2020/03/03/238/
3日目 : https://komochiduki.net/ikupro/2020/03/03/245/
4日目 : https://komochiduki.net/ikupro/2020/03/04/250/
5日目 : https://komochiduki.net/ikupro/2020/03/04/253/
6日目 : https://komochiduki.net/ikupro/2020/03/09/259/
7、8、9日目 : https://komochiduki.net/ikupro/2020/03/11/263/
10、11、12日目 : https://komochiduki.net/ikupro/2020/03/12/268/
13日目[本編1日目] : https://komochiduki.net/ikupro/2020/03/13/286/
14日目[本編2日目] : https://komochiduki.net/ikupro/2020/03/15/289/
15-21日目[本編3-9日目] : https://komochiduki.net/ikupro/2020/03/21/302/

そろそろ授業から実習に移りたいと思うようになってきました。
制作が進んだ結果、プログラミングに必要なことというよりはアルゴリズムを考えるようになってきて、「これ自分が考えるより娘に考えさせた方がいいんじゃないか」と感じるようになってきたためです。
そこで、この辺りからは少しずつ機能を追加して娘のモチベーションを高めながら、タイピング練習の量を増やしてコーディングの準備を始めました。

■10日目
 敵キャラについての構造体を定義しました。
 中身はマスくん用の構造体とほぼ同じなのですが、娘にとってわかりやすいように今は別個に作りました。
 敵の構造体を作った結果として、娘の描いたこぐまを表示することができるように。
 ここ数日小難しいことばかりやっていた娘としては、ゲームとしての進展を確認出来て大喜びでした。
 最後に判定を□で表示して、極端なバグがないことを確認しました。

■11日目
 10日目にわざと分けていたs_マス君・s_敵という二つの似通った構造体をs_キャラクタに統合しました。
 この作業の、構造体定義のところは娘に任せてみました。
 とりあえずよくわかっていないものの、初めてソースコードを書いたことになります。
 そのほかの整合性は私が取りましたが、その際についでに敵キャラに重力を適用したので、娘は「小熊さんが地面に立ってるー!」と大喜びでした。(それまでは宙に浮いていました)

■12日目
 左右に動いたときに振り向くための処理を実装、そのために画像を調整。
 一応いつ最終回になってもいいようにファンクションキーからクレジットを呼び出せるように。
 ドリルを追加し、ドリルを飛ばせるように(判定はなし)
 この時点で、全部説明してから作らせるより、ここまでの部分を自分で作れるようになれば最後まで作れるだろうなぁと強く思いました。

というわけで、春休みの自由研究は、翌日の13日目から[本編1日目]となります。


#include "DxLib.h"

#include <array>

constexpr int ウインドウの大きさ_x = 1920;
constexpr int ウインドウの大きさ_y = 1080;
constexpr int ブロックの大きさ = ウインドウの大きさ_y / 16;

const std::string クレジット[] =
{
"クレジット",
"",
"",
"企画・アルゴリズム・マスくん・くじら・いちごブロック",
"お父さん",
"",
"タイピング練習監修・おやぐま",
"お母さん",
"",
"ステージ設計・プログラム・こぐま・はりせんぼん・いちごブロック以外のブロック",
"娘",
"",
"",
"作成環境",
"Windows 10 / VisualStudio Community 2019 / DXライブラリ",
"",
"",
"F3で戻ります"
};

int カメラの左上位置_x = 0;

enum class e_ブロック : int { 空気, 水, 草, 丸太, いちご };
enum class e_キャラクター : int { 未定義, マスくん, ドリル, こぐま, おやぐま, はりせんぼん, くじら };
enum class e_向き : bool { 右向き = false, 左向き = true };

struct s_画面
{
    enum class e_状態 : int { タイトル, ステージ選択, アクション, スタッフロール };
    e_状態 状態;
};

struct s_ブロック
{
    e_ブロック ブロックID;

    // 位置(いち)
    double x;
    double y;

    // 判定の位置
    double 判定_x;
    double 判定_y;

    // 判定の大きさ(はば、たかさ)
    double 判定_w;
    double 判定_h;
};

struct s_キャラクター
{
    e_キャラクター キャラクターID = e_キャラクター::未定義;
    e_向き 向き = e_向き::左向き;

    // 位置(いち)
    double x;
    double y;

    //速さ(はやさ)、速度(そくど)
    double vx;
    double vy;
    //加速度(かそくど)
    double ax;
    double ay;

    //判定の位置
    double 判定_x;
    double 判定_y;

    //判定の大きさ(はば、たかさ)
    double 判定_w;
    double 判定_h;

    //状態(じょうたい)
    enum class e_状態 : int { 接地, 空中, 水中, };
    e_状態 状態;
};

struct s_ステージ
{
    // 定義の部分
    std::array<std::array<s_ブロック, 16>, 128> ブロック; // [128][16]の配列、拡張性はない
    int スタート位置_x;
    int スタート位置_y;

    // 今の敵の状態
    std::array<s_キャラクター, 10> 敵;

    // 今のドリルの状態
    std::array<s_キャラクター, 1> ドリル;
};
s_ステージ ステージ_1;

int AABB(double A_x, double A_y, double A_w, double A_h, double B_x, double B_y, double B_w, double B_h)
{
    if (((A_x + A_w) < B_x) || (A_x > (B_x + B_w))) { return 0; }
    if (((A_y + A_h) < B_y) || (A_y > (B_y + B_h))) { return 0; }
    return 1;
}

bool キャラクターをブロックが押しのける(s_キャラクター& キャラクター, s_ブロック& ブロック)
{
    double キャラクター判定_x_world = キャラクター.x + キャラクター.判定_x;
    double キャラクター判定_y_world = キャラクター.y + キャラクター.判定_y;
    double ブロック判定_x_world = ブロック.x + ブロック.判定_x;
    double ブロック判定_y_world = ブロック.y + ブロック.判定_y;

    // まずブロックとくっついているか調べて、くっついていなければ特に何もしない
    if (AABB(キャラクター判定_x_world, キャラクター判定_y_world, キャラクター.判定_w, キャラクター.判定_h, ブロック判定_x_world, ブロック判定_y_world, ブロック.判定_w, ブロック.判定_h) == 0) { return false; }

    // キャラクターの1フレーム前の位置を、現在の速度を使って逆算する
    double キャラクター_x_org = キャラクター判定_x_world - キャラクター.vx;
    double キャラクター_y_org = キャラクター判定_y_world - キャラクター.vy;

    // 動く前の位置から、速度の分移動した位置の間で、まだブロックとくっついていないときと、もうブロックとくっついてしまったときの境目が存在する
    // その境目を探したい
    // vxあるいはvyが100%(1.0)のときはブロックとくっついているはず、また逆に0%(0.0)のときはブロックとくっついていないはず
    // そのため、90%から10%ずつ減らしてブロックから少しずつ遠ざけることによって、ブロックにくっつかないが一番ブロックに近い座標を探す
    for (double i_rate = 0.9; i_rate >= 0.0; i_rate -= 0.1)
    {
        double A_x_new = キャラクター_x_org + キャラクター.vx * i_rate;
        double A_y_new = キャラクター_y_org + キャラクター.vy * i_rate;

        // ブロックにくっつかない場合、その座標が探したいものなので、A_xとA_yに手に入れた答えを入れて、関数を終了する。
        if (AABB(A_x_new, A_y_new, キャラクター.判定_w, キャラクター.判定_h, ブロック判定_x_world, ブロック判定_y_world, ブロック.判定_w, ブロック.判定_h) == 0)
        {
            キャラクター.x = A_x_new - キャラクター.判定_x;
            キャラクター.y = A_y_new - キャラクター.判定_y;
            return true;
        };
    }

    return false;
}

int キャラクターとブロックの存在判定(s_キャラクター& キャラクター, s_ブロック& ブロック)
{
    // ブロックとくっついているか
    if (キャラクターをブロックが押しのける(キャラクター, ブロック) == true)
    {
        // キャラクターの下側がブロックの上側より上にあるとき、キャラクターはブロックの上に乗っている
        // 上に乗っている方が優先される
        if (キャラクター.y + キャラクター.判定_y + キャラクター.判定_h < ブロック.y)
        {
            キャラクター.vy *= double(0);
            キャラクター.状態 = s_キャラクター::e_状態::接地;
        }
        // キャラクターの右側がブロックの左側より左にあったり、キャラクターの左側がブロックの右側より右にあるとき、キャラクターは壁側にくっついているといえる
        else if ((キャラクター.x + キャラクター.判定_x + キャラクター.判定_w < ブロック.x) || (ブロック.x + ブロック.判定_x + ブロック.判定_w < キャラクター.x))
        {
            キャラクター.vx *= double(0);
        }

        return 1;
    }
    return 0;
}

void 重力と摩擦(s_キャラクター& キャラクター)
{
    if (キャラクター.状態 == s_キャラクター::e_状態::接地)
    {
        // 摩擦
        キャラクター.vx = double(0);

        キャラクター.vy = double(0);
        キャラクター.ay = double(0);
    }
    else
    {
        // 重力(重力)
        キャラクター.ay = +9.80665 / double(6); // 「6」はなんとなく
    }
}

void 加速度と速度の処理(s_キャラクター& キャラクター)
{
    // 加速度で速度を変える
    キャラクター.vx += キャラクター.ax;
    キャラクター.vy += キャラクター.ay;
    if (キャラクター.vy > double(+127)) { キャラクター.vy = double(+127); }

    // 速度で位置を変える
    キャラクター.x += キャラクター.vx;
    キャラクター.y += キャラクター.vy;
}


//==============================================================================

// プログラムは WinMain から始まります
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    ChangeWindowMode(true); // ウインドウモードで起動
    SetWindowStyleMode(7); // 7:最大化ボタンが存在するウインドウモードに変更

    SetGraphMode(1920, 1080, 32);
    SetWindowSize(1920, 1080); // 初期ウインドウの大きさ

    SetWindowSizeChangeEnableFlag(true, true); // ウインドウサイズ変更を可能にする(縦横比変更不可)

    if (DxLib_Init() == -1)     // DXライブラリ初期化処理
    {
        return -1;          // エラーが起きたら直ちに終了
    }

    SetTransColor(255, 255, 255);
    SetUsePremulAlphaConvertLoad(true); // 画像を読み込んだ後、乗算済みアルファ画像に変換する設定を有効にする
    SetDrawScreen(DX_SCREEN_BACK);//裏画面

    // 画像読み込み
    int 画像_マスくん_立ち = LoadGraph("../../data/マスくん_立ち.png");
    int 画像_マスくんの手 = LoadGraph("../../data/マスくんの手.png");
    int 画像_マスくんのドリル = LoadGraph("../../data/マスくんの手_ドリル.png");
    int マップ情報_1 = LoadSoftImage("../../data/マップ_1ステージ目.png");
    int 画像_ブロック_草 = LoadGraph("../../data/ブロック_草.png");
    int 画像_ブロック_丸太 = LoadGraph("../../data/ブロック_丸太.png");
    int 画像_ブロック_いちご = LoadGraph("../../data/ブロック_いちご.png");
    int 画像_敵_こぐま = LoadGraph("../../data/小熊.png");
    int 画像_敵_おやぐま = LoadGraph("../../data/熊.png");
    int 画像_敵_はりせんぼん = LoadGraph("../../data/ハリセンボン.png");

    int 次の敵番号 = 0;
    // マップ情報をブロックに変換
    for (int i_x = 0; i_x < 128; i_x += 1)
    {
        for (int i_y = 0; i_y < 16; i_y += 1)
        {
            ステージ_1.ブロック.at(i_x).at(i_y).x = i_x * ブロックの大きさ;
            ステージ_1.ブロック.at(i_x).at(i_y).y = i_y * ブロックの大きさ;
            ステージ_1.ブロック.at(i_x).at(i_y).判定_x = double(0);
            ステージ_1.ブロック.at(i_x).at(i_y).判定_y = double(0);
            ステージ_1.ブロック.at(i_x).at(i_y).判定_w = double(ブロックの大きさ);
            ステージ_1.ブロック.at(i_x).at(i_y).判定_h = double(ブロックの大きさ);

            int R, G, B, A;
            GetPixelSoftImage(マップ情報_1, i_x, i_y, &R, &G, &B, &A);

            /**/ if (R == 255 && G == 255 && B == 255) { ステージ_1.ブロック.at(i_x).at(i_y).ブロックID = e_ブロック::空気; }
            else if (R == 207 && G == 143 && B == 79) { ステージ_1.ブロック.at(i_x).at(i_y).ブロックID = e_ブロック::草; }
            else if (R == 128 && G == 64 && B == 0) { ステージ_1.ブロック.at(i_x).at(i_y).ブロックID = e_ブロック::丸太; }
            else if (R == 0 && G == 254 && B == 0) { ステージ_1.ブロック.at(i_x).at(i_y).ブロックID = e_ブロック::いちご; }
            else if (R == 0 && G == 128 && B == 255) { ステージ_1.ブロック.at(i_x).at(i_y).ブロックID = e_ブロック::水; }
            else if (R == 255 && G == 122 && B == 0)
            {
                ステージ_1.ブロック.at(i_x).at(i_y).ブロックID = e_ブロック::空気;
                ステージ_1.スタート位置_x = i_x;
                ステージ_1.スタート位置_y = i_y;
            }
            else if (R == 254 && G == 0 && B == 0)
            {
                ステージ_1.ブロック.at(i_x).at(i_y).ブロックID = e_ブロック::空気;
                ステージ_1.敵.at(次の敵番号).キャラクターID = e_キャラクター::こぐま;
                ステージ_1.敵.at(次の敵番号).x = i_x * ブロックの大きさ;
                ステージ_1.敵.at(次の敵番号).y = i_y * ブロックの大きさ;
                ステージ_1.敵.at(次の敵番号).判定_x = 41;
                ステージ_1.敵.at(次の敵番号).判定_y = 47;
                ステージ_1.敵.at(次の敵番号).判定_w = 43;
                ステージ_1.敵.at(次の敵番号).判定_h = 36;
                次の敵番号 += 1;
            }
            else if (R == 254 && G == 0 && B == 254)
            {
                ステージ_1.ブロック.at(i_x).at(i_y).ブロックID = e_ブロック::空気;
                ステージ_1.敵.at(次の敵番号).キャラクターID = e_キャラクター::おやぐま;
                ステージ_1.敵.at(次の敵番号).x = i_x * ブロックの大きさ;
                ステージ_1.敵.at(次の敵番号).y = i_y * ブロックの大きさ;
                ステージ_1.敵.at(次の敵番号).判定_x = 44;
                ステージ_1.敵.at(次の敵番号).判定_y = 29;
                ステージ_1.敵.at(次の敵番号).判定_w = 39;
                ステージ_1.敵.at(次の敵番号).判定_h = 98;
                次の敵番号 += 1;
            }
            else if (R == 255 && G == 248 && B == 64)
            {
                ステージ_1.ブロック.at(i_x).at(i_y).ブロックID = e_ブロック::水;
                ステージ_1.敵.at(次の敵番号).キャラクターID = e_キャラクター::はりせんぼん;
                ステージ_1.敵.at(次の敵番号).x = i_x * ブロックの大きさ;
                ステージ_1.敵.at(次の敵番号).y = i_y * ブロックの大きさ;
                ステージ_1.敵.at(次の敵番号).判定_x = 22;
                ステージ_1.敵.at(次の敵番号).判定_y = 25;
                ステージ_1.敵.at(次の敵番号).判定_w = 80;
                ステージ_1.敵.at(次の敵番号).判定_h = 74;
                次の敵番号 += 1;
            }
        }
    }

    s_キャラクター マスくん;
    マスくん.キャラクターID = e_キャラクター::マスくん;
    マスくん.向き = e_向き::右向き;
    マスくん.x = ステージ_1.スタート位置_x * ブロックの大きさ;
    マスくん.y = ステージ_1.スタート位置_y * ブロックの大きさ;
    マスくん.判定_x = 50;
    マスくん.判定_y = 26;
    マスくん.判定_w = 43;
    マスくん.判定_h = 81;

    bool is_クレジット表示 = false;
    int カメラの左端 = 0;
    while (ProcessMessage() != -1)
    {
        // キーボードの入力を取得する
        char keydata[256];
        GetHitKeyStateAll(keydata);

        if (keydata[KEY_INPUT_F1] == 1)
        {
            is_クレジット表示 = true;
        }

        if (keydata[KEY_INPUT_F3] == 1)
        {
            is_クレジット表示 = false;
        }

        ClearDrawScreen(); // 画面を掃除する
        if (is_クレジット表示 == true)
        {
            int i_line = 0;
            for (auto& itm : クレジット)
            {
                DrawString(0, i_line * 32, itm.c_str(), GetColor(255, 255, 255));
                i_line += 1;
            }

            ScreenCopy(); // 描画を反映する
            continue;
        }
        else
        {
            DrawBox(0, 0, ウインドウの大きさ_x, ウインドウの大きさ_y, GetColor(255, 255, 255), true);
            DrawString(128, 0, "F1でクレジット表示", GetColor(0, 0, 0));
        }



        重力と摩擦(マスくん);
        for (int i_敵 = 0; i_敵 < 10; i_敵 += 1)
        {
            if (ステージ_1.敵.at(i_敵).キャラクターID != e_キャラクター::未定義)
            {
                重力と摩擦(ステージ_1.敵.at(i_敵));
            }
        }

        if (keydata[KEY_INPUT_RIGHT] == 1)
        {
            マスくん.vx = double(+10);
            マスくん.向き = e_向き::右向き;
        }
        if (keydata[KEY_INPUT_LEFT] == 1)
        {
            マスくん.vx = double(-10);
            マスくん.向き = e_向き::左向き;
        }

        if (keydata[KEY_INPUT_Z] == 1 && マスくん.状態 != s_キャラクター::e_状態::空中)
        {
            //マスくん.vy -= double(25);
            マスくん.vy -= double(50);
            マスくん.状態 = s_キャラクター::e_状態::空中;
        }

        if (keydata[KEY_INPUT_X] == 1)
        {
            if (マスくん.向き == e_向き::右向き)
            {
                ステージ_1.ドリル.at(0).x = マスくん.x + 16;
                ステージ_1.ドリル.at(0).y = マスくん.y + 16;
                ステージ_1.ドリル.at(0).vx = double(+15);
                ステージ_1.ドリル.at(0).向き = e_向き::右向き;
            }
            else
            {
                ステージ_1.ドリル.at(0).x = マスくん.x - 16;
                ステージ_1.ドリル.at(0).y = マスくん.y + 16;
                ステージ_1.ドリル.at(0).vx = double(-15);
                ステージ_1.ドリル.at(0).向き = e_向き::左向き;
            }
        }

        加速度と速度の処理(マスくん);
        for (int i_敵 = 0; i_敵 < 10; i_敵 += 1)
        {
            if (ステージ_1.敵.at(i_敵).キャラクターID != e_キャラクター::未定義)
            {
                加速度と速度の処理(ステージ_1.敵.at(i_敵));
            }
        }
        加速度と速度の処理(ステージ_1.ドリル.at(0));

        カメラの左端 = マスくん.x - (ウインドウの大きさ_x / 2);
        if (カメラの左端 < 0) { カメラの左端 = 0; }
        if (カメラの左端 >= (ブロックの大きさ * 128 - ウインドウの大きさ_x)) { カメラの左端 = (ブロックの大きさ * 128 - ウインドウの大きさ_x); }

        // 判定処理
        int マスくんとブロックがくっついている数 = 0;
        for (int i_x = 0; i_x < 128; i_x += 1)
        {
            for (int i_y = 16 - 1; i_y >= 0; i_y -= 1)
            {
                if (ステージ_1.ブロック.at(i_x).at(i_y).ブロックID != e_ブロック::空気)
                {
                    マスくんとブロックがくっついている数 += キャラクターとブロックの存在判定(マスくん, ステージ_1.ブロック.at(i_x).at(i_y));
                }
            }
        }
        if (マスくんとブロックがくっついている数 == 0)
        {
            マスくん.状態 = s_キャラクター::e_状態::空中;
        }
        for (int i_敵 = 0; i_敵 < 10; i_敵 += 1)
        {
            if (ステージ_1.敵.at(i_敵).キャラクターID != e_キャラクター::未定義)
            {
                int 敵とブロックがくっついている数 = 0;
                for (int i_x = 0; i_x < 128; i_x += 1)
                {
                    for (int i_y = 16 - 1; i_y >= 0; i_y -= 1)
                    {
                        if (ステージ_1.ブロック.at(i_x).at(i_y).ブロックID != e_ブロック::空気)
                        {
                            敵とブロックがくっついている数 += キャラクターとブロックの存在判定(ステージ_1.敵.at(i_敵), ステージ_1.ブロック.at(i_x).at(i_y));
                        }
                    }
                }
                if (敵とブロックがくっついている数 == 0)
                {
                    ステージ_1.敵.at(i_敵).状態 = s_キャラクター::e_状態::空中;
                }
            }
        }

        // 背景の描画

        // ブロックの描画
        for (int i_x = 0; i_x < 128; i_x += 1)
        {
            for (int i_y = 16 - 1; i_y >= 0; i_y -= 1)
            {
                int 左上座標_x = ブロックの大きさ * i_x;
                int 左上座標_y = ブロックの大きさ * i_y;

                switch (ステージ_1.ブロック.at(i_x).at(i_y).ブロックID)
                {
                case e_ブロック::空気: {  } break;
                case e_ブロック::草: { DrawExtendGraph(左上座標_x - カメラの左端, 左上座標_y - ブロックの大きさ, 左上座標_x + ブロックの大きさ - カメラの左端, 左上座標_y + ブロックの大きさ, 画像_ブロック_草, true); } break;
                case e_ブロック::丸太: { DrawExtendGraph(左上座標_x - カメラの左端, 左上座標_y - ブロックの大きさ, 左上座標_x + ブロックの大きさ - カメラの左端, 左上座標_y + ブロックの大きさ, 画像_ブロック_丸太, true); } break;
                case e_ブロック::いちご: { DrawExtendGraph(左上座標_x - カメラの左端, 左上座標_y - ブロックの大きさ, 左上座標_x + ブロックの大きさ - カメラの左端, 左上座標_y + ブロックの大きさ, 画像_ブロック_いちご, true); } break;
                case e_ブロック::水: {  } break;
                }
            }
        }

        // 敵の描画
        for (int i_敵 = 0; i_敵 < 10; i_敵 += 1)
        {
            switch (ステージ_1.敵.at(i_敵).キャラクターID)
            {
            case e_キャラクター::こぐま: { DrawGraph(double(ステージ_1.敵.at(i_敵).x - カメラの左端), double(ステージ_1.敵.at(i_敵).y), 画像_敵_こぐま, true); }break;
            case e_キャラクター::おやぐま: { DrawGraph(double(ステージ_1.敵.at(i_敵).x - カメラの左端), double(ステージ_1.敵.at(i_敵).y), 画像_敵_おやぐま, true); }break;
            case e_キャラクター::はりせんぼん: { DrawGraph(double(ステージ_1.敵.at(i_敵).x - カメラの左端), double(ステージ_1.敵.at(i_敵).y), 画像_敵_はりせんぼん, true); }break;
            default: {}
            }
        }

        // マスくんの描画
        if (マスくん.向き == e_向き::右向き)
        {
            DrawGraph(double(マスくん.x - カメラの左端), double(マスくん.y), 画像_マスくん_立ち, true);
            DrawGraph(double(マスくん.x - カメラの左端), double(マスくん.y), 画像_マスくんの手, true);
        }
        else
        {
            DrawTurnGraph(double(マスくん.x - カメラの左端), double(マスくん.y), 画像_マスくん_立ち, true);
            DrawTurnGraph(double(マスくん.x - カメラの左端), double(マスくん.y), 画像_マスくんの手, true);
        }

        if (マスくん.向き == e_向き::右向き)
        {
            DrawGraph(double(ステージ_1.ドリル.at(0).x - カメラの左端), double(ステージ_1.ドリル.at(0).y), 画像_マスくんのドリル, true);
        }
        else
        {
            DrawTurnGraph(double(ステージ_1.ドリル.at(0).x - カメラの左端), double(ステージ_1.ドリル.at(0).y), 画像_マスくんのドリル, true);
        }


        // 判定の描画
        DrawBox(マスくん.x + マスくん.判定_x - カメラの左端, マスくん.y + マスくん.判定_y, マスくん.x + マスくん.判定_x + マスくん.判定_w - カメラの左端, マスくん.y + マスくん.判定_y + マスくん.判定_h, GetColor(0, 0, 255), false);
        for (int i_x = 0; i_x < 128; i_x += 1)
        {
            for (int i_y = 16 - 1; i_y >= 0; i_y -= 1)
            {
                if (ステージ_1.ブロック.at(i_x).at(i_y).ブロックID != e_ブロック::空気)
                {
                    int x1 = ステージ_1.ブロック.at(i_x).at(i_y).x + ステージ_1.ブロック.at(i_x).at(i_y).判定_x - カメラの左端;
                    int y1 = ステージ_1.ブロック.at(i_x).at(i_y).y + ステージ_1.ブロック.at(i_x).at(i_y).判定_y;
                    int x2 = ステージ_1.ブロック.at(i_x).at(i_y).x + ステージ_1.ブロック.at(i_x).at(i_y).判定_x + ステージ_1.ブロック.at(i_x).at(i_y).判定_w - カメラの左端;
                    int y2 = ステージ_1.ブロック.at(i_x).at(i_y).y + ステージ_1.ブロック.at(i_x).at(i_y).判定_y + ステージ_1.ブロック.at(i_x).at(i_y).判定_h;

                    DrawBox(x1, y1, x2, y2, GetColor(0, 0, 255), false);
                }
            }
        }
        for (int i_敵 = 0; i_敵 < 10; i_敵 += 1)
        {
            if (ステージ_1.敵.at(i_敵).キャラクターID != e_キャラクター::未定義)
            {
                int x1 = ステージ_1.敵.at(i_敵).x + ステージ_1.敵.at(i_敵).判定_x - カメラの左端;
                int y1 = ステージ_1.敵.at(i_敵).y + ステージ_1.敵.at(i_敵).判定_y;
                int x2 = ステージ_1.敵.at(i_敵).x + ステージ_1.敵.at(i_敵).判定_x + ステージ_1.敵.at(i_敵).判定_w - カメラの左端;
                int y2 = ステージ_1.敵.at(i_敵).y + ステージ_1.敵.at(i_敵).判定_y + ステージ_1.敵.at(i_敵).判定_h;

                DrawBox(x1, y1, x2, y2, GetColor(0, 0, 255), false);
            }
        }


        ScreenCopy(); // 描画を反映する
    }

    DxLib_End();                // DXライブラリ使用の終了処理

    return 0;               // ソフトの終了 
}

おすすめ

コメントを残す

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