2. JavaScriptを体験してみよう

実際にJavaScriptのソースコードと実行サンプルを見てみましょう。

<style type="text/css">
#gameArea {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
#settingForm {
    margin : 10px 0;
}
#settingForm > div {
    display : inline-block;
    border : 1px #ddd solid;
}
#settingForm > div div:first-child {
    background-color: #ace;
    border-bottom : 1px #ddd solid;
}
</style>
<script type="text/javascript">
    window.addEventListener("load", function() {
        // ゲーム情報の宣言と初期値の設定
        var gameData = {
            maxNum : 25,  // クリックする数字の最大数
            panelPixelSize : 50,  // パネル1枚分の縦横のピクセル数
            gamePixelSize : 250, // ゲーム部分の縦横のピクセル数
            panelSideNum : 5,   // 一辺あたりのパネル数
            nextNum : 1,   // 次にクリックする数字
            border : {    // パネルの枠線の設定
                size : 1,
                color : "#ddd",
                type : "solid",
            },
            panelColor : {    // 未クリック時とクリック後のパネル色
            notClicked : "#fff",
            clicked : "#ace",
            },
        };
    
        /*
         * 設定された最大数とパネルサイズから、全体の大きさを計算する関数
         */
        function calcGameSize() {
            var panelSideNum = 1;
            while (panelSideNum*panelSideNum < gameData.maxNum) {
                panelSideNum++;
            }
            gameData.panelSideNum = panelSideNum;
            var gameAreaa = document.getElementById("gameArea");
            var sideLength = gameData.panelPixelSize * gameData.panelSideNum + gameData.border.size * panelSideNum * 2;
            gameArea.style.width = gameArea.style.height = sideLength + "px";
        }
    
        /*
         * 設定された最大数分のパネルを生成する関数
         */
        function createPanel() {
            var panels = [];
            for (var i=1; i<=gameData.panelSideNum*gameData.panelSideNum; i++) {
                var panel = document.createElement("div");
                panel.innerHTML = (i <= gameData.maxNum) ? i : " ";
                panel.style.textAlign = "center";
                panel.style.color = "#000";
                panel.style.fontWeight = "bold";
                panel.style.backgroundColor = gameData.panelColor.notClicked;
                panel.style.border = gameData.border.size + "px " + gameData.border.color + " " + gameData.border.type;
                panel.style.width = gameData.panelPixelSize + "px";
                panel.style.height = gameData.panelPixelSize + "px";
                panel.style.display = "inline-block";
                panel.addEventListener("click", function(event) {
                    if (parseInt(event.target.textContent) == gameData.nextNum) {
                        event.target.style.backgroundColor = gameData.panelColor.clicked;
                        updateGameStatus();
                    }
                });
                panels.push(panel);
            }
            // 空白パネルの数を計算
            var emptyPanelCount = (gameData.panelSideNum * gameData.panelSideNum - gameData.maxNum) % gameData.panelSideNum;
            while (panels.length) {
                var gameArea = document.getElementById("gameArea");
                var i = Math.floor(Math.random() * panels.length);
                if (panels[i].innerHTML == " ") {
                    // 空白パネルを必要な数だけ末尾に追加します
                    if (emptyPanelCount > 0) {
                        emptyPanelCount--;
                        gameArea.appendChild(panels[i]);
                    }
                }
                else {
                    // 数字パネルを先頭に追加します
                    gameArea.insertBefore(panels[i], gameArea.firstChild);
                }
                panels.splice(i, 1);
            }
        }
    
        /*
         * ゲーム情報を更新します
         */
        function updateGameStatus() {
            gameData.nextNum++;
            if (gameData.nextNum == gameData.maxNum + 1) {
                alert("CLEAR!!");
            }
        }
    
        /*
         * 最大数とパネルサイズの初期値の設定と、適用・リセットボタンのイベントを設定します
         * 設定後にreset関数を呼び出し、ゲームの状態を初期化します
         */
        function init() {
            var formElm = document.getElementById("settingForm");
            formElm.maxNum.value = gameData.maxNum;
            formElm.panelPixelSize.value = gameData.panelPixelSize;
            document.getElementById("applyBtn").addEventListener("click", function() {
                if (!parseInt(formElm.maxNum.value) || !parseInt(formElm.panelPixelSize.value)) {
                    alert("最大数とパネルサイズは1以上の半角数字で入力してください。");
                }
                else {
                    gameData.maxNum = parseInt(formElm.maxNum.value);
                    gameData.panelPixelSize = parseInt(formElm.panelPixelSize.value);
                    reset();
                }
            });
            document.getElementById("resetBtn").addEventListener("click", function() {
                reset();
            });
    
            reset();
        }
    
        /*
         * リセット時と初回実行時に必要な処理を実行する関数です
         */
        function reset() {
            gameData.nextNum = 1;
            document.getElementById("gameArea").innerHTML = "";
            calcGameSize();
            createPanel();
        }
    
        init();
    });
</script>
<form id="settingForm" name="settingForm" onsubmit="return false;">
    <div>
        <div>
            最大数
        </div>
        <div>
            <input type="text" name="maxNum" value="" />
        </div>
    </div>
    <div>
        <div>
            パネルサイズ
        </div>
        <div>
            <input type="text" name="panelPixelSize" value="" />
        </div>
    </div>
    <input id="applyBtn" type="button" value="適用" />
    <input id="resetBtn" type="button" value="リセット" />
</form>
<div id="gameArea"></div>

This software includes the work that is distributed in the Apache License 2.0

最終更新日時: 2022年 02月 17日(木曜日) 09:12