My background
I had no programming background, so I’m much slower than other people in our class when it came to understanding and applying the information from Sprint 2.
Memory
3.8 was generally about iteration, which is the process of repeating a set of instructions or operations. Iterations are usually carried out through the usage of loops, which repeat until a condition is fulfilled or it has been repeated a set amount of times. The lessons that I was in charge of were looping with an index, where the position of an item was stated, and Nested if Statements, where multiple conditions could be checked by placing if statements in other conditional statements.
Relevancy
From the other groups, 3.5, booleans were the most impactful to me. This was because it was easy to understand but also because I was able to connect that to Nested if statements, where I could directly set conditions with the booleans and check each condition.
Impact of Sprint 2
I think that Sprint 2 was overall a good learning process as it taught us to collaborate and approach the lesson with a clear plan. I think if we had the time in class to teach one topic and do one or two homework problems in class, I would have been able to more effectively learn and retain the information. While developing our portion of the lesson, I learned about pull requests, the importance of git pulling before saving and committing changes, and also the content in general.
I still think that I need further review of the lessons and Big Idea 3 in order to feel fully prepared for the AP CSP Exam, but overall I think I learned a lot about the topics that I needed to know and grew a lot as a collaborator and student.
#Javascript For Loops and Sprites ###https://nighthawkcoders.github.io/portfolio_2025/csse/javascript/fundamentals/for-loops/</body>
%%html
<h1>introduction to for loops</h1>
<!-- HTML output div -->
<div id="forConventional"></div>
<script>
var names = ['turtle', 'fish', 'frog', 'penguin'];
// Conventional for loop with index used to access elements
for (let i = 0; i < names.length; i++) {
// Create a p tag for each name and add it to the forConventional div
const p = document.createElement('p');
p.innerHTML = names[i];
document.getElementById('forConventional').appendChild(p);
}
</script>
introduction to for loops
%%html
<h1> ForEach Loop </h1>
<!-- HTML output div -->
<div id="forEach"></div>
<script>
var codingAdventures = ['GitHub', 'Terminal', 'Jupyter', 'JavaScript'];
// ForEach loop to iterate over the array
for (let adventure of codingAdventures) {
// Create a p tag for each adventure and add it to the forEach div
const p = document.createElement('p');
p.innerHTML = adventure;
document.getElementById('forEach').appendChild(p);
}
</script>
ForEach Loop
%%html
<h1>2D arrays</h1>
<div id="questionsAnswers"></div>
<script>
// 2D array of questions and answers with titles
var qaArray = [
[
'GitHub',
[
{ question: 'What is a repository?', answer: 'A repository is a storage space where your project lives.' },
{ question: 'How do you create a branch?', answer: 'You can create a branch by using the command git checkout -b branchName.' },
{ question: 'How do you merge branches?', answer: 'You can merge branches by using the command git merge branchName.' },
{ question: 'How do you push changes to GitHub?', answer: 'You can push changes to GitHub by using the command git push origin branchName.' }
]
],
[
'Terminal',
[
{ question: 'What is the command to list hidden files in a directory?', answer: 'The command to list files in a directory is ls -a.' },
{ question: 'What is the command to change directories?', answer: 'The command to change directories is cd.' },
{ question: 'What is the command to create a new directory?', answer: 'The command to create a new directory is mkdir.' },
{ question: 'What is the command to remove a directory?', answer: 'The command to remove a directory is rm -rf.' }
]
],
[
'Jupyter Notebook',
[
{ question: 'How do you setup a markdown cell?', answer: 'You setup a markdown cell by selecting the cell type dropdown and selecting markdown.' },
{ question: 'How do you setup a code cell?', answer: 'You setup a code cell by selecting the cell type dropdown and selecting code.' },
{ question: 'What kernel do you select to run JavaScript code?', answer: 'You select the Python kernel to run JavaScript code.' },
{ question: 'How do you see JavaScript console output?', answer: 'You see JavaScript console output by using the console.log() method.' }
]
],
[
'JavaScript',
[
{ question: 'What is JavaScript?', answer: 'JavaScript is a programming language that enables you to create interactive web pages.' },
{ question: 'What is a variable?', answer: 'A variable is a container that stores data.' },
{ question: 'What is a function?', answer: 'A function is a block of code that performs a specific task.' },
{ question: 'What is a loop?', answer: 'A loop is a programming structure that repeats a sequence of instructions.' }
]
]
];
// Nested for loops to display questions and answers with titles
for (let category of qaArray) {
// Create an h2 tag for each category title
const h2 = document.createElement('h2');
h2.innerHTML = category[0]; // index 0 is the title of the category
document.getElementById('questionsAnswers').appendChild(h2);
// Iterate through each question and answer in the category
for (let qa of category[1]) { // index 1 is the array of questions and answers
// Create a p tag for each question and answer
const p = document.createElement('p');
p.innerHTML = `<strong>Q:</strong> ${qa.question} <br> <strong>A:</strong> ${qa.answer}`;
document.getElementById('questionsAnswers').appendChild(p);
}
}
</script>
2D arrays
%%html
<h1>2D arrays</h1>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>2D Game with NPC Interaction</title>
<style>
#gameCanvas {
border: 2px solid black;
display: block;
margin: 20px auto;
}
h2 {
text-align: center;
}
#npcDialog {
text-align: center;
margin-top: 10px;
}
</style>
</head>
<body>
<h2>2D Game with NPC Interaction</h2>
<canvas id="gameCanvas" width="480" height="480"></canvas>
<div id="npcDialog"></div>
<script>
const TILE_SIZE = 48;
const GRID_WIDTH = 10;
const GRID_HEIGHT = 10;
// 2D array to represent the game grid
let gameMap = [
['P', '', '', '', '', '', '', '', '', 'NPC'],
['', '', '', '', '', '', '', '', '', ''],
['', '', '', '', '', '', '', '', '', ''],
['', '', '', '', '', '', '', '', '', ''],
['', '', '', '', '', '', '', '', '', ''],
['', '', '', '', '', '', '', '', '', ''],
['', '', '', '', '', '', '', '', '', ''],
['', '', '', '', '', '', '', '', '', ''],
['', '', '', '', '', '', '', '', '', ''],
['', '', '', '', '', '', '', '', '', ''],
];
// Player and NPC positions
let playerPos = { x: 0, y: 0 };
let npcPos = { x: 9, y: 0 };
// Get the canvas and context
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// Function to render the game grid
function renderGame() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas
for (let row = 0; row < GRID_HEIGHT; row++) {
for (let col = 0; col < GRID_WIDTH; col++) {
let x = col * TILE_SIZE;
let y = row * TILE_SIZE;
if (gameMap[row][col] === 'P') {
ctx.fillStyle = 'green'; // Player color
ctx.fillRect(x, y, TILE_SIZE, TILE_SIZE);
} else if (gameMap[row][col] === 'NPC') {
ctx.fillStyle = 'red'; // NPC color
ctx.fillRect(x, y, TILE_SIZE, TILE_SIZE);
} else {
ctx.strokeStyle = 'gray'; // Empty tile borders
ctx.strokeRect(x, y, TILE_SIZE, TILE_SIZE);
}
}
}
}
// Function to display NPC interaction
function npcInteraction() {
const dialog = document.getElementById('npcDialog');
dialog.innerHTML = "NPC: 'Hello, traveler! Welcome to our world.'";
}
// Handle player movement
window.addEventListener('keydown', function(event) {
gameMap[playerPos.y][playerPos.x] = ''; // Clear current player position
// Update player position based on arrow key
if (event.key === 'ArrowUp' && playerPos.y > 0) playerPos.y--;
if (event.key === 'ArrowDown' && playerPos.y < GRID_HEIGHT - 1) playerPos.y++;
if (event.key === 'ArrowLeft' && playerPos.x > 0) playerPos.x--;
if (event.key === 'ArrowRight' && playerPos.x < GRID_WIDTH - 1) playerPos.x++;
gameMap[playerPos.y][playerPos.x] = 'P'; // Set new player position
// Check for NPC interaction
if (playerPos.x === npcPos.x && playerPos.y === npcPos.y) {
npcInteraction();
} else {
document.getElementById('npcDialog').innerHTML = ''; // Clear dialog when not near NPC
}
renderGame(); // Re-render the game grid after moving
});
// Initial rendering of the game
renderGame();
</script>
</body>
</html>
2D arrays
2D Game with NPC Interaction
%%html
<h1>Display sprite file</h1>
<style>
#gameCanvas {
border: 4px solid rgb(102, 4, 4); /* Red border for the canvas */
}
</style>
<canvas id="gameCanvas" width="521" height="967"></canvas>
<script>
function defineAndDrawImage() {
/**
* Function to define the sprite metadata for Tux the penguin
* @returns {Object} spriteMetaData - The metadata for the Tux sprite
*/
function TuxSpriteMetaData() {
// NPC sprite data (Tux the penguin)
const spriteMetaData = {
name: 'tux',
src: "./tux.png",
};
return spriteMetaData;
}
/**
* Class to handle the canvas data and drawing of the image file
*/
class CanvasDrawImage {
constructor(spriteMetaData) {
this.INIT_POSITION = { x: 0, y: 0 };
this.spriteMetaData = spriteMetaData;
this.canvas = document.getElementById('gameCanvas');
this.ctx = this.canvas.getContext('2d');
this.spriteImage = new Image();
this.spriteImage.src = spriteMetaData.src;
this.spriteImage.onload = () => this.draw(); // Ensure draw is called after image is loaded
}
// Method to draw the sprite on the canvas
draw() {
// This is the size of the sprite file, calculated from the PNG file
const width = this.spriteImage.width;
const height = this.spriteImage.height;
console.log(`Drawing sprite: ${this.spriteMetaData.name}`);
console.log(`Sprite Dimensions: ${width}x${height}`);
this.ctx.drawImage(this.spriteImage, 0, 0, width, height);
}
}
const tux = new CanvasDrawImage(TuxSpriteMetaData());
}
// Call the function to define the class and draw the sprite
defineAndDrawImage();
</script>
Display sprite file
%%html
<h1>Display frames in sprite file</h1>
<style>
#gameCanvasUnique {
border: 4px solid rgb(4, 102, 33); /* Green border for the canvas */
}
</style>
<canvas id="gameCanvasUnique" width="521" height="967"></canvas>
<script>
// Outer function is required by Jupyter Notebook to avoid conflicts
function defineAndDrawSprite() {
/**
* Function to define the sprite metadata for Tux the penguin
* @returns {Object} spriteMetaData - The metadata for the Tux sprite
*/
function TuxSpriteMetaData() {
// NPC sprite data (Tux the penguin)
const spriteMetaData = {
name: 'tux',
src: "./tux.png",
orientation: {
rows: 10,
columns: 8,
header: 16,
pad: 2,
jagged: [1, 2, 1, 1, 1, 1, 1, 7, 8, 4]
},
};
return spriteMetaData;
}
/**
* Class to handle the canvas data and drawing of the sprite
*/
class CanvasData {
constructor(spriteMetaData) {
this.spriteMetaData = spriteMetaData;
this.INIT_POSITION = { x: 0, y: 0 };
this.canvas = document.getElementById('gameCanvasUnique');
this.ctx = this.canvas.getContext('2d');
this.spriteImage = new Image();
this.spriteImage.src = spriteMetaData.src;
this.spriteImage.onload = () => this.draw(); // Ensure draw is called after image is loaded
}
// Method to draw each sprite individually
draw() {
// This is the size of the sprite file, calculated from the PNG file
const sheetWidth = this.spriteImage.width;
const sheetHeight = this.spriteImage.height;
// This meta data describes the sprite sheet
const rows = this.spriteMetaData.orientation.rows;
const cols = this.spriteMetaData.orientation.columns;
const jagged = this.spriteMetaData.orientation.jagged || null;
const header = this.spriteMetaData.orientation.header || 0;
const pad = this.spriteMetaData.orientation.pad || 0;
// This is the initial output position on the canvas
const x = this.INIT_POSITION.x;
const y = this.INIT_POSITION.y;
// Calculate the dimensions of each individual sprite
const spriteWidth = sheetWidth / cols;
const spriteHeight = (sheetHeight - header * rows) / rows;
console.log(`Sprite Sheet Dimensions: ${sheetWidth}x${sheetHeight}`);
console.log(`Individual Sprite Dimensions: ${spriteWidth}x${spriteHeight}`);
console.log(`Rows: ${rows}, Columns: ${cols}`);
// Nested for loop to draw 2-dimensional sprite sheet
for (let row = 0; row < rows; row++) {
const columnsInRow = jagged ? jagged[row] || cols : cols;
for (let col = 0; col < columnsInRow; col++) {
const srcX = col * spriteWidth;
const srcY = row * (spriteHeight + header) - (pad * row);
const destX = x + col * spriteWidth;
const destY = y + row * spriteHeight;
const destWidth = spriteWidth;
const destHeight = spriteHeight;
console.log(`Drawing row: ${row}, column: ${col}`);
console.log(`Source: (${srcX}, ${srcY}, ${spriteWidth}, ${spriteHeight})`);
console.log(`Destination: (${destX}, ${destY}, ${destWidth}, ${destHeight})`);
this.ctx.drawImage(
this.spriteImage,
srcX, srcY + header, spriteWidth, spriteHeight, // Source rectangle
destX, destY, destWidth, destHeight // Destination rectangle
);
}
}
}
}
// Setup to Tux sprite
const tux = new CanvasData(TuxSpriteMetaData());
}
defineAndDrawSprite();
</script>
%%html
<style>
#gameCanvasUnique {
border: 4px solid rgb(4, 102, 33); /* Green border for the canvas */
}
</style>
<canvas id="gameCanvasUnique" width="521" height="967"></canvas>
<script>
// Outer function is required by Jupyter Notebook to avoid conflicts
function defineAndDrawSprite() {
/**
* Function to define the sprite metadata for Tux the penguin
* @returns {Object} spriteMetaData - The metadata for the Tux sprite
*/
function TuxSpriteMetaData() {
// NPC sprite data (Tux the penguin)
const spriteMetaData = {
name: 'tux', // Sprite identifier
src: "./tux.png", // Source file location
orientation: {
rows: 10, // Number of rows in the sprite sheet
columns: 8, // Number of columns
header: 16, // Header space above each sprite row
pad: 2, // Padding between sprites
jagged: [1, 2, 1, 1, 1, 1, 1, 7, 8, 4] // Jagged row data
},
};
return spriteMetaData;
}
/**
* Class to handle the canvas and sprite drawing
*/
class CanvasData {
constructor(spriteMetaData) {
this.spriteMetaData = spriteMetaData;
this.INIT_POSITION = { x: 0, y: 0 }; // Initial canvas position
this.canvas = document.getElementById('gameCanvasUnique'); // Get the canvas element
this.ctx = this.canvas.getContext('2d'); // Get 2D drawing context
this.spriteImage = new Image(); // Create a new image object for the sprite sheet
this.spriteImage.src = spriteMetaData.src; // Load the sprite sheet
this.spriteImage.onload = () => this.draw(); // Call draw() when image is loaded
}
// Method to draw the sprite sheet on the canvas
draw() {
// Dimensions of the full sprite sheet
const sheetWidth = this.spriteImage.width;
const sheetHeight = this.spriteImage.height;
// Extract orientation metadata
const rows = this.spriteMetaData.orientation.rows;
const cols = this.spriteMetaData.orientation.columns;
const jagged = this.spriteMetaData.orientation.jagged || null;
const header = this.spriteMetaData.orientation.header || 0;
const pad = this.spriteMetaData.orientation.pad || 0;
// Calculate individual sprite dimensions
const spriteWidth = sheetWidth / cols;
const spriteHeight = (sheetHeight - header * rows) / rows;
console.log(`Sprite Sheet Dimensions: ${sheetWidth}x${sheetHeight}`);
console.log(`Sprite Dimensions: ${spriteWidth}x${spriteHeight}`);
// Loop through the sprite sheet to extract and draw each sprite
for (let row = 0; row < rows; row++) {
// Handle jagged rows (some rows may have fewer columns)
const columnsInRow = jagged ? jagged[row] || cols : cols;
for (let col = 0; col < columnsInRow; col++) {
// Source coordinates from sprite sheet
const srcX = col * spriteWidth;
const srcY = row * (spriteHeight + header) - (pad * row);
// Destination coordinates on the canvas
const destX = this.INIT_POSITION.x + col * spriteWidth;
const destY = this.INIT_POSITION.y + row * spriteHeight;
console.log(`Drawing row: ${row}, column: ${col}`);
console.log(`Source: (${srcX}, ${srcY}, ${spriteWidth}, ${spriteHeight})`);
console.log(`Destination: (${destX}, ${destY}, ${spriteWidth}, ${spriteHeight})`);
// Draw the individual sprite onto the canvas
this.ctx.drawImage(
this.spriteImage,
srcX, srcY + header, spriteWidth, spriteHeight, // Source sprite from sheet
destX, destY, spriteWidth, spriteHeight // Destination on canvas
);
}
}
}
}
// Initialize the sprite and canvas drawing
const tux = new CanvasData(TuxSpriteMetaData());
}
// Call the function to define and draw the sprite
defineAndDrawSprite();
</script>