Hilary02
3/20/2019 - 2:02 PM

Siv3D

テキストボックスの領域内で文字の描画を行うゲームランチャ(Siv3D)

#include "stdafx.h"
#include "Launcher.h"

Launcher::Launcher(const FilePath& path) :
    loader(path),
    fontTitle(27),
    fontSub(18),
    fontExplain(20),
    rectTitle(420, 30, 510, 55),
    rectSub(420, 90, 510, 40),
    rectExplain(420, Window::Height() - 150, 510, 140) {
    /*リソース読み込みはここ*/
    games = loader.LoadGames();
    numGames = games.size() ;
    numImgs = games[selectGame].screenshot.size();
}

Launcher::~Launcher(){}

void Launcher::Update() {
    /*キー監視とかここ*/
    if (Input::KeyDown.clicked) {
        selectGame = numLoop(selectGame + 1, numGames);
        selectImg = 0;
        numImgs = games[selectGame].screenshot.size();
    }
    if (Input::KeyUp.clicked) {
        selectGame = numLoop(selectGame - 1, numGames);
        selectImg = 0;
        numImgs = games[selectGame].screenshot.size();
    }
    if (Input::KeyLeft.clicked) {
        selectImg = numLoop(selectImg + 1, numImgs);
    }
    if (Input::KeyRight.clicked) {
        selectImg = numLoop(selectImg - 1, numImgs);
    }

    if (Input::KeyZ.clicked) {
        process = System::CreateProcess(games[selectGame].exePath);
        playingCounter = 0;
    }
    winW = Window::Width();
    winH = Window::Height();

    rectTitle.setSize(winW - 440, 55);
    rectSub.setSize(winW - 440, 40);
    rectExplain.setPos(420, winH - 150);
    rectExplain.setSize(winW - 440, 140);
}

void Launcher::Draw() {
    /*描画はここ*/
    Rect(88, Window::Height() / 4 - 90 - 32, bannerSub.w + 4, bannerSub.h + 4).draw(Palette::Blue);
    games[numLoop(selectGame - 1, numGames)].banner.resize(bannerSub.w, bannerSub.h).draw(90, Window::Height() / 4 - 90 - 30);

    Rect(88, Window::Height() * 3 / 4 - 90 + 28, bannerSub.w + 4, bannerSub.h + 4).draw(Palette::Red);
    games[numLoop(selectGame + 1, numGames)].banner.resize(bannerSub.w, bannerSub.h).draw(90, Window::Height() * 3 / 4 - 90 + 30);

    Rect(48, Window::Height() / 2 - 122, bannerCenter.w + 4, bannerCenter.h + 4).draw();
    games[selectGame].banner.resize(bannerCenter.w, bannerCenter.h).draw(50, Window::Height() / 2 - 120);

    fontSub.draw(ToString(selectGame + 1) + L"/" + ToString(numGames), Vec2(10, Window::Height() - 50));
    //画像と説明文との境界線
    Line(400, 0, 400, Window::Height()).draw(5);
    Line(406, 0, 406, Window::Height()).draw(2);

    //説明文の表示
    rectTitle.draw();
    rectSub.draw();
    rectExplain.draw();

    fontTitle.drawCenter(games[selectGame].info.name, Vec2(420 + (winW - 440) / 2, 58), Palette::Black);
    fontSub.drawCenter(games[selectGame].info.controll, Vec2(420 + (winW - 440) / 2, 110), Palette::Black);

    int pos = 0;
    Array<String> texts;
    String text = games[selectGame].info.explain;

    while (pos < text.length) {
        int n = Max<int>(fontExplain.drawableCharacters(text, winW - 440 - 420), 1);
        texts.push_back(text.substr(pos, n));
        pos += n;
    }
    for (size_t i = 0; i < texts.size(); ++i) {
        int y = static_cast<int>(rectExplain.y + 10 + i * fontExplain.height);
        bool overflow = (i + 1 < texts.size()) && (y + fontExplain.height * 2 + 10 > rectExplain.y + rectExplain.h);
        if (overflow) {
            if (texts[i].length > 2) {
                texts[i].resize(texts[i].length - (texts[i].length > 2 ? 2 : 1));
            }
            texts[i].append(L"...");
        }

        fontExplain(texts[i]).draw(rectExplain.x + 5, y, Palette::Black);

        if (overflow) {
            break;
        }
    }

    //fontExplain.draw(games[selectGame].info.explain, Vec2(420, winH - 200), Palette::Black);
    games[selectGame].screenshot[selectImg].resize(bannerCenter.w, bannerCenter.h).draw(460, Window::Height() / 2 - 120);

    fontSub.draw(ToString(selectImg) + L"/" + ToString(numImgs));

    //実行中ならば最少化&カウンタ回す
    if (process) {
        if (process->isRunning()) {
            Window::Minimize();
            playingCounter++;
        }
        else {
            Window::Restore();
            process = none;
        }
    }
}

int Launcher::numLoop(int next, int max) {
    if (next >= max) return 0;
    if (next < 0) return max - 1;
    return next;
}