CS111 College Ready
CSSE topic-by-topic explanation of the Aquatic game level code.
CS111 College Ready
This notebook explains the code in Aquatic For Reference.js using CSSE topics like functions, arrays, booleans, conditionals, classes, constructors, methods, strings, data abstraction, math expressions, variables, and iteration.
Each section below connects one CSSE topic to a real code pattern from the Aquatic level file.
Before the topic-by-topic breakdown, the notebook now includes a small playable aquatic runner and a preview of the assets currently wired into the published site.
Interactive Rubric Dashboard
Interactive Rubric Dashboard
CS 111 Course Alignment Rubric
Required Evidence for College Credit
Students must demonstrate competency in all CS 111 learning objectives through their game project. Below is the alignment between CS 111 requirements and project deliverables, with evidence pulled from the Aquatic game level implementation.
| Learning Objective | Project Evidence Required | Assessment Method |
|---|---|---|
| Object-Oriented Programming | ||
| Writing Classes | Create minimum 2 custom character classes extending base classes. Evidence: class Player extends Character, class Npc extends Character, class Shark extends Enemy in assets/js/GameEnginev1/essentials/Player.js, assets/js/GameEnginev1/essentials/Npc.js, assets/js/GameEnginev1/Shark.js. |
Code review: class declarations and extends usage |
| Methods & Parameters | Implement methods with parameters. Evidence: applyPlayerDamage(damage, x, y, source) and applyMermaidBossDamage(damage, hitX, hitY) in assets/js/GameEnginev1/GameLevelAquaticGameLevel.js. |
Code review: method signatures with 2+ parameters |
| Instantiation & Objects | Instantiate game objects in level configuration/runtime. Evidence: const guardian = new Npc(guardianData, this.gameEnv); and this.gameEnv.gameObjects.push(guardian); in assets/js/GameEnginev1/GameLevelAquaticGameLevel.js. |
Code review: GameLevel setup and runtime object registration |
| Inheritance (Basic) | Create class hierarchy with 2+ levels. Evidence: GameObject -> Character -> Player and Character -> Npc -> Shark. |
Code review: inheritance chain and shared behavior |
| Method Overriding | Override parent methods (update(), interaction handling, behavior methods). Evidence: child entity update and interaction methods in player/NPC/enemy classes. |
Code review: polymorphic implementations |
| Constructor Chaining | Use super() to chain constructors. Evidence: super(data, gameEnv) patterns in entity constructors. |
Code review: super(data, gameEnv) calls |
| Control Structures | ||
| Iteration | Use loops for game object arrays and attack phases. Evidence: thresholds.forEach((threshold) => { ... }), update loops, projectile iteration. |
Code review: for, forEach, while |
| Conditionals | Implement collision checks and state transitions. Evidence: quest/boss transitions such as if (q1.completed && !q2.accepted) { ... }. |
Code review: if/else branches |
| Nested Conditions | Multi-stage combat logic. Evidence: if (state.phaseTwoUnlocked && now >= state.nextLaserAt && state.phaseThreeUnlocked) { ... }. |
Code review: multi-level conditional logic |
| Data Types | ||
| Numbers | Position, HP, cooldown, and timing tracking. Evidence: const hpRatio = this.bossState.hp / this.bossState.maxHp;. |
Code review: numeric properties and math usage |
| Strings | Character IDs, paths, and labels. Evidence: const aquaticSpriteStorageKey = 'aquatic_selected_sprite_v1';. |
Code review: string literals and concatenation/template usage |
| Booleans | Flags for active/completed states. Evidence: this.levelCompleted = false;, this.bossState.active = true;. |
Code review: boolean state transitions |
| Arrays | Game object collections and threshold lists. Evidence: const thresholds = [0.75, 0.5, 0.25];. |
Code review: array operations |
| Objects (JSON) | Config/state object literals. Evidence: const guardianData = { orientation: { ... }, attack: { ... } };. |
Code review: object literal structure |
| Operators | ||
| Mathematical | Physics/combat calculations. Evidence: this.bossState.maxHp * threshold, vector and distance calculations in attacks. |
Code review: +, -, *, / usage |
| String Operations | Path assembly and identifiers. Evidence: const backgroundAssetPath = path + '/images/gamebuilder/bg';. |
Code review: concatenation/template literals |
| Boolean Expressions | Compound game-state checks. Evidence: &&, ||, ! in phase gates and quest flow. |
Code review: compound conditions |
| Input/Output | ||
| Keyboard Input | WASD/keyboard mapping and handlers. Evidence: this.keypress = data?.keypress || { up: 87, left: 65, down: 83, right: 68 }; and keydown listeners. |
Testing: key event handlers respond correctly |
| Canvas Rendering | Draw/update lifecycle for entities. Evidence: update() { this.draw(); } and sprite rendering in character classes. |
Code review: render lifecycle methods |
| GameEnv Configuration | Canvas/runtime setup and class registration. Evidence: this.gameEnv.create(); and level constructor wiring. |
Code review: GameEnv setup + GameLevel init |
| API Integration | Fetch-based external communication. Evidence: await fetch(${this.game.javaURI}/bank/${personId}/npcProgress, this.fetchOptions);. |
Code review: fetch calls with error handling |
| Asynchronous I/O | Non-blocking runtime functions. Evidence: async handleMoodClick(mood) { const response = await fetch(...); }. |
Code review: async/await flow |
| JSON Parsing | Parse API payloads. Evidence: const result = await response.json();. |
Code review: response parsing and property access |
| Documentation | ||
| Code Comments | Intent comments in complex logic. Evidence: // Initialize touch controls for mobile devices. |
Code review: meaningful comment usage |
| Mini-Lesson Documentation | Notebook sections and rubric mapping for instruction. Evidence: this notebook’s rubric + objective sections. | Portfolio review: published mini-lesson |
| Code Highlights | Annotated snippets under each rubric objective. Evidence: objective-specific code blocks in this notebook. | Portfolio review: highlighted explanations |
| Debugging | ||
| Console Debugging | Runtime diagnostics. Evidence: console.warn('Unable to play aquatic boss theme', err);. |
Code review: strategic logging/warnings |
| Hit Box Visualization | Collision-distance validation. Evidence: if (hitDistance < 30) { applyPlayerDamage(...); }. |
Demo: collision boundary verification |
| Source-Level Debugging | Breakpoint-friendly state guards. Evidence: if (this.bossState.active || this.bossState.introPlayed) return;. |
Demo: stepping through flow in Sources |
| Network Debugging | Request status checks. Evidence: if (!response.ok) throw new Error('Failed to send mood');. |
Demo: inspect requests and responses |
| Application Debugging | Local/session state verification. Evidence: localStorage.setItem(...), sessionStorage.setItem(...). |
Demo: inspect storage state |
| Element Inspection | DOM/canvas inspection logic. Evidence: if (this.canvas?.parentNode) { this.canvas.parentNode.removeChild(this.canvas); }. |
Demo: inspect DOM/canvas lifecycle |
| Testing & Verification | ||
| Gameplay Testing | Validate quest/combat flow. Evidence: dialogue progression and boss-state transitions in Aquatic level scripts. | Live demo: complete flow without blockers |
| Integration Testing | Verify backend-connected paths. Evidence: await fetch(${this.game.javaURI}/createStats, { method: 'POST', body: JSON.stringify({ stats, gname, uid }) });. |
Demo: successful integrated requests |
| API Error Handling | Graceful failure handling. Evidence: try/catch around fetch with fallback status UI (this.showStatus('Network error', true);). |
Code review: explicit error handling |
1 — Object-Oriented Programming
1.1 Writing Classes
A class is a blueprint for creating objects. extends builds an inheritance chain so classes can reuse behavior. this.classes tells the engine what to create at startup.
Code Runner Challenge
OOP coverage for 1.1 to 1.6
View IPYNB Source
// Player class extends Character, so Player inherits movement/collision/sprite behavior.
class Player extends Character {
// Constructor runs when a new Player is created in the level class list.
constructor(data = null, gameEnv = null) {
// super(...) calls Character constructor first; required before using this.
super(data, gameEnv);
// Player identity in Aquatic (fallback if data.id is missing).
this.id = data?.id ?? 'player';
// Default WASD key mapping used by movement listeners.
this.keypress = data?.keypress || { up: 87, left: 65, down: 83, right: 68 };
// Tracks currently pressed keys for continuous movement.
this.pressedKeys = {};
}
}
// NPC class extends Character so it can share sprite and interaction lifecycle.
class Npc extends Character {
constructor(data = null, gameEnv = null) {
super(data, gameEnv);
}
}
// Shark class extends Enemy (Enemy extends Character), forming a multi-level chain.
class Shark extends Enemy {
constructor(data = null, gameEnv = null) {
super(data, gameEnv);
// Enemy-state flag used in collision/combat logic.
this.playerDestroyed = false;
}
}
// Aquatic level class: this.classes tells the engine exactly what objects to instantiate.
class GameLevelAquaticGameLevel {
constructor(gameEnv) {
this.gameEnv = gameEnv;
this.classes = [
{ class: GameEnvBackground, data: bgData },
{ class: Player, data: playerData },
{ class: Npc, data: mermaidNpc },
{ class: Npc, data: slimeNpc },
{ class: Npc, data: kirbyNpc },
{ class: Npc, data: sharkNpc }
];
}
}
1.2 Methods & Parameters
A method is a class function that uses this instance state. Parameters let one method handle many callers.
applyPlayerDamage(damage, x, y, source) {
if (!this.bossState.active) return;
// damage and hit position are parameter-driven
}
applyMermaidBossDamage(damage, hitX, hitY) {
if (!this.mermaidBossState.active) return;
// same logic shape, different target state
}
collisionChecks() {
for (const gameObj of this.gameEnv.gameObjects) {
if (gameObj instanceof Player) {
this.isCollision(gameObj);
if (this.collisionData.hit) return true;
}
}
return false;
}
1.3 Instantiation & Objects
Instantiation uses new ClassName(...) to create independent runtime objects. Aquatic level setup uses both class instances and object-literal configuration.
const guardianData = {
orientation: { rows: 6, columns: 6 },
attack: { row: 4, start: 0, columns: 5 }
};
const guardian = new Npc(guardianData, this.gameEnv);
this.gameEnv.gameObjects.push(guardian);
this.classes = [
{ class: GameEnvBackground, data: image_data_aquatic }
];
1.4 Inheritance
Inheritance lets child classes automatically use parent fields/methods without rewriting everything.
class GameObject {
constructor(gameEnv) {
this.gameEnv = gameEnv;
gameEnv.gameObjects.push(this);
}
}
class Character extends GameObject {
constructor(data = null, gameEnv = null) {
super(gameEnv);
this.velocity = { x: 0, y: 0 };
}
}
class Player extends Character {
constructor(data = null, gameEnv = null) {
super(data, gameEnv);
this.keypress = data?.keypress || { up: 87, left: 65, down: 83, right: 68 };
}
}
1.5 Method Overriding
Overriding happens when a child defines the same method name as a parent. super.methodName() keeps parent behavior and extends it.
update() {
super.update();
if (!this.playerDestroyed && this.collisionChecks()) {
this.handleCollisionEvent();
}
this.stayWithinCanvas();
}
handleCollisionReaction(other) {
const touchPoints = this.collisionData?.touchPoints?.this;
if (touchPoints?.top) this.velocity.y = Math.min(0, this.velocity.y);
if (touchPoints?.bottom) this.velocity.y = Math.max(0, this.velocity.y);
if (touchPoints?.left) this.velocity.x = Math.min(0, this.velocity.x);
if (touchPoints?.right) this.velocity.x = Math.max(0, this.velocity.x);
}
1.6 Constructor Chaining
super() in child constructors calls parent setup first. JavaScript requires this before using this.
constructor(data = null, gameEnv = null) {
super(data, gameEnv);
this.pressedKeys = {};
}
constructor(data = null, gameEnv = null) {
super(gameEnv);
this.canvas = document.createElement('canvas');
this.velocity = { x: 0, y: 0 };
}
constructor(gameEnv) {
this.gameEnv = gameEnv;
this.canvas = document.createElement('canvas');
gameEnv.gameObjects.push(this);
}
Use this section as the OOP evidence reference, then continue with the existing sections for Control Structures, Data Types, Operators, Input/Output, Documentation, Debugging, and Testing.
OOP Code Runners (1.1-1.6)
Run this cell to execute concrete mini-examples for all Object-Oriented Programming sub-lessons.
Code Runner Challenge
Practice #1 - Conditionals and Loops
View IPYNB Source
%%js
// CODE_RUNNER: OOP coverage for 1.1 to 1.6
// 1.4 Inheritance root
class GameObject {
constructor(gameEnv) {
this.gameEnv = gameEnv;
}
update() {
return 'base-update';
}
}
// 1.4 Inheritance middle + 1.6 constructor chaining
class Character extends GameObject {
constructor(data = null, gameEnv = null) {
super(gameEnv);
this.data = data || {};
this.velocity = { x: 0, y: 0 };
}
}
// 1.1 Writing classes + 1.6 constructor chaining
class Player extends Character {
constructor(data = null, gameEnv = null) {
super(data, gameEnv);
this.id = data?.id ?? 'player';
this.keypress = data?.keypress || { up: 87, left: 65, down: 83, right: 68 };
this.pressedKeys = {};
}
// 1.2 Methods and parameters
applyPlayerDamage(damage, source) {
this.hp = Math.max(0, (this.hp ?? 100) - damage);
return `Took ${damage} from ${source}. HP=${this.hp}`;
}
// 1.5 Method overriding
update() {
const parentResult = super.update();
return `${parentResult} -> player-update`;
}
}
// 1.3 Instantiation and objects
const gameEnv = { level: 'Aquatic Demo' };
const p1 = new Player({ id: 'aqua_hero' }, gameEnv);
console.log('1.1 class + extends:', p1 instanceof Player, p1 instanceof Character);
console.log('1.2 method params:', p1.applyPlayerDamage(25, 'rocket'));
console.log('1.3 instantiation:', p1.id, p1.keypress.left);
console.log('1.5 overriding:', p1.update());
console.log('1.6 constructor chaining gameEnv:', p1.gameEnv.level);
Runner: Category 6 (Documentation)
Use comments and clear section labels to document intent.
Code Runner Challenge
Practice #2 - Arrays, Objects, and Iteration
View IPYNB Source
%%js
// Category 6: Documentation runner
// This function demonstrates concise comments and explicit naming.
function formatRubricStatus(categoryName, completed, total) {
// Convert progress into percent for display.
const percent = Math.round((completed / total) * 100);
// Return a readable status string for lesson dashboards.
return `${categoryName}: ${completed}/${total} (${percent}%)`;
}
console.log(formatRubricStatus('Documentation', 3, 3));
Runner: Category 5 (Input/Output)
Simulate keyboard-style input and API-style async flow.
Code Runner Challenge
Practice #3 - Classes and Methods
View IPYNB Source
%%js
// Category 5: Input/Output runner
const keypress = { up: 87, left: 65, down: 83, right: 68 };
const pressed = [87, 68];
const direction = pressed.includes(keypress.up) && pressed.includes(keypress.right) ? 'upRight' : 'idle';
async function fakeApiSave(payload) {
// Simulate async request/response round trip.
return Promise.resolve({ ok: true, json: async () => ({ saved: true, payload }) });
}
const response = await fakeApiSave({ direction });
const result = await response.json();
console.log('Direction:', direction, '| API saved:', result.saved);
Runner: Category 4 (Operators)
Practice math, string, and boolean operators in one snippet.
%%js
// Category 4: Operators runner
const hp = 84;
const maxHp = 120;
const ratio = hp / maxHp; // mathematical operator
const label = `HP ratio: ${ratio}`; // string operation
const canCast = ratio <= 0.75 && hp > 0; // boolean expression
console.log(label);
console.log('Can cast ability:', canCast);
Runner: Category 3 (Data Types)
Use numbers, strings, booleans, arrays, and objects together.
%%js
// Category 3: Data types runner
const hp = 95; // number
const playerName = 'Aqua Hero'; // string
const isBossActive = true; // boolean
const thresholds = [0.75, 0.5, 0.25]; // array
const state = { hp, maxHp: 120, name: playerName }; // object
console.log(playerName, 'active?', isBossActive);
console.log('Threshold count:', thresholds.length);
console.log('HP ratio:', state.hp / state.maxHp);
Runner: Category 2 (Control Structures)
Practice iteration and nested conditions with boss phases.
%%js
// Category 2: Control structures runner
const thresholds = [0.75, 0.5, 0.25];
const state = { hp: 48, maxHp: 100, phaseTwoUnlocked: true, phaseThreeUnlocked: true, nextLaserAt: 10 };
const now = 20;
thresholds.forEach((threshold) => {
if (state.hp <= state.maxHp * threshold) {
console.log('Triggered threshold:', threshold);
}
});
if (state.phaseTwoUnlocked && now >= state.nextLaserAt && state.phaseThreeUnlocked) {
console.log('Nested condition passed: laser can start');
}
2 — Control Structures
2.1 Iteration
Code evidence (Aquatic):
// Each threshold represents a boss HP phase trigger (75%, 50%, 25%).
thresholds.forEach((threshold) => {
// Compare current HP to a percentage of max HP.
if (this.bossState.hp <= this.bossState.maxHp * threshold) {
// Spawn reinforcements when that phase is reached.
summonRushingSharks();
}
});
How this works in my Aquatic game:
- The loop checks each HP threshold (75%, 50%, 25%).
- When Megalodon HP drops below a threshold, shark reinforcements are spawned.
- This creates phase-based combat escalation.
2.2 Conditionals
Code evidence (Aquatic):
// Only show Quest 2 prompt after Quest 1 is complete.
if (q1.completed && !q2.accepted) {
// Dialogue branch advances story progression.
this.dialogueSystem.showDialogue('Will you take Aquatic Quest #2?', 'Slime', null);
}
How this works in my Aquatic game:
- The game only offers Quest 2 after Quest 1 is complete.
- It prevents showing wrong dialogue at the wrong time.
- This keeps quest progression logic consistent.
2.3 Nested Conditions
Code evidence (Aquatic):
// Laser requires: phase unlocked + cooldown reached + late-phase flag.
if (state.phaseTwoUnlocked && now >= state.nextLaserAt && state.phaseThreeUnlocked) {
// Start laser with configured charge duration.
startMermaidBossAbility('laser', state.laserChargeMs);
}
How this works in my Aquatic game:
- Mermaid laser requires multiple conditions at once: phase unlock + cooldown time.
- This prevents ability spam and preserves intended boss pacing.
3 — Data Types
3.1 Numbers
Code evidence (Aquatic):
// Convert absolute HP into a ratio so behavior can scale by percent.
// Example: 50/100 = 0.5, which can unlock mid-fight phase logic.
const hpRatio = this.bossState.hp / this.bossState.maxHp;
How this works in my Aquatic game:
- Converts boss health into a ratio for phase checks and UI decisions.
- Allows behavior to scale by percent, not hardcoded HP only.
3.2 Strings
Code evidence (Aquatic):
// Storage key name used for persisting selected player sprite.
// This exact key is reused when writing and reading localStorage values.
const aquaticSpriteStorageKey = 'aquatic_selected_sprite_v1';
How this works in my Aquatic game:
- This string is the storage key used to remember selected player sprite.
- Keeps player customization persistent across sessions.
3.3 Booleans
Code evidence (Aquatic):
// Menu starts hidden when gameplay begins.
this.frontMenuActive = false;
// Boss logic gates open once encounter is activated.
// Many attack/update branches check this flag before running.
this.bossState.active = true;
How this works in my Aquatic game:
frontMenuActivetoggles menu state.bossState.activeenables boss combat logic only when encounter starts.
3.4 Arrays
Code evidence (Aquatic):
// Array of selectable character presets for the Aquatic level.
// Each object stores a stable key (used by logic) and a label (used by UI text).
const aquaticSpriteOptions = [
{ key: 'scuba-diver', label: 'Scuba Diver' },
{ key: 'boy', label: 'Boy' }
];
How this works in my Aquatic game:
- Stores available character choices in one data structure.
- UI can render options and switch sprites from this list.
3.5 Objects (JSON)
Code evidence (Aquatic):
// Object literal groups guardian animation configuration.
// Nested fields let renderer/animation code read structured data by action name.
const guardianData = {
orientation: { rows: 6, columns: 6 },
attack: { row: 4, start: 0, columns: 5 }
};
How this works in my Aquatic game:
- Groups sprite/animation config for a guardian NPC.
- Makes NPC setup data-driven rather than hardcoding values across methods.
4 — Operators
4.1 Mathematical Operators
Code evidence (Aquatic):
// Multiply max HP by threshold to compute phase breakpoint.
// If max HP is 200 and threshold is 0.5, trigger point becomes 100 HP.
if (this.bossState.hp <= this.bossState.maxHp * threshold) {
summonRushingSharks();
}
How this works in my Aquatic game:
- Multiplies max HP by threshold to compute trigger points.
- Uses
<=to activate phase actions when HP reaches that level.
4.2 String Operations
Code evidence (Aquatic):
// Build sprite path using string concatenation.
// This keeps file paths dynamic across local and deployed environments.
const spriteAssetPath = path + '/images/gamebuilder/sprites';
// Build unique collectible id using template literal.
// i changes each loop, so IDs become starfish_0, starfish_1, etc.
const itemId = `starfish_${i}`;
How this works in my Aquatic game:
- Concatenation builds asset folder paths.
- Template literals generate unique collectible IDs.
4.3 Boolean Expressions
Code evidence (Aquatic):
// Compound condition ensures laser can run only in valid phase/timing state.
// All three checks must be true for this branch to execute.
if (state.phaseTwoUnlocked && now >= state.nextLaserAt && state.phaseThreeUnlocked) {
startMermaidBossAbility('laser', state.laserChargeMs);
}
How this works in my Aquatic game:
- Compound boolean logic ensures ability fires only in valid game state.
- Reduces bugs from partial or premature phase triggers.
5 — Input/Output
5.1 Keyboard Input
Code evidence (Aquatic):
// Default WASD controls used when custom key data is absent.
// 87=W (up), 65=A (left), 83=S (down), 68=D (right).
this.keypress = data?.keypress || { up: 87, left: 65, down: 83, right: 68 };
// Keydown listener routes keyboard input into movement logic.
// bind(this) preserves class context inside handleKeyDown.
addEventListener('keydown', this.handleKeyDown.bind(this));
How this works in my Aquatic game:
- Maps WASD keycodes to movement directions.
- Listener captures real-time key presses for player control.
5.2 Canvas Rendering
Code evidence (Aquatic):
update() {
// Draw is called each frame through the update lifecycle.
// This keeps sprite position/animation synced with current state.
this.draw();
}
How this works in my Aquatic game:
- Every frame calls draw through update lifecycle.
- Keeps character and boss visuals synced with game state.
5.3 GameEnv Configuration
Code evidence (Aquatic):
// Create initializes game canvas/context and runtime object systems.
// This is the startup handoff that makes the scene render and update.
this.gameEnv.create();
How this works in my Aquatic game:
- Initializes runtime environment, canvas, and object loop.
- Without this call, gameplay rendering and updates cannot start.
5.4 API Integration
Code evidence (Aquatic):
// Fetch backend NPC progress tied to current person/player id.
// fetchOptions usually includes method, headers, and auth/session context.
const response = await fetch(`${this.game.javaURI}/bank/${personId}/npcProgress`, this.fetchOptions);
How this works in my Aquatic game:
- Sends/reads backend progress data tied to player profile.
- Connects in-game actions with persistent external systems.
5.5 Asynchronous I/O
Code evidence (Aquatic):
// Async handler keeps UI responsive while POST request completes.
// await pauses this function only, not the entire render/game loop.
async handleMoodClick(mood) {
const response = await fetch(this.endpoint, { method: 'POST' });
}
How this works in my Aquatic game:
- Prevents UI/game loop blocking during network requests.
- Allows responses to be handled after request completion.
5.6 JSON Parsing
Code evidence (Aquatic):
// Parse JSON payload into JavaScript object for game logic use.
// After parsing, fields like result.success or result.stats can be read safely.
const result = await response.json();
How this works in my Aquatic game:
- Converts backend response payload into usable JS object data.
- Enables quest/mood/progress logic to read structured fields.
6 — Documentation
6.1 Code Comments
Code evidence (Aquatic):
// Initialize touch controls for mobile devices.
// This gives phone/tablet players on-screen movement and interaction inputs.
this.touchControls = new TouchControls(gameEnv, this.touchOptions);
How this works in my Aquatic game:
- Comment explains why touch controls are created here.
- Helps reviewers quickly understand mobile input design.
6.2 Mini-Lesson Documentation
Code evidence (Aquatic notebook):
## CS 111 Course Alignment Rubric
### Required Evidence for College Credit
How this works in my Aquatic game portfolio:
- Organizes evidence in rubric order for grading.
- Connects gameplay code to CS111 objectives clearly.
6.3 Code Highlights
Code evidence (Aquatic):
// Create boss NPC instance from configured boss data.
// This line proves class-based object creation in a real combat flow.
const boss = new Npc(bossData, this.gameEnv);
// Register boss in game object list so update/draw loop processes it.
// Without push, boss would exist but never be updated or rendered by engine loop.
this.gameEnv.gameObjects.push(boss);
How this works in my Aquatic game:
- Highlighted snippet proves instantiation + runtime registration.
- Shows exactly where boss entities enter the update/draw pipeline.
Each topic is now separated with one focused code evidence block, inline comments, and one direct Aquatic-specific explanation.
Topic Index
Use this plain index instead of teleport buttons.
- Functions
- Arrays
- Booleans
- Conditionals
- Classes
- Constructors
- Methods
- Strings
- Data Abstraction
- Mathematical Expressions
- Variables
- Iteration
- Project Checklist Integration
- Megalodon Boss Explanation
- Code Breakdown
Project Checklist
| Learning Objective | Related Notes | Project Evidence Required | Assessment Method | ||
|---|---|---|---|---|---|
| Writing Classes | Classes | Create minimum 2 custom character classes extending base classes | Code review: Player.js, Npc.js, Enemy.js | ||
| Methods & Parameters | Methods | Implement methods with parameters | Code review: methods with 2+ parameters | ||
| Instantiation & Objects | Data Abstraction | Instantiate game objects in level config | Code review: GameLevel setup objects | ||
| Inheritance (Basic) | Classes | Use class hierarchy (GameObject -> Character -> Player) | Code review: extends chain | ||
| Method Overriding | Methods | Override parent methods like update and draw | Code review: polymorphic implementations | ||
| Constructor Chaining | Constructors | Use super() in subclass constructors | Code review: super(data, gameEnv) calls | ||
| Iteration | Iteration | Use loops for arrays and animation | Code review: for, forEach, while | ||
| Conditionals | Conditionals | Use if else logic for state transitions | Code review: nested conditions | ||
| Numbers | Mathematical Expressions | Track position, velocity, score | Code review: numeric properties | ||
| Strings | Strings | Use names, paths, and dialogue strings | Code review: string operations | ||
| Booleans | Booleans | Use flags for game state | Code review: boolean logic | ||
| Arrays | Arrays | Use arrays for objects and level data | Code review: array operations | ||
| Objects (JSON) | Data Abstraction | Use object literals for config/state | Code review: object structures | ||
| Mathematical Operators | Mathematical Expressions | Use + - * / for gameplay math | Code review: arithmetic in logic | ||
| Boolean Expressions | Booleans | Use &&, | , ! in logic | Code review: compound conditions | |
| Keyboard Input | Functions | Implement WASD or arrow controls | Testing: key handlers work | ||
| Canvas Rendering | Classes | Draw sprites/backgrounds with canvas | Code review: draw methods | ||
| GameEnv Configuration | Variables | Configure canvas and game settings | Code review: GameEnv.create | ||
| Async I/O | Methods | Use async and await for runtime flows | Code review: async methods | ||
| JSON Parsing | Data Abstraction | Parse structured data payloads | Code review: JSON.parse and object access | ||
| Debugging | Code Breakdown | Use console logs, inspect state, tune hitboxes | Demo: stable gameplay loop |
| Jump to Code Breakdown | Jump to Megalodon Boss Section | Jump to Checklist Integration Layer | Jump to Full Evidence Rubric |
Code Practice Runners
Use the runnable examples below to practice core CS111 patterns.
Practice 1: Conditionals and Thresholds
Test phase checks with loops and if-statements.
%%js
// CODE_RUNNER: Practice #1 - Conditionals and Loops
const bossHp = 46;
const maxHp = 100;
const thresholds = [0.75, 0.5, 0.25];
thresholds.forEach((t) => {
if (bossHp <= maxHp * t) {
console.log(`Threshold triggered at ${t * 100}%`);
}
});
Practice 2: Arrays and Objects
Loop through item data and compute score totals.
%%js
// CODE_RUNNER: Practice #2 - Arrays, Objects, and Iteration
const starfish = [
{ id: 'starfish_0', points: 5 },
{ id: 'starfish_1', points: 10 },
{ id: 'starfish_2', points: 15 }
];
let total = 0;
starfish.forEach((item) => {
total += item.points;
});
console.log('Collected:', starfish.map((s) => s.id).join(', '));
console.log('Total points:', total);
Practice 3: Classes and Methods
Create an object, call methods, and watch state updates.
%%js
// CODE_RUNNER: Practice #3 - Classes and Methods
class MiniPlayer {
constructor(name, hp = 100) {
this.name = name;
this.hp = hp;
}
takeDamage(amount) {
this.hp = Math.max(0, this.hp - amount);
return this.hp;
}
}
const diver = new MiniPlayer('Aqua Hero', 120);
console.log('Start HP:', diver.hp);
console.log('After 25 damage:', diver.takeDamage(25));
console.log('After 200 damage:', diver.takeDamage(200));