MENU

ウェブサイトでビートマニアがしたくなった仕事中に

ので、
いつも通りにチャッピーに聞きました。

はい、ウェブサイト上にビートマニアのようなリズムゲームを再現することは可能です!以下は簡単な実装方法の概要です。必要な技術としては、HTML, CSS, JavaScript を使用します。

さすがやで。

開始をクリックしてスタート
ASDFキーで赤い線に入ったら消えるまでにキーを押す
終了をクリックしておわりです。

さすがやで。

A
S
D
F
Score: 0

チャットGPTで10分もあればこんなものが出来てしまうのは、
実にすごいなぁと思いました・・・(仕事中に)

以下ソースとか(要らないかもしれないですが・・・

【html】

<div id="game-area">
    <div class="lane" data-key="a">
        <div class="lane-key">A</div>
        <div class="judge-line"></div>
    </div>
    <div class="lane" data-key="s">
        <div class="lane-key">S</div>
        <div class="judge-line"></div>
    </div>
    <div class="lane" data-key="d">
        <div class="lane-key">D</div>
        <div class="judge-line"></div>
    </div>
    <div class="lane" data-key="f">
        <div class="lane-key">F</div>
        <div class="judge-line"></div>
    </div>
    <div id="score">Score: 0</div>
</div>
<div id="controls">
    <button id="start-button">開始</button>
    <button id="stop-button">終了</button>
</div>

<script src="script.js"></script>

【css】

body {
    margin: 0;
}

#game-area {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    height: 60vh;
    position: relative;
    overflow: hidden;
}

.lane {
    position: relative;
    width: 50px;
    height: 100%;
    background-color: #222;
    border: 1px solid #ccc; /* レーンの枠線 */
    margin: 0 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end; /* キー名を下部に配置 */
    overflow: hidden;
}

.lane-key {
    position: absolute;
    bottom: 10px; /* レーンの下部に配置 */
    font-size: 20px;
    color: white;
    background-color: rgba(0, 0, 0, 0.7);
    padding: 5px 10px;
    border-radius: 5px;
    pointer-events: none; /* マウスクリックを無効化 */
}

.note {
    width: 50px;
    height: 15px;
    background-color: rgba(255, 255, 255, 0.755);
    position: absolute;
    bottom: 100%;
    animation: drop 2s linear infinite;
}

@keyframes drop {
    to {
        bottom: 0;
    }
}

#score {
    position: absolute;
    top: 10px;
    left: 10px;
}

#controls {
    margin-top: 20px;
}

button {
    padding: 10px 20px;
    font-size: 16px;
    margin: 0 10px;
    cursor: pointer;
}

button:hover {
    background-color: #333;
    color: white;
}

.score-effect {
    position: absolute;
    bottom: 50px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 18px;
    color: gold;
    animation: fade-out 1s forwards;
    pointer-events: none;
}

@keyframes fade-out {
    0% {
        opacity: 1;
        transform: translateX(-50%) translateY(0);
    }
    100% {
        opacity: 0;
        transform: translateX(-50%) translateY(-20px);
    }
}

.judge-line {
    position: absolute;
    bottom: 50px; /* 判定エリアの位置 */
    width: 100%; /* レーン全体に線を引く */
    height: 2px; /* ラインの太さ */
    background-color: red; /* ラインの色 */
    pointer-events: none; /* マウスクリックを無効化 */
}

【js】

let score = 0;
let gameInterval = null;

// ノートが消える位置に得点表示を追加する関数
function showScoreEffect(lane, points) {
    const effect = document.createElement('div');
    effect.textContent = `+${points}`;
    effect.classList.add('score-effect');
    lane.appendChild(effect);

    // 少し時間が経ったら得点表示を消す
    setTimeout(() => {
        effect.remove();
    }, 1000);
}

document.addEventListener('keydown', (event) => {
    const key = event.key.toLowerCase();
    const lane = document.querySelector(`.lane[data-key="${key}"]`);
    if (lane) {
        const notes = lane.querySelectorAll('.note');
        if (notes.length > 0) {
            const note = notes[0];
            const noteBottom = parseFloat(window.getComputedStyle(note).bottom);
            if (noteBottom < 50 && noteBottom > 0) { // 判定範囲
                note.remove(); // ノートを削除
                score += 10; // スコア加算
                updateScore(); // スコア更新

                // 得点エフェクトを表示
                showScoreEffect(lane, 10);
            }
        }
    }
});

function createNote() {
    const lanes = document.querySelectorAll('.lane');
    const randomLane = lanes[Math.floor(Math.random() * lanes.length)];
    const note = document.createElement('div');
    note.classList.add('note');
    randomLane.appendChild(note);

    setTimeout(() => {
        if (note.parentElement) {
            note.remove();
        }
    }, 2000); // ノートが流れる時間と一致
}

function updateScore() {
    document.getElementById('score').textContent = `Score: ${score}`;
}

function startGame() {
    if (!gameInterval) {
        gameInterval = setInterval(createNote, 1000);
        console.log("ゲーム開始");
    }
}

function stopGame() {
    if (gameInterval) {
        clearInterval(gameInterval);
        gameInterval = null;
        console.log("ゲーム終了");
    }
}

// ボタンにイベントリスナーを設定
document.getElementById('start-button').addEventListener('click', startGame);
document.getElementById('stop-button').addEventListener('click', stopGame);

人間の要らない、いい時代になったもんだ・・・(と、仕事中に

目次