%%html

SPRITE
<body>
    <div id="controls"> <!--basic radio buttons which can be used to check whether each individual animaiton works -->
    </div>
    <div>
        <canvas id="spriteContainer"> <!-- Within the base div is a canvas. An HTML canvas is used only for graphics. It allows the user to access some basic functions related to the image created on the canvas (including animation) -->
            <img id="robotSprite" src="/sharedGame/images/sprite1.png">  <!-- Change sprite here -->
        </canvas>
    </div>
</body>

<script>
    const canvas = document.getElementById('spriteContainer');
    const ctx = canvas.getContext('2d');
    // start on page load
    window.addEventListener('load', function () {
        const SPRITE_WIDTH = 35;  // matches sprite pixel width
        const SPRITE_HEIGHT = 49; // matches sprite pixel height
        const FRAME_LIMIT = 7;  // matches number of frames per sprite row, this code assume each row is same

        const SCALE_FACTOR = 2;  // control size of sprite on canvas
        canvas.width = SPRITE_WIDTH * SCALE_FACTOR;
        canvas.height = SPRITE_HEIGHT * SCALE_FACTOR;

        // a class to store the differences in the animations to make it clear what the animation changes are for
        class AnimationType{
            constructor(initFrameX = 0, maxFrame = FRAME_LIMIT, animationDelay = 75){
                this.maxFrame = maxFrame;
                this.initFrameX = initFrameX;
                this.animationDelay = animationDelay;
            }
        }

        class Robot {
            constructor() {
                this.image = document.getElementById("robotSprite");
                this.x = 0;
                this.y = 0;
                this.minFrame = 0;
                this.animationType = new AnimationType();
                this.frameX = 0;
                this.frameY = 0;
            }

            // draw Robot object
            draw(context) {
                context.drawImage(
                    this.image,
                    this.frameX * SPRITE_WIDTH,
                    this.frameY * SPRITE_HEIGHT,
                    SPRITE_WIDTH,
                    SPRITE_HEIGHT,
                    this.x,
                    this.y,
                    canvas.width,
                    canvas.height
                );
            }

            // update frameX of object
            update() {
                // this sprite sheet uses a variable number of frames for different animations
                if (this.frameX < this.animationType.maxFrame) {
                    this.frameX++;
                } else {
                    // the start frame of the animations changes in this sprite sheet
                    this.frameX = this.animationType.initFrameX;
                }
            }
        }

        // Robot object
        const robot = new Robot();

        // Make the animations that deviate from the default use a class 
        // to make it more readible what the changes are doing
        const jumpRightAnimation = new AnimationType(undefined, 7, undefined); // frames go from 0 to 7 but everything else is the same
        const jumpLeftAnimation = new AnimationType(8, undefined, undefined); // frames go from 8 to 14 but everything else is the same

        // update frameY of robot object, action from radio controls
        document.addEventListener('keydown', function (event) {
            const key = event.key.toLowerCase();
            switch (key) {
                case 'w':
                    robot.frameY = 2; // Walk Right
                    robot.animationType = new AnimationType();
                    break;
                case 'a':
                    robot.frameY = 0; // Walk Left
                    robot.animationType = new AnimationType();
                    break;
                case 'd':
                    robot.frameY = 1; // Jump Right
                    robot.animationType = jumpRightAnimation;
                    break;
                case 's':
                    robot.frameY = 2; // Jump Left
                    robot.animationType = jumpLeftAnimation;
                    break;
                default:
                    break;
            }
        });

        // Animation recursive control function
        function animate() {
            // Clears the canvas to remove the previous frame.
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // Draws the current frame of the sprite.
            robot.draw(ctx);

            // Updates the `frameX` property to prepare for the next frame in the sprite sheet.
            robot.update();

            // Uses `requestAnimationFrame` to synchronize the animation loop with the display's refresh rate,
            // ensuring smooth visuals.
            requestAnimationFrame(function() {
                setTimeout(animate, robot.animationType.animationDelay); // Adjust the delay (in milliseconds) to control the frame rate.
            });
        }

        // run 1st animate
        animate();
    });
</script>

SPRITE