Iteration

Iteration refers to the process of repeating a set of instructions or operations in a sequence. It is commonly used in loops to execute a block of code multiple times until a certain condition is met. Iterations are fundamental in programming as they allow for the efficient execution of repetitive tasks.

Example:

Below is a snippet from my Jungle Level file showing some use of iteration

handleLumberjackQuiz(event) {
    if (event.key === 'e' || event.key === 'u') {
        // Find the lumberjack object from the list of objects
        const lumberjack = this.objects.find(obj => obj.data.id === 'Lumberjack');
        // Find the tree instance from GameEnv.gameObjects
        const tree = GameEnv.gameObjects.find(obj => obj instanceof Tree);
        
        if (lumberjack && tree) {
            // Get the quiz question from the lumberjack's data
            const question = lumberjack.data.quiz.questions[0];
            // Prompt the player with the quiz question and get their answer
            const answer = prompt(`${lumberjack.data.quiz.title}\n${question}`);
            if (answer === '1') {
                // If the player answers "1", chop the tree
                alert("The tree was chopped down!");
                tree.chopTree();  // Call chopTree on the actual tree instance
            } else if (answer === '2') {
                // If the player answers "2", do not chop the tree
                alert("The tree was not chopped down.");
            } else {
                // If the player provides an invalid response, show an error message
                alert("Invalid response. Please answer with 1 or 2.");
            }
        }
    }
}

Explanation

Here, the find method is used to iterate through the this.objects array to find the lumberjack object and through the GameEnv.gameObjects array to find the tree instance. (Third and Fourth line)

Conditions

Conditions are used to perform different actions based on whether a specified condition is true or false. They are essential for controlling the flow of a program and making decisions. Conditional statements include if, else if, and else.

Example: I used a lot of conditions in my code, one instance is in my Tree class to handle the tree chopping and drawing.

class Tree extends Character {
    constructor(data) {
        super(data);
        
        // Basic properties
        this.isChopped = false;
        this.frameIndex = 0;
        this.frameCounter = 0;
        this.spriteData = data;
    }

    // Handle tree chopping
    chopTree() {
        if (!this.isChopped) {
            this.isChopped = true;
            this.frameIndex = 0;
            this.frameCounter = 0;
            
            // Hide idle canvas and show chop canvas
            this.idleCanvas.style.display = 'none';
            this.chopCanvas.style.display = 'block';
        }
    }

    // Draw the tree
    draw() {
        if (this.spriteSheet && this.spriteSheet.complete) {
            const frameWidth = this.spriteData.pixels.width / this.spriteData.orientation.columns;
            const frameHeight = this.spriteData.pixels.height / this.spriteData.orientation.rows;

            // Get animation data
            const animationData = this.isChopped ? this.spriteData.chop : this.spriteData.idle;
            
            // Calculate position in sprite sheet
            const frameX = (animationData.start + this.frameIndex) * frameWidth;
            const frameY = animationData.row * frameHeight;

            // Clear and draw on appropriate canvas
            const currentCanvas = this.isChopped ? this.chopCanvas : this.idleCanvas;
            const currentCtx = this.isChopped ? this.chopCtx : this.ctx;
            
            currentCtx.clearRect(0, 0, currentCanvas.width, currentCanvas.height);
            currentCtx.drawImage(
                this.spriteSheet,
                frameX, frameY, frameWidth, frameHeight,
                0, 0, currentCanvas.width, currentCanvas.height
            );

            // Update animation frame based on animation rate from sprite data
            this.frameCounter++;
            if (this.frameCounter >= this.spriteData.ANIMATION_RATE) {
                if (this.isChopped) {
                    this.frameIndex = Math.min(this.frameIndex + 1, animationData.columns - 1);
                } else {
                    this.frameIndex = (this.frameIndex + 1) % animationData.columns;
                }
                this.frameCounter = 0;
            }
        }
    }

    update() {
        this.draw();
    }
}

export default Tree;

Explanation

“if (!this.isChopped)” is an example which is checking if the Tree is chopped. Another example of conditions in the Tree.js file is “if (this.spriteSheet && this.spriteSheet.complete)”

Nested Conditions

Nested conditions involve placing one conditional statement inside another. This allows for more complex decision-making processes by evaluating multiple conditions in a hierarchical manner. Nested conditions are useful for handling scenarios where multiple criteria need to be checked.

Example:

The tree class also uses Nested conditionals to update the tree’s animation. Here is an example:

draw() {
    if (this.spriteSheet && this.spriteSheet.complete) {
        const frameWidth = this.spriteData.pixels.width / this.spriteData.orientation.columns;
        const frameHeight = this.spriteData.pixels.height / this.spriteData.orientation.rows;

        // Get animation data
        const animationData = this.isChopped ? this.spriteData.chop : this.spriteData.idle;
        
        // Calculate position in sprite sheet
        const frameX = (animationData.start + this.frameIndex) * frameWidth;
        const frameY = animationData.row * frameHeight;

        // Clear and draw on appropriate canvas
        const currentCanvas = this.isChopped ? this.chopCanvas : this.idleCanvas;
        const currentCtx = this.isChopped ? this.chopCtx : this.ctx;
        
        currentCtx.clearRect(0, 0, currentCanvas.width, currentCanvas.height);
        currentCtx.drawImage(
            this.spriteSheet,
            frameX, frameY, frameWidth, frameHeight,
            0, 0, currentCanvas.width, currentCanvas.height
        );

        // Update animation frame based on animation rate from sprite data
        this.frameCounter++;
        if (this.frameCounter >= this.spriteData.ANIMATION_RATE) {
            if (this.isChopped) {
                this.frameIndex = Math.min(this.frameIndex + 1, animationData.columns - 1);
            } else {
                this.frameIndex = (this.frameIndex + 1) % animationData.columns;
            }
            this.frameCounter = 0;
        }
    }
}

Explanation

The outer if statement checks if the frameCounter reached the animation rate: “if (this.frameCounter >= this.spriteData.ANIMATION_RATE)”. The inner statement checks if the tree is chopped:(“if (this.isChopped) { this.frameIndex = Math.min(this.frameIndex + 1, animationData.columns - 1); } else { this.frameIndex = (this.frameIndex + 1) % animationData.columns; })”