Game Status: Not Started

CS111 Requirements

Section Name Description Evidence of Implementation
Object Oriented Programming (OOP)    
Writing Classes Creating class definitions to encapsulate data and behavior Writing Classes
Methods & Parameters Defining functions within classes that accept input parameters Methods & Parameters
Instantiation & Objects Creating instances of classes and working with object instances Instantiation & Objects
Inheritance (Basic) Creating subclasses that inherit properties and methods from parent classes Inheritance (Basic)
Method Overriding Redefining methods in subclasses to provide specific implementations Method Overriding
Constructor Chaining Calling parent class constructors from child class constructors Constructor Chaining
Control Structures    
Iteration Iterating through a list using loops Iteration
Conditionals Using if, else if, else statements Conditionals
Nested Conditions Using nested if-else statements Nested Conditions
Data Types    
Numbers Number can be used for positions, indexes, etc. Numbers
Strings Strings can be used for dialogue and paths Strings
Booleans Booleans can be used for conditions Booleans
Arrays Arrays can be used for lists Arrays
Objects (JSON) Objects can be used for data structures Objects (JSON)
Operators    
Mathematical Mathematical operators can be used for calculations Mathematical
String Operations String operators can be used for string manipulation String Operations
Boolean Expressions Boolean expressions can be used for conditions Boolean Expressions
Input/Output (IO)    
Keyboard Input Capturing user input from the keyboard Keyboard Input
Canvas Rendering Drawing graphics and animations on a canvas element Canvas Rendering
GameEnv Configuration Setting up game environment with configuration options GameEnv Configuration
API Integration Integrating external APIs for data or functionality  
Asynchronous I/O Handling asynchronous operations like API calls or timers Asynchronous I/O
JSON Parsing Parsing JSON data for configuration or data exchange JSON Parsing
Documentation    
Code Comments Adding comments to explain 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 Using console.log() and other debugging techniques to identify and fix issues Console Debugging
Hit Box Visualization Using visual debugging to understand collision detection  
Source-Level Debugging Using browser developer tools to step through code and inspect variables Source-Level Debugging
Network Debugging Using browser developer tools to inspect network requests and responses  
Application Debugging Using browser developer tools to inspect application state and behavior Application Debugging
Element Inspection Using browser developer tools to inspect HTML elements and their properties Element Inspection
Testing & Verification    
Gameplay Testing Testing game mechanics, controls, and overall user experience Gameplay Testing
Integration Testing Testing the interaction between different components of the game Integration Testing
API Error Handling Handling errors when integrating external APIs  

Each Programming Concept Demonstrated is shown below.

OOP Evidence

Writing Classes

// 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

// 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

// 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)

// 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

// 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

// 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();
}

IO Evidence

Keyboard Input

// 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

// 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

// 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'
    };
}

Asynchronous I/O

// GameLevelFortress.js - Async operations with timers and promises
initializeLeaderboard() {
    // Async score manager initialization
    this.gameEnv.initScoreManager().then(() => {
        console.log('Score manager initialized successfully');
        if (this.gameEnv.scoreManager) {
            this.gameEnv.scoreManager.toggleScoreDisplay();
        }
    }).catch(error => {
        console.warn('Failed to initialize score manager:', error);
    });
}

// Timer-based async operations
update() {
    this.gameTimer++;
    
    // Update survival time every 60 frames (1 second)
    if (this.gameTimer % 60 === 0) {
        this.updateSurvivalTime();
    }
}

JSON Parsing

// GameLevelFortress.js - JSON-like object configuration
const sprite_data_mc = {
    id: 'Knight',
    greeting: "Hi, I am a Knight.",
    src: sprite_src_mc,
    SCALE_FACTOR: MC_SCALE_FACTOR,
    STEP_FACTOR: 500,
    ANIMATION_RATE: 100,
    INIT_POSITION: { x: 0.5 * width, y: 0.8 * height },
    pixels: { height: 432, width: 234 },
    orientation: { rows: 4, columns: 3 },
    keypress: { up: 87, left: 65, down: 83, right: 68 }
};

Documentation Evidence

Code Comments

/**
 * 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

Spline Barrier Mini-Lesson Documentation

Platformer Mini-Lesson Documentation

Code Highlights

Key code snippets highlighted throughout the implementation:

  • OOP: Class inheritance with UnifiedScythe extends Enemy
  • Collision Detection: Distance-based collision algorithms
  • Event Handling: Keyboard and touch input processing
  • Animation: Canvas rendering with rotation and effects

Debugging Evidence

Console Debugging

// 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');

Source-Level Debugging

// GameLevelFortress.js - Error handling with try-catch
try {
    const audioElements = document.querySelectorAll('audio');
    audioElements.forEach(audio => {
        try { if (!audio.paused) audio.pause(); } catch (e) { }
    });
} catch (e) { /* ignore */ }

// UnifiedScythe.js - Conditional debugging
if (players.length === 0) {
    console.error("No player found in game environment");
    return { x: 0, y: 0 };
}

Application Debugging

// GameLevelFortress.js - State inspection
initializeScoring() {
    // Initialize stats object if it doesn't exist
    if (!this.gameEnv.stats) {
        this.gameEnv.stats = {};
    }
    
    // Set initial scores for debugging
    this.gameEnv.stats.scythesDestroyed = 0;
    this.gameEnv.stats.survivalTime = 0;
    this.gameEnv.stats.finalScore = 0;
}

// Interceptor.js - Runtime state checking
checkScytheInterception() {
    if (this.hasIntercepted) return; // Prevent duplicate interceptions
    
    // Debug: Check if scythes exist
    const scythes = this.gameEnv.gameObjects.filter(obj => 
        obj.constructor.name === 'UnifiedScythe' && obj.scytheType === 'regular'
    );
    
    if (scythes.length === 0) return; // No targets available
}

Element Inspection

// DialogueSystem.js - DOM element creation and inspection
createDialogueBox() {
    this.dialogueBox = document.createElement("div");
    this.dialogueBox.id = "custom-dialogue-box-" + this.id;
    
    // Set styles for inspection
    Object.assign(this.dialogueBox.style, {
        position: "absolute",
        bottom: "20px",
        left: "50%",
        zIndex: "9999",
        display: "none" // Initially hidden for debugging
    });
}

// GameLevelFortress.js - Element manipulation for debugging
createTimerDisplay() {
    this.timerElement = document.createElement('div');
    this.timerElement.id = 'game-timer';
    
    // Style for easy inspection in dev tools
    this.timerElement.style.position = 'absolute';
    this.timerElement.style.zIndex = '10000';
    this.timerElement.style.backgroundColor = 'rgba(0,0,0,0.5)';
}

Testing Evidence

Gameplay Testing

// GameLevelFortress.js - Gameplay mechanics testing
update() {
    // Test scythe spawning system
    this.scytheSpawnTimer++;
    if (this.scytheSpawnTimer >= this.scytheSpawnInterval) {
        const numScythes = Math.floor(Math.random() * MAX_SCYTHES) + 1;
        for (let i = 0; i < numScythes; i++) {
            this.spawnScythe(); // Test spawn functionality
        }
        this.scytheSpawnTimer = 0;
    }
}

// Test player collision detection
onLevelCompleted() {
    if (!this.levelCompleted) {
        this.levelCompleted = true;
        this.scores.completionTime = Math.floor((Date.now() - this.startTime) / 1000);
        console.log('Level completed! Final scores:', this.scores);
    }
}

Integration Testing

// Interceptor.js - Component integration testing
handleInterception(scythe) {
    // Test integration between interceptor and scythe
    const accuracy = 0.75; // 75% accuracy for testing
    const willHit = Math.random() < accuracy;
    
    if (willHit) {
        // Test successful integration
        this.createInterceptionEffect();
        scythe.destroy();
        
        // Test score system integration
        if (typeof window !== 'undefined' && window.currentGameLevel && 
            window.currentGameLevel.onScytheDestroyed) {
            window.currentGameLevel.onScytheDestroyed();
        }
    }
}

// GameLevelFortress.js - System integration testing
initializeScoring() {
    // Test integration between scoring and game environment
    this.gameEnv.scoreConfig = {
        counterVar: 'finalScore',
        counterLabel: 'Score',
        scoreVar: 'finalScore'
    };
    
    // Test integration with leaderboard
    this.gameEnv.initScoreManager().then(() => {
        console.log('Score manager initialized successfully');
    }).catch(error => {
        console.warn('Failed to initialize score manager:', error);
    });
}