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; })”