Object-Oriented Programming (OOP)

Table of Contents

  1. Class Hierarchy Diagram
  2. Writing Classes
  3. Methods & Parameters
  4. Instantiation & Objects

Class Hierarchy Diagram

The diagram below shows the class hierarchy used throughout this portfolio’s game projects — every concept on this page lives somewhere in this chain.

classDiagram
    class GameObject {
        +position
        +draw()
        +update()
    }
    class Character {
        +speed
        +isAlive
        +move()
    }
    class Player {
        +keypress
        +score
        +handleInput()
        +collisionHandler()
    }
    class Npc {
        +dialogues
        +greeting
        +react()
        +interact()
    }
    class Enemy {
        +damage
        +patrol()
    }
    class Coin {
        +value
        +collected
        +reaction()
    }
    GameObject <|-- Character
    GameObject <|-- Coin
    Character <|-- Player
    Character <|-- Npc
    Character <|-- Enemy

OOP is about designing code using classes, objects, and inheritance. It helps organize code for games and applications, making it modular and reusable.


Subrequirements

Writing Classes

What was learned: Classes are blueprints for creating objects, letting us organize code for different parts of a game or app. By defining custom classes, we can model things like paddles, balls, or players with their own properties and behaviors. In Pong and Snake, writing classes made it easier to manage game logic and reuse code.
Evidence:
  • Pong Game: Custom classes for Ball, Paddle, Game, Input, Renderer (View Pong Game)
  • Local Storage Demo: localStorageDemo class encapsulates an entire game level
// From hacks/pong.md — full Paddle class definition
class Paddle {
    constructor(x, y, width, height, speed, boundsHeight) {
        this.position = new Vector2(x, y);
        this.width = width;
        this.height = height;
        this.speed = speed;
        this.boundsHeight = boundsHeight;
    }
    move(dy) {
        this.position.y = Math.min(
            this.boundsHeight - this.height,
            Math.max(0, this.position.y + dy)
        );
    }
    rect() { return { x: this.position.x, y: this.position.y, w: this.width, h: this.height }; }
}

Code Runner Challenge

Hit Run to see a class being defined and used — the exact Paddle blueprint from Pong. A class defines what an object looks like (properties) and what it can do (methods), and new creates a working instance.

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

Quick Quiz: Writing Classes

  1. What is a class in programming?
    • a) A function that runs automatically
    • b) A blueprint for creating objects
    • c) A type of variable
  2. What does the move(dy) method do in the Paddle class?
  3. Why is it useful to use classes in a game project?
Show Answers 1. b) A blueprint for creating objects 2. It moves the paddle up or down, clamped within the canvas. 3. Classes help organize code and make it reusable for similar objects.

Methods & Parameters

What was learned: Methods are functions inside classes that define what an object can do, and parameters let us pass in information. In Pong, methods like move(dy) and capBallSpeedFor(ball) let game objects react to events. Using methods with parameters made our code flexible and easy to extend for new features.
Evidence:
  • Pong Game: Methods like move(dy), capBallSpeedFor(ball), _applyPowerUp(type, playerSide)
// From hacks/pong.md — _applyPowerUp uses type and playerSide params to apply different effects
_applyPowerUp(type, playerSide) {
    const dur = Config.powerUp.durationSec * 1000;
    if (type === 1) {
        const p = (playerSide === 'left') ? this.paddleLeft : this.paddleRight;
        p.height = Math.min(Config.canvas.height, Config.paddle.height * 1.6);
    } else if (type === 2) {
        const factor = 1.6;
        for (const b of this.balls) { b.velocity.x *= factor; b.velocity.y *= factor; }
    }
}

Code Runner Challenge

Hit Run to see methods with parameters — a Car class from the Classes & Methods notebook, same pattern as Pong's Paddle and Ball methods. Parameters let one method handle many different situations.

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

Instantiation & Objects

What was learned: Instantiation means creating an object from a class using new, giving us a working game element with its own data. In Pong, we instantiate balls and paddles to bring the game to life. This process is key to building games with many interactive parts.
Evidence:
  • Pong Game: new Ball(...), new Paddle(...), new Renderer(ctx) in game setup
// From hacks/pong.md — Game constructor instantiates all game objects
this.renderer    = new Renderer(this.ctx);
this.input       = new Input();
this.paddleLeft  = new Paddle(0, midY, width, height, speed, Config.canvas.height);
this.paddleRight = new Paddle(Config.canvas.width - width, midY, width, height, speed, Config.canvas.height);
this.balls       = [ new Ball(Config.ball.radius, Config.canvas.width, Config.canvas.height) ];

Code Runner Challenge

Hit Run to see instantiation — each new call creates a separate object with its own data. Changing one paddle does not affect the other, which is the whole point of objects.

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

Inheritance (Basic)

What was learned: Inheritance lets us create new classes based on existing ones, sharing code and adding new features. The game engine uses this pattern widely — level classes and NPC classes extend base engine classes. This makes code more organized and easier to maintain as projects grow.
Evidence:
  • Classes & Methods Lesson: Inheritance demonstrated with Car → ElectricCar example
  • Collisions Mechanic Level: Follows the same constructor pattern as all engine-level classes
// From _notebooks/JavaScriptLessons/Classes_and_Methods — extending a base class
class ElectricCar extends Car {
    constructor(brand, color, range) {
        super(brand, color);   // calls Car's constructor
        this.range = range;
    }
    chargeBattery() { console.log(this.brand + " is charging."); }
}

Code Runner Challenge

Hit Run to see inheritance — ElectricCar extends Car and gets accelerate/brake for free via super(), then adds its own chargeBattery method. This is how the game engine level classes work too.

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

Method Overriding

What was learned: Method overriding means redefining a method from a parent class in a child class to change its behavior. In the game engine, every level class overrides the constructor to set up its own objects while still following the shared interface.
Evidence:
  • Collisions Mechanic Level: Overrides the shared constructor to configure an alien-planet scene
// From _projects/collisions-mechanic/levels/GameLevelCollisionMechanicsLessonLevel.js
class GameLevelCollisionMechanicsLessonLevel {
    constructor(gameEnv) {         // overrides the base game level setup
        const bgData = {
            src: path + "/images/gamebuilder/bg/alien_planet.jpg",
            pixels: { height: 772, width: 1134 }
        };
        const playerData = { id: 'playerData', src: path + "/images/gamebuilder/sprites/astro.png" };
        this.classes = [
            { class: GameEnvBackground, data: bgData },
            { class: Player,            data: playerData },
        ];
    }
}

Code Runner Challenge

Hit Run to see method overriding — Animal.speak() is defined once in the parent, but Dog and Cat each override it with their own version. The same method name, completely different behaviour.

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

Constructor Chaining

What was learned: Constructor chaining uses super() to call a parent class's constructor from a child class. This ensures all shared properties are set up before adding child-specific ones. In Pong, every object's constructor sets up position via Vector2, and in inheritance examples super() wires the chain together.
Evidence:
  • Pong Game: Vector2 used inside Paddle and Ball constructors
// From hacks/pong.md — Ball constructor chains through Vector2 and reset()
class Ball {
    constructor(radius, boundsWidth, boundsHeight) {
        this.position = new Vector2();   // Vector2 constructor called here
        this.velocity = new Vector2();
        this.reset(true);               // chains to own method to finish setup
    }
}

Code Runner Challenge

Hit Run to see constructor chaining — super() runs the parent constructor before the child adds its own setup. The console shows the exact order each constructor fires.

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