3
3

画面が汚れているな。 カラフルなパーティクル掃除機ゲーム。スペースキーで吸引です。

Posted at

スクリーンショット 2024-09-02 042744.png

スクリーンショット 2024-09-02 042805.png

マウスでノズルを移動してスペースキーを押すと吸引です。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>カラフルなパーティクル掃除機ゲーム</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background-color: #000;
        }
        canvas {
            display: block;
        }
        .nozzle {
            position: absolute;
            width: 50px;
            height: 50px;
            background-color: #fff;
            border-radius: 50%;
        }
        .fps-counter {
            position: absolute;
            top: 10px;
            left: 10px;
            color: #00ff00;
            font-size: 20px;
            font-family: monospace;
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas"></canvas>
    <div id="nozzle" class="nozzle"></div>
    <div id="fpsCounter" class="fps-counter"></div>
    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const nozzle = document.getElementById('nozzle');
        const fpsCounter = document.getElementById('fpsCounter');

        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        let particles = [];
        let isSucking = false;
        let lastTime = performance.now();
        let fps = 0;

        function getRandomColor() {
            const letters = '0123456789ABCDEF';
            let color = '#';
            for (let i = 0; i < 6; i++) {
                color += letters[Math.floor(Math.random() * 16)];
            }
            return color;
        }

        function createParticles() {
            for (let i = 0; i < 100; i++) {
                particles.push({
                    x: Math.random() * canvas.width,
                    y: Math.random() * canvas.height,
                    radius: 5,
                    dx: (Math.random() - 0.5) * 2,
                    dy: (Math.random() - 0.5) * 2,
                    color: getRandomColor()
                });
            }
        }

        function drawParticles() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            particles.forEach((particle, index) => {
                ctx.beginPath();
                ctx.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2);
                ctx.fillStyle = particle.color;
                ctx.fill();

                // パーティクルの移動
                particle.x += particle.dx;
                particle.y += particle.dy;

                // パーティクルが画面外に出たら反転させる
                if (particle.x < 0 || particle.x > canvas.width) particle.dx *= -1;
                if (particle.y < 0 || particle.y > canvas.height) particle.dy *= -1;

                // 吸引機能
                if (isSucking) {
                    let dx = particle.x - (nozzle.offsetLeft + nozzle.offsetWidth / 2);
                    let dy = particle.y - (nozzle.offsetTop + nozzle.offsetHeight / 2);
                    let distance = Math.sqrt(dx * dx + dy * dy);

                    if (distance < 100) {
                        particle.dx = -dx / distance * 5;
                        particle.dy = -dy / distance * 5;

                        // ノズルに近づいたら吸い込む
                        if (distance < 20) {
                            particles.splice(index, 1);
                        }
                    }
                }
            });
        }

        function updateFPS() {
            const now = performance.now();
            fps = Math.round(1000 / (now - lastTime));
            lastTime = now;
            fpsCounter.textContent = `FPS: ${fps}`;
        }

        function animate() {
            drawParticles();
            updateFPS();
            requestAnimationFrame(animate);
        }

        createParticles();
        animate();

        // マウスの動きにノズルを追従させる
        document.addEventListener('mousemove', (e) => {
            nozzle.style.left = `${e.clientX - nozzle.offsetWidth / 2}px`;
            nozzle.style.top = `${e.clientY - nozzle.offsetHeight / 2}px`;
        });

        // スペースキーで吸引開始・停止
        document.addEventListener('keydown', (e) => {
            if (e.code === 'Space') {
                isSucking = true;
                nozzle.style.backgroundColor = getRandomColor();
            }
        });

        document.addEventListener('keyup', (e) => {
            if (e.code === 'Space') {
                isSucking = false;
            }
        });
    </script>
</body>
</html>

3
3
0

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
3
3