(鳩の言い訳)

しょうもないものを作るなと思うかもしれないが、残像を残す描画をさせる方法を調べていたらできてしまったので仕方ない。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ももてぃにはちょっと失礼なサンプルプログラム</title>
<meta name = "viewport" content = "width=device-width, initial-scale = 1.0">
<style>
    body{
        background-color: black;
        color: #fff;
    }
    #container {
        width: 360px;
    }

    #field {
        position: relative;
        height: 320px;
    }
    #canvas1, #canvas2{
        position: absolute;
        left: 0px;
        top: 0px;
    }
    #canvas1 {
        z-index: 0;
    }
    #canvas2 {
        z-index: 1;
    }
    #sound {
        width: 160px;
        height: 50px;
        text-align: center;
    }
</style>
</head>

<body>
    <div id ="container">
        <div id ="field">
            <canvas id="canvas1"></canvas>
            <canvas id="canvas2"></canvas>
        </div>
        <button id = "sound">音を出す</button>
        <p>(鳩の言い訳)</p>
        <p>しょうもないものを作るなと思うかもしれないが、残像を残す描画をさせる方法を調べていたらできてしまったので仕方ない。</p>
    </div>

    <script>
        const $canvas1 = document.getElementById('canvas1');
        const $canvas2 = document.getElementById('canvas2');

        const ctx1 = $canvas1.getContext('2d');
        const ctx2 = $canvas2.getContext('2d');

        const image = new Image();
        image.src = './1111547.png';

        const CANVAS_WIDTH = 360;
        const CANVAS_HEIGHT = 300;

        let playSound = false;
        const sound = new Audio('./footsteps.mp3');

        let pig = null;

        class Pig{
            constructor(){
                this.X = CANVAS_WIDTH;
                this.Y = 160;
                this.BaseY = this.Y;
                this.UpdateCount = 0;
            }
            Update(){
                const oldSin = Math.sin(this.UpdateCount * 0.05);

                this.UpdateCount++;
                this.X--;
                const sin = Math.sin(this.UpdateCount * 0.05);
                if(sin < 0)
                    this.Y = this.BaseY + 100 * sin;
                else {
                    this.Y = this.BaseY;
                    if(oldSin < 0){
                        if(playSound)
                            sound.play();
                    }
                }
            }
        }

        function update(){
            pig.Update();
            if(pig.X < -100)
                pig.X = CANVAS_WIDTH;

            ctx1.fillStyle = 'rgba(0,0,0,0.04)';
            ctx1.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);

            ctx1.beginPath();
            ctx1.arc(pig.X + 32, pig.Y + 32, 24, 0, Math.PI*2);
            ctx1.fillStyle = '#f0f';
            ctx1.fill();

            ctx2.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
            ctx2.drawImage(image, pig.X, pig.Y, 64, 64);
            requestAnimationFrame(update);
        }

        window.onload = () => {
            pig = new Pig();

            $canvas1.width = CANVAS_WIDTH;
            $canvas1.height = CANVAS_HEIGHT;

            $canvas2.width = CANVAS_WIDTH;
            $canvas2.height = CANVAS_HEIGHT;

            document.getElementById('sound')?.addEventListener('click', () => {
                playSound = true;
            });
            update();
        }
    </script>

</body>
</html>