LoginSignup
0
0

RPGの戦闘シーン(?)のシュミレーターを作ってみた

Last updated at Posted at 2024-06-01

初めに

今回はRPGゲームの戦闘シーンのシュミレーター(?)を作ります

準備物

特になし

ファイル構成

今回はmain.htmlだけで作ります

プログラムをコピペ

以下のコードをコピペしてください

main.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>RPG simulator</title>
    <style>
        body {
            text-align: center;
        }
        input[type="text"] {
            width: 300px;
            height: 30px;
        }
        input[type="text"]:hover {
            background-color: rgb(0, 174, 255);
        }
        input[type="text"]:focus {
            background-color: rgb(0, 81, 255);
        }
        button {
            width: 100px;
            height: 35px;
            background-color: rgb(58, 57, 57);
            color: white;
            margin-bottom: 20px;
            margin-top: 20px;
        }
        button:hover {
            background-color: rgb(87, 85, 85);
        }
        .container {
            display: flex;
            justify-content: space-between;
            margin: 0 auto;
            margin-top: 20px;
            margin-bottom: 20px;
            width: 1000px;
            height: 200px;
            overflow: scroll;
            border: 1px solid black;
            text-align: left;
        }
        .info-box {
            width: 48%;
        }
        textarea {
            resize: none;
            width: 400px;
            height: 100px;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h2>RPGのシュミレーター(戦闘シーン)</h2>
    <p>rpgのシュミレーターです</p>
    <input type="text" id="name" placeholder="ニックネームを入力">
    <br>
    <textarea readonly hidden id="waza">技表
殴る:相手を殴る 攻撃力10
魔法:魔法を使う攻撃力0~100 消費mp50
火:炎で攻撃 攻撃力0~20
逃げる:逃げる(敗北)
    </textarea>
    <br>
    <button id="btn" onclick="start()">スタート</button>
    <br>
    <input type="text" id="navi" readonly>
    <br>
    <div class="container" id="status"></div>
    <script>
        let d = document;
        let waza = d.getElementById("waza");
        let player;
        let enemy;
        let navi = d.getElementById("navi");
        let btn = d.getElementById("btn");
        let tbox = d.getElementById("name");
        let container = d.getElementById("status");
        const typingInterval = 50;

        const propertyFormat = obj => `
          名前: ${obj.name}
          HP: ${obj.hp}
          MP: ${obj.mp}
          攻撃力: ${obj.attack}
          防御力: ${obj.defense}
        `;

        function createPlayer() {
            let playerName = tbox.value.trim() || "anonymous";
            player = {
                name: playerName,
                hp: 100,
                mp: 100,
                attack: 20,
                defense: 10
            };
        }

        function createEnemy() {
            enemy = {
                name: "",
                hp: 100,
                mp: 100,
                attack: 15,
                defense: 5
            };
        }

        function message(text) {
            return new Promise(resolve => {
                let currentIndex = 0;
                function displayNextChar() {
                    if (currentIndex < text.length) {
                        navi.value += text[currentIndex];
                        currentIndex++;
                        setTimeout(displayNextChar, typingInterval);
                    } else {
                        setTimeout(() => {
                            navi.value = "";
                            resolve();
                        }, 500);
                    }
                }
                displayNextChar();
            });
        }

        async function start() {
            tbox.disabled = true;
            btn.disabled = true;
            tbox.textContent = "";
            tbox.placeholder = "しばらくお待ちください。";
            await message("戦闘を開始しています...");
            await message("hp等を初期化中...");
            await message("最終処理中...");
            tbox.placeholder = "攻撃名を入力";
            
            await message("敵が現れた!");
            btn.textContent = "attack";
            btn.onclick = function() { attack_1p(); };
            createPlayer();
            createEnemy();
            displayPlayerInfo();
            displayEnemyInfo();
            att();
        }

        function displayPlayerInfo() {
            let playerInfo = document.createElement("div");
            playerInfo.classList.add("info-box", "player-info");
            let playerHeaderText = document.createElement("div");
            playerHeaderText.textContent = "プレイヤー情報";
            playerInfo.appendChild(playerHeaderText);
            let playerStatusText = document.createElement("div");
            playerStatusText.textContent = propertyFormat(player);
            playerInfo.appendChild(playerStatusText);
            container.appendChild(playerInfo);
        }

        function displayEnemyInfo() {
            let enemyInfo = document.createElement("div");
            enemyInfo.classList.add("info-box", "enemy-info");
            let enemyHeaderText = document.createElement("div");
            enemyHeaderText.textContent = "敵情報";
            enemyInfo.appendChild(enemyHeaderText);
            let enemyStatusText = document.createElement("div");
            enemyStatusText.textContent = propertyFormat(enemy);
            enemyInfo.appendChild(enemyStatusText);
            container.appendChild(enemyInfo);
        }

        async function att() {
            await message(`${player.name}の攻撃`);
            tbox.disabled = false;
            waza.hidden = false;
            btn.disabled = false;
        }

        async function attack_1p() {
            btn.disabled = true;
            switch(tbox.value) {
                case "殴る":
                    await message(`${player.name}は殴った!`);
                    await message(`10のダメージ`);
                    enemy.hp -= 10;
                    break;
                case "魔法":
                    if (player.mp >= 50) {
                        let power = Math.floor(Math.random() * 100);
                        await message(`${player.name}は魔法を使った`);
                        await message(`${power}のダメージ`);
                        enemy.hp -= power;
                        player.mp -= 50;
                    } else {
                        await message("MPが足りません!");
                        return;
                    }
                    break;
                case "":
                    let firePower = Math.floor(Math.random() * 20);
                    await message(`${player.name}は炎を使った`);
                    await message(`${firePower}のダメージ`);
                    enemy.hp -= firePower;
                    break;
                case "逃げる":
                    await message(`${player.name}は逃げた`);
                    await message(`${enemy.name}の勝利`);
                    return;
                default:
                    await message("無効な攻撃名です");
                    btn.disabled = false;
                    return;
            }
            updateInfo();
            finishcheck_player();
        }

        async function attack_enemy() {
            let attnum = Math.floor(Math.random() * 3);
            switch(attnum) {
                case 0:
                    await message(`${enemy.name}は殴った`);
                    await message("10のダメージ");
                    player.hp -= 10;
                    break;
                case 1:
                    await message(`${enemy.name}は魔法を使った`);
                    if(enemy.mp >= 50) {
                        let power = Math.floor(Math.random() * 100);
                        await message(`${power}の攻撃`);
                        player.hp -= power;
                        enemy.mp -= 50;
                    } else {
                        await message("MPが足りません!");
                    }
                    break;
                case 2:
                    await message(`${enemy.name}は炎を使った`);
                    let power = Math.floor(Math.random() * 20);
                    await message(`${power}のダメージ`);
                    player.hp -= power;
                    break;
            }
            updateInfo();
            finishcheck_enemy();
        }

        async function finishcheck_player() {
            if(enemy.hp <= 0) {
                await message(`${enemy.name}は倒れた`);
                await message(`${player.name}の勝利`);
            } else {
                attack_enemy();
            }
        }

        async function finishcheck_enemy() {
            if(player.hp <= 0) {
                await message(`${player.name}は倒れた`);
                await message(`${enemy.name}の勝利`);
            } else {
                att();
            }
        }

        function updateInfo() {
            let playerInfo = container.querySelector('.player-info');
            let enemyInfo = container.querySelector('.enemy-info');
            if (playerInfo && enemyInfo) {
                let playerStatusText = playerInfo.querySelector('div:nth-child(2)');
                playerStatusText.textContent = propertyFormat(player);
                let enemyStatusText = enemyInfo.querySelector('div:nth-child(2)');
                enemyStatusText.textContent = propertyFormat(enemy);
            } else {
                console.error('情報が見つかりません');
            }
        }
    </script>
</body>
</html>

これでプログラムは完成しました。

最後に

皆さん、いかがだったでしょうか?今回はhtmlとjsを使って簡単な戦闘シーンのシュミレーターを作りました。ちなみに今回も修正をGPTにやってもらいました。
それではまたお会いしましょう!

0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0