Game Status: Not Started

CS111 Requirements

Section Name Description Evidence of Implementation
Object Oriented Programming (OOP)    
Writing Classes Create minimum 2 custom character classes extending base classes Writing Classes
Methods & Parameters Implement methods with parameters (e.g., collisionHandler(other, direction)) Methods & Parameters
Instantiation & Objects Instantiate game objects in GameLevel configuration Instantiation & Objects
Inheritance (Basic) Create class hierarchy with 2+ levels (e.g., GameObjectCharacterPlayer) Inheritance (Basic)
Method Overriding Override parent methods (update(), draw(), handleCollision()) Method Overriding
Constructor Chaining Use super() to chain constructors Constructor Chaining
Control Structures    
Iteration Use loops for game object arrays, animation frames Iteration
Conditionals Implement collision detection, state transitions Conditionals
Nested Conditions Complex game logic (e.g., power-up + collision + direction) Nested Conditions
Data Types    
Numbers Position, velocity, score tracking Numbers
Strings Character names, sprite paths, game states Strings
Booleans Flags (isJumping, isPaused, isVulnerable) Booleans
Arrays Game object collections, level data Arrays
Objects (JSON) Configuration objects, sprite data Objects (JSON)
Operators    
Mathematical Physics calculations (gravity, velocity, collision) Mathematical
String Operations Path concatenation, text display String Operations
Boolean Expressions Compound conditions in game logic Boolean Expressions
Input/Output (IO)    
Keyboard Input Arrow keys, space, WASD controls using event listeners Keyboard Input
Canvas Rendering Draw sprites, backgrounds, platforms using Canvas API Canvas Rendering
GameEnv Configuration Set canvas size, difficulty levels, game settings GameEnv Configuration
API Integration Implement Leaderboard API (POST/GET scores) API Integration
Asynchronous I/O Use async/await or promises for API calls Asynchronous I/O
JSON Parsing Parse API responses (leaderboard data, AI responses) JSON Parsing
Documentation    
Code Comments JSDoc comments for classes and methods Code Comments
Mini-Lesson Documentation Create comic/visual post with embedded runtime game demo Mini-Lesson Documentation
Code Highlights Annotate key code snippets in documentation (OOP, APIs, collision) Code Highlights
Debugging    
Console Debugging Use console.log() to track game state, variables, method calls Console Debugging
Hit Box Visualization Draw/visualize collision boundaries to refine detection Hit Box Visualization
Source-Level Debugging Set breakpoints in DevTools, step through code execution Source-Level Debugging
Network Debugging Examine Network tab for API calls, CORS errors, response status Network Debugging
Application Debugging Examine cookies, localStorage, session data for login/state Application Debugging
Element Inspection Use Element Viewer to inspect canvas, DOM elements, styles Element Inspection
Testing & Verification    
Gameplay Testing Test level completion, character interactions, collision detection Gameplay Testing
Integration Testing Test API integration (Leaderboard, NPC AI) with live backend Integration Testing
API Error Handling Try/catch blocks for API calls, network error handling API Error Handling

Each Programming Concept Demonstrated is shown below.

OOP Evidence

Writing Classes

Demonstrates creating custom classes like GameLevelFortress and UnifiedScythe to encapsulate game logic and behavior.

// GameLevelFortress.js - Main game level class
class GameLevelFortress {
    constructor(gameEnv) {
        this.gameEnv = gameEnv;
        this.scytheSpawnTimer = -300;
        this.scytheSpawnInterval = 120;
        // ... initialization code
    }
}

// UnifiedScythe.js - Enemy projectile class
class UnifiedScythe extends Enemy {
    constructor(gameEnv, type = 'regular', spawnX = null, spawnY = null) {
        const typeConfig = UnifiedScythe.getTypeConfig(type, path, width, spawnX, spawnY, gameEnv);
        super(scytheData, gameEnv);
        // ... scythe-specific initialization
    }
}

Methods & Parameters

Shows methods accepting parameters like findNearestScythe() and handleInterception(scythe) for targeted game logic.

// Interceptor.js - Methods with parameters for targeting
findNearestScythe() {
    const scythes = this.gameEnv.gameObjects.filter(obj => 
        obj.constructor.name === 'UnifiedScythe' && obj.scytheType === 'regular' && obj.canBeIntercepted()
    );
    // ... distance calculation logic
}

handleInterception(scythe) {
    this.hasIntercepted = true;
    this.revComplete = true;
    // ... interception logic with scythe parameter
}

Instantiation & Objects

Illustrates creating object instances dynamically in the game level configuration and during gameplay.

// GameLevelFortress.js - Creating object instances
constructor(gameEnv) {
    // Creating player instance
    this.classes = [
        { class: Player, data: sprite_data_mc },
        { class: Npc, data: sprite_data_helpful_npc },
        { class: Barrier, data: barrier_data }
    ];
    
    // Creating scythe instances dynamically
    const scythe = new UnifiedScythe(this.gameEnv, 'regular');
    this.gameEnv.gameObjects.push(scythe);
}

Inheritance (Basic)

Demonstrates class hierarchy with UnifiedScythe extends Enemy and Interceptor extends Character for code reuse.

// UnifiedScythe.js inherits from Enemy class
class UnifiedScythe extends Enemy {
    constructor(gameEnv, type = 'regular', spawnX = null, spawnY = null) {
        super(scytheData, gameEnv); // Calling parent constructor
        // ... child-specific initialization
    }
}

// Interceptor.js inherits from Character class
class Interceptor extends Character {
    constructor(gameEnv, spawnX, spawnY) {
        super({ id: 'interceptor' }, gameEnv);
        // ... interceptor-specific initialization
    }
}

Method Overriding

Shows overriding parent methods like update() to implement custom behavior in child classes.

// UnifiedScythe.js overrides parent update method
update() {
    if (this.revComplete) return;
    
    // Check lifespan for timed scythes
    if (this.lifespan && this.creationTime) {
        const currentTime = Date.now();
        if (currentTime - this.creationTime >= this.lifespan) {
            this.revComplete = true;
            this.destroy();
            return;
        }
    }
    
    // Custom motion update
    this.updateMotion();
    super.update(); // Call parent update
}

Constructor Chaining

Demonstrates using super() to chain constructors and initialize parent class properties.

// UnifiedScythe.js - Constructor chaining with super()
constructor(gameEnv, type = 'regular', spawnX = null, spawnY = null) {
    const scytheData = {
        id: `${type}_scythe_${Math.random().toString(36).substr(2, 9)}`,
        src: path + "/images/mansionGame/scythe.png",
        // ... configuration
    };
    
    super(scytheData, gameEnv); // Chain to parent constructor
    
    // Continue with child-specific initialization
    this.scytheType = type;
    this.setTypeFlags();
}

Control Structures

Iteration

Original evidence link: Iteration practice.

Conditionals

Original evidence link: Conditionals practice.

Nested Conditions

Original evidence link: Nested conditions practice.

Data Types

Numbers

Original evidence link: Numbers practice.

Strings

Original evidence link: Strings practice.

Booleans

Original evidence link: Booleans practice.

Arrays

Original evidence link: Arrays practice.

Objects (JSON)

Original evidence link: Objects JSON practice.

Operators

Mathematical

Original evidence link: Mathematical expressions practice.

String Operations

Original evidence link: String operations practice.

Boolean Expressions

Original evidence link: Boolean expressions practice.

IO Evidence

Keyboard Input

Shows event listener setup for keyboard controls like Space/I keys to fire interceptors.

// GameLevelFortress.js - Keyboard event handling
setupInterceptorControls() {
    this.boundFireInterceptor = this.fireInterceptor.bind(this);
    document.addEventListener('keydown', this.boundFireInterceptor);
}

fireInterceptor(event) {
    if ((event.code === 'Space' || event.keyCode === 32) ||
        (event.code === 'KeyI' || event.keyCode === 73)) {
        event.preventDefault();
        // Create interceptor at player position
        const interceptor = new Interceptor(this.gameEnv, spawnX, spawnY);
        this.gameEnv.gameObjects.push(interceptor);
    }
}

Canvas Rendering

Demonstrates Canvas API usage for drawing sprites with rotation, translation, and glow effects.

// UnifiedScythe.js - Canvas drawing with effects
draw() {
    this.canvas.width = this.width;
    this.canvas.height = this.height;
    
    this.ctx.save();
    this.ctx.translate(this.canvas.width / 2, this.canvas.height / 2);
    this.ctx.rotate(this.rotationAngle);
    
    // Add glow effects
    if (this.glowColor) {
        this.ctx.shadowColor = this.glowColor;
        this.ctx.shadowBlur = 40;
    }
    
    this.ctx.drawImage(this.spriteSheet, 0, 0, this.spriteSheet.naturalWidth, 
                     this.spriteSheet.naturalHeight, -this.width / 2, -this.height / 2, 
                     this.width, this.height);
    this.ctx.restore();
}

GameEnv Configuration

Shows configuring game environment settings like score configuration and stats initialization.

// GameLevelFortress.js - Environment setup
constructor(gameEnv) {
    let width = gameEnv.innerWidth;
    let height = gameEnv.innerHeight;
    let path = gameEnv.path;
    
    // Configure game environment
    this.gameEnv.scoreConfig = {
        counterVar: 'finalScore',
        counterLabel: 'Score',
        scoreVar: 'finalScore'
    };
    
    // Initialize scoring system
    this.gameEnv.stats = {
        scythesDestroyed: 0,
        survivalTime: 0,
        finalScore: 0,
        gameName: 'FortressGame'
    };
}

API Integration

Demonstrates extending the Coin class to integrate with the GameEngine’s leaderboard API system. As explained in the Asynchronous I/O section, API integration was used in our SpriteSheetCoin.js file, which extends the basic Coin class that was used as a very basic example of the game. The GameEngine implements specific POST and GET methods.

Example of POST method from GameEngine Leaderboard.js:

// POST to backend using API chaining pattern
fetch(
    url,
    {
        ...fetchOptions,
        method: 'POST',
        body: JSON.stringify(requestBody)
    }
)

Asynchronous I/O

Shows using promises and fetch API for asynchronous leaderboard data retrieval and error handling.

Asynchronous Input/Output enables programs to continue running while waiting for input such as requests to a server or file system.

The GameEngine (v1.1) uses asynchronous I/O for API calls to the backend server to implement leaderboard. We used this in our SpriteSheetCoin.js file, which extends the basic Coin class that was used as a very basic example of the game.

Our SpriteSheetCoin.js:

import Coin from '@assets/js/GameEnginev1.1/Coin.js';

// ...

class SpriteSheetCoin extends Coin {
    // ...
}

GameEngine Leaderboard.js:

fetch(`${javaURI}/api/events/SCORE_COUNTER`, fetchOptions)
    .then(res => {
        if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
        return res.json();
    })
    .then(data => {
        this.displayLeaderboard(data);
    })
    .catch(err => {
        console.error('Error fetching dynamic leaderboard:', err);
        // Check for authentication errors (401 or 403 status)
        if (err.message && (err.message.includes('401') || err.message.includes('403'))) {
            list.innerHTML = `<p class="error">Please login to access this feature.</p>`;
        } else {
            list.innerHTML = `<p class="error">Failed to load leaderboard</p>`;
        }
    });

JSON Parsing

Demonstrates parsing JSON data from localStorage and API responses for leaderboard management.

Like asyncrounous I/O, JSON parsing occours in the GameEngine with the leaderboard, and was used by us in SpriteSheetCoin.js. This is the one example of json parsing from the leaderboard:

this.deletedElementaryIds = new Set(
    JSON.parse(localStorage.getItem(this.deletedElementaryIdsStorageKey) || '[]')
        .map((v) => String(v))
);

Documentation Evidence

Code Comments

Shows JSDoc-style comments documenting classes, methods, and properties for code clarity.

/**
 * Represents the Fortress game level with all game objects and systems
 * @class GameLevelFortress
 */
class GameLevelFortress {
    /**
     * Constructs the Fortress game level with all game objects and systems
     * @param {Object} gameEnv - The game environment containing width, height, path, and other properties
     */
    constructor(gameEnv) {
        /**
         * Timer for scythe spawning - increments each frame
         * @type {number}
         */
        this.scytheSpawnTimer = -300;  // Delay the first spawn
        
        /**
         * Interval for scythe spawning (120 frames = 2 seconds at 60 FPS)
         * @type {number}
         */
        this.scytheSpawnInterval = 120;
    }
}

Mini-Lesson Documentation

Provides links to external mini-lesson documentation for spline barriers and platformer game mechanics.
Spline Barrier Mini-Lesson Documentation

Platformer Mini-Lesson Documentation

Code Highlights

Annotates key code snippets with inline comments to explain critical game logic and implementation details.

// Handle NPC collisions <-- I annotate a key part of my code here!
if (this.scytheType === 'regular') {
    this.checkNPCCollision();
} else {
    // Special+ scythes ignore NPC collisions
    this._hittingNPC = false;
}

Debugging Evidence

Console Debugging

Demonstrates using console.log, console.warn, and console.error to track game state and debug issues.

// GameLevelFortress.js - Console logging for debugging
console.log('Scythe destroyed! New score:', this.gameEnv.stats.finalScore);
console.log('Level completed! Final scores:', this.scores);
console.warn('Could not find level with onScytheDestroyed method');
console.error('Error creating DialogueSystem:', error);

// Interceptor.js - Debug logging
console.log('SuperScythe spawned at top of screen with 4 key!');
console.warn('No player found for interceptor firing');

Hit Box Visualization

Shows visual debugging of collision boundaries to ensure accurate hitbox detection for spline barriers. In this visualization, we’ve carefully crafted the hitboxes of spline barriers to ensure that they effectively block the correct areas. This visualization is crucial for debugging and ensures that our team maintains accurate and effective collision detection. Hit Box Visualization

Source-Level Debugging

Demonstrates using Chrome DevTools breakpoints and JavaScript console for step-through debugging. This is an image of my source level debugging, where I use the JavaScript console and add breakpoints into the source from the web page. Source-Level Debugging

Network Debugging

Shows examining network requests in Chrome DevTools to debug API calls and CORS issues. This is an image of my network debugging, where I use Chrome developer tools to look through the network requests of my site. Network Debugging

Application Debugging

Demonstrates inspecting localStorage and application state in Chrome DevTools for debugging. This is an image of my application debugging, where I use Chrome developer tools to look through the local storage of my site. Application Debugging

Element Inspection

Shows using Chrome DevTools element inspector to examine canvas elements and DOM structure. Here, I use the inspect on the Chrome developer tools to inspect the Knight’s canvas element. Element Inspection

Testing Evidence

Gameplay Testing

Demonstrates testing player-NPC interactions and resolving distance-based interaction bugs. Here in this image, I’m testing interactions between the player and the closet NPC. After there was a bug that caused this interaction to work from long distances. As you can see, I’ve resolved it! Gameplay Testing

Integration Testing

Shows testing leaderboard integration to verify score updates and API functionality. Here, I’m testing to make sure the leaderboard for game level fortress works. We can see the score updating! Integration Testing

API Error Handling

Demonstrates try/catch blocks and error handling for API calls in the GameEngine leaderboard system. As stated in the Asynchronous I/O section, we used SpriteSheetCoin.js for the leaderboard. This contained code that used the game engine code shown below, which has the API error handling.

GameEngine Leaderboard.js:

fetch(`${javaURI}/api/events/SCORE_COUNTER`, fetchOptions)
    .then(res => {
        if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
        return res.json();
    })
    .then(data => {
        this.displayLeaderboard(data);
    })
    .catch(err => {
        console.error('Error fetching dynamic leaderboard:', err);
        // Check for authentication errors (401 or 403 status)
        if (err.message && (err.message.includes('401') || err.message.includes('403'))) {
            list.innerHTML = `<p class="error">Please login to access this feature.</p>`;
        } else {
            list.innerHTML = `<p class="error">Failed to load leaderboard</p>`;
        }
    });

Code Runner

Basic Data Types Runner

Code Runner Challenge

Strings & Other Basic Data Types

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Basic Classes Runner

Code Runner Challenge

Classes & Methods Demonstrated

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...