Sprint View

OOP

5 min read

OOP

Table of Contents

Core Topics

Core Building Blocks

  • Classes:Blueprints or templates that define the data and behavior (methods) for a specific type of object.
  • Objects: Specific instances created from a class. For example, if “Car” is the class, “My Toyota” is a specific object.
  • Attributes: The data or state of an object (e.g., a car’s color or model).
  • Methods: Functions defined within a class that describe the actions an object can perform (e.g., “drive” or “brake”).

Writing Classes

Writing Classes, involves creating reusable blueprints that define the unique properties and behaviors of game entities.

//Enemy Example

class Enemy extends Character {
    constructor(data = null, gameEnv = null) {
        super(data, gameEnv);
        this.playerDestroyed = false; // Tracks if the player has been "killed"
    }
//Npc example
class Npc extends Character {
    constructor(data = null, gameEnv = null) {
        super(data, gameEnv);
        this.interact = data?.interact; // Interact function
        this.currentQuestionIndex = 0;
        this.alertTimeout = null;
        this.isInteracting = false; // Flag to track if currently interacting
        this.handleKeyDownBound = this.handleKeyDown.bind(this);
        this.handleKeyUpBound = this.handleKeyUp.bind(this);
        this.bindInteractKeyListeners();

Methods and Parameters

Methods and parameters allow you to define specific actions for your objects and pass in unique data to customize how those actions are performed.

Example - In this example, the handleCollision method uses parameters (other and direction) to determine if the NPC should start an interaction based on which game object it touched.

// A method within the Npc class
handleCollision(other, direction) {

    if (this.interact && direction === "side") {
        this.isInteracting = true; 
        this.interact(other);      
        console.log("NPC interaction started with: " + other.id);
    }
}

Instantiation

instantiation is the process of creating a concrete, usable instance (an object) from an abstract template called a class.

for (let gameObjectClass of this.gameObjectClasses) {
    if (!gameObjectClass.data) gameObjectClass.data = {}
    // THIS IS INSTANTIATION
    let gameObject = new gameObjectClass.class(gameObjectClass.data, this.gameEnv)
    this.gameEnv.gameObjects.push(gameObject)
}

Explanation - This loop iterates through an array of class references and their specific configuration data. Within the loop, it uses the new keyword to allocate memory for a unique instance of that class (Instantiation) and then stores that active object in a global array so the game engine can manage its movement and logic.

Inheritence

Inheritance is the mechanism where a child class (like Npc or Enemy) automatically gains all the logic and attributes of a parent class (like Character). By using the extends keyword, you ensure that every specialized character in your game starts with the same foundational physics and movement rules without needing to rewrite that code for every new file.

Code Runner Challenge

Inheritance

View IPYNB Source
%%js 

// CODE_RUNNER: Inheritance

class Character {
    constructor(data, gameEnv) {
        this.x = data.x;
        this.y = data.y;
        this.velocity = { x: 0, y: 0 };
        this.gameEnv = gameEnv;
    }
}

class Player extends Character {
    constructor(data, gameEnv) {
        super(data, gameEnv); // Variables are passed from Parent to Child here
        
        // This log proves 'x', 'y', and 'velocity' exist in the Player instance
        console.log("Variables preserved from Parent:", this.x, this.y, this.velocity);
        
        this.health = 100;
    }
}

// Testing the preservation
const data = { x: 100, y: 200 };
const myPlayer = new Player(data, "Game Environment");
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Explanation - The code uses inheritance by using the extends keyword to link the Player to the Character. This creates a direct connection where the Player starts with all the variables such as gravity. The health variable is only for the player because it is only defined in the player class and not in the character class.

Method Overiding

Method Overriding is when a child class changes or adds to a behavior it inherited from its parent. While inheritance gives the child the parent’s “tools,” overriding allows the child to use those tools in a custom way.

Code Runner Challenge

Method Overidinga

View IPYNB Source
%%js

//CODE_RUNNER: Method Overidinga

// Classes with unique overrides
class Player extends Character {
    update() {
        console.log("Running Player input logic...");
    }
}

class Enemy extends Character {
    update() {
        console.log("Running Enemy AI logic...");
    }
}

// Polymorphic implementation
const gameObjects = [new Player(), new Enemy()];

gameObjects.forEach(obj => {
    obj.update(); 
});
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...
  1. The Collection: I store different subclasses (Player and Enemy) in one single array called gameObjects.

  2. The Single Command: I use one loop to call .update() on everything in that list, treating them all as generic “objects.”

  3. The Polymorphic Result: Even though the command is the same, the Player runs its input code and the Enemy runs its AI code because the computer automatically finds the unique version of update I wrote for each class.

Constrctor Chaining

Constructor Chaining is the process of calling one constructor from another within a hierarchy of classes.

class Character {
    constructor(data, gameEnv) {
        this.x = data.x;
        this.y = data.y;
        this.gameEnv = gameEnv;
    }
}

class Player extends Character {
    constructor(data, gameEnv) {
        super(data, gameEnv); 
        this.health = 100;
    }
}

The Bridge: The super() call acts as a bridge, passing the spawn data and game environment from the Player up to the Character class.

The Initialization: This ensures that the parent class initializes the position and world settings before the Player class adds its own specific properties like health.

The Requirement: In JavaScript, this chain is required; I cannot use the this keyword to set player stats until the parent constructor has finished its job through super().

Course Timeline