Trimester 2

Trimester 2

Data Types, OOP & Full Stack Projects

Game Builder & Game Engine

The biggest project of this trimester was working with a full game engine to build a multi‑level pirate game. This was where everything clicked—JavaScript fundamentals, team communication, and creative problem‑solving all came together. Working inside the game engine taught me how scenes, objects, and interaction systems connect under the hood, and gave me hands‑on experience with a real game builder workflow.

Through this project I got to communicate more with my team, coordinate on level design, and really understand how a game goes from idea to playable product. The game has 3 levels, and I built Level 1—Pirate Heist.

Play the Pirate Mega Game →

Working as a Team

Building a 3‑level game isn't something one person can do alone. One of the most valuable parts of this project was learning how to work as a real team—not just splitting tasks, but actually staying in sync, communicating progress, and holding each other accountable.

We used GitHub Issues and a project board to manage our workflow. Every feature, bug, and task was tracked as an issue, and we organized them into columns (To Do, In Progress, Done) so everyone could see at a glance what needed attention and who was working on what. This made it easy to:

  • Break the project into manageable pieces and assign ownership
  • Keep track of each other's progress without constant check‑ins
  • Stay on schedule by seeing what was blocked or falling behind
  • Document decisions and discussions directly on the issues

Using a board changed how we collaborated. Instead of vague "I'll work on it" promises, we had clear, visible commitments. It also helped when someone got stuck—teammates could jump in because they knew exactly where things stood. This experience taught me that good tooling and transparency are just as important as writing good code.

Team Board & Issues in Action

Team board screenshot 1 Team board screenshot 2 Team board screenshot 3 Team board screenshot 4

Pirate Heist – Level 1

Game Concept

In this level, the main character McArchie sneaks into a guarded area to steal valuable treasure before anyone notices. The goal is to collect four key items:

  • Chest
  • Gold
  • Ruby
  • Treasure Map

McArchie explores the area and interacts with objects to collect these items. Once all four are stolen, the player presses Esc to progress to Level 2, where McArchie is discovered and forced into a fight. Level 1 focuses on exploration and interaction, while Level 2 introduces combat mechanics.

Objects Used

  • Player with 8‑way movement
  • Background environment
  • Multiple NPCs with dialogue
  • Collectible objects (Chest, Gold, Ruby, Treasure Map)
  • Checklist UI system

Key Technical Decisions

Multiple NPC Implementation

One of the main technical improvements in this level was learning how to implement multiple NPCs instead of just one. Each NPC was given:

  • A position in the game world
  • Dialogue that appears when interacted with
  • Interaction detection when the player presses E

Previously, I had only worked with a single NPC, so creating several required restructuring how NPC objects were created and stored in the game level. This allowed each NPC to function independently while still using the same dialogue system.

Reusing Existing Systems

Instead of rebuilding everything from scratch, I reused several systems from previous work:

  • Character movement for McArchie
  • Dialogue interactions for NPC conversations
  • Interaction key logic for pressing E

Because these systems were already working, I could focus my time on building new features instead of debugging basic mechanics.

The Checklist System (Most Difficult Feature)

The checklist system was the hardest feature to implement. The idea was simple: the player sees a list of items to steal, and once collected, each item gets crossed off.

Example checklist at the start:

  • Chest
  • Gold
  • Ruby
  • Treasure Map

After collecting an item:

  • Chest
  • Gold
  • Ruby
  • Treasure Map

Even though the concept seemed simple, the coding was much more complicated. To make it work, I had to:

  • Track whether each item has been collected
  • Update the checklist UI dynamically
  • Prevent the player from collecting the same item twice
  • Connect object interaction with checklist updates

Overall, the checklist system took the most time out of everything in this level.

Object Positioning Challenges

Another surprisingly difficult part was positioning objects in the game world. Every object—NPCs, treasure items, and interactable objects—needed exact coordinates. If positioned incorrectly:

  • Items could appear off screen
  • NPCs could spawn inside walls or other objects
  • Interaction zones wouldn't align correctly with the sprite

This required a lot of trial and error—adjusting coordinates, reloading, and testing again until everything appeared in the correct place. Although it sounds simple, it became one of the more time‑consuming parts of building the level.

Preparing for Level 2

After the player collects all four items, the checklist is fully completed, McArchie has stolen the treasure, and the story progresses to Level 2—where McArchie is caught and must fight his way out, introducing combat gameplay that builds on the exploration mechanics from Level 1.

Pirate Game – Requirements Checklist

# Requirement Present? Where
1 Writing Classes (Player, Boss, NPC) Yes Player in Player.js, BlackbreadBoss in GameLevelPirateBoss.js:7, Npc in Npc.js
2 Methods & Parameters (2 params) Yes checkCollision(player, cookie), checkInZone(player, zone), _overlap(ax,ay,aw,ah,bx,by,bw,bh)
3 Instantiation via GameLevel config Yes this.classes = [{ class: Player, data: playerData }, ...] in GameLevelPirateHunt.js:214
4 Inheritance (3 levels) Yes GameObject → Character → Player / BlackbreadBoss / Npc
5 Method Overriding Yes update() overridden in Player, BlackbreadBoss, Npc; handleCollisionReaction() overridden in Player
6 Constructor Chaining Yes super(data, gameEnv) in BlackbreadBoss, Player, Npc
7 Iteration (forEach) Yes gameEnv.gameObjects?.forEach(...) in PirateBoss; for loops in game loop and destroy sequences
8 Conditionals Yes Collision type checks, state transitions throughout
9 Nested Conditions (3+ levels) Yes Attack + sword + range + phase checks in GameLevelPirateBoss.js:370‑407; NPC interact handler in Npc.js:100‑142
10 Numbers Yes x, y, velocity, HP, scale factors, angles everywhere
11 Strings Yes Character IDs ('lost sailor', 'Blackbread'), sprite paths, greeting messages
12 Booleans Yes isPaused, wonGame, isInteracting, isOpen
13 Arrays Yes gameObjects[], cannonballs[], cookies[], waypoints[], this.classes[]
14 JSON Objects Yes playerData, bossData, npcData1‑4, bgData, cannonball objects
15 Mathematical Ops Yes Math.cos/sin for orbital motion, Math.sqrt for distance, Math.max/min for clamping, Math.PI for rotation
16 String Ops Yes Template literals for HTML/CSS, string concatenation for IDs
17 Boolean Expressions Yes &&, ||, ! in compound conditions throughout
18 Canvas Rendering Yes ctx.drawImage(), ctx.arc(), ctx.fill(), ctx.save()/restore() in Character and Boss
19 Keyboard Events Yes keydown/keyup listeners in Player.js, Npc interaction keys, Escape for exit
20 GameEnv Config Yes Object literals configure every level and game state
21 Single Responsibility Yes Separate methods for draw, update, collision, input handling
22 Data‑Driven Design Yes GameBuilder Object Literals (playerData, bossData, etc.) drive all game objects
23 State Management Yes Pause state, boss phases (1/2/3), wonGame, dialogue open/close, level.continue
24 SDLC Yes Kanban board, GitHub issues, feature branches, git history
25 Documentation (inline comments) Yes Inline comments on every method across all pirate level files
26 Testing Yes Tests exist for level 2

Key Skills Learned

  • Implement multiple NPCs in a game scene
  • Build a dynamic checklist system
  • Connect object interactions with UI updates
  • Reuse code from older projects
  • Handle precise object placement in a game environment

Even though some features—especially the checklist and object positioning—were challenging, solving these problems helped me better understand game logic, interaction systems, and UI state management.

Code Examples

Below are line-by-line snippets from the pirate game that demonstrate a few key requirements.

#1 — Writing Classes

class BlackbreadBoss extends Character {  // define a new class that inherits from Character
    constructor(data, gameEnv) {          // constructor receives config data and game environment
        super(data, gameEnv);                // call parent constructor to set up shared properties
        this.hp = 100;                       // boss starts with 100 health points
        this.phase = 1;                      // boss starts in phase 1
    }
}

#4 — Inheritance (3 levels)

// Level 1: Base class
class GameObject { ... }

// Level 2: Character extends GameObject
class Character extends GameObject { ... }

// Level 3: Specific characters extend Character
class Player extends Character { ... }
class BlackbreadBoss extends Character { ... }
class Npc extends Character { ... }

#7 — Iteration (forEach)

// loop through every game object to check for collisions with the boss
gameEnv.gameObjects?.forEach(obj => {   // iterate over each object in the scene
    if (obj.id === 'player') {           // only care about the player object
        this.checkCollision(obj, this);    // run collision detection between player and boss
    }
});

#9 — Nested Conditions (3+ levels)

if (isAttacking) {                              // level 1: is the player attacking?
    if (hasSword) {                              // level 2: do they have a weapon?
        if (distanceToBoss < attackRange) {       // level 3: are they close enough?
            if (this.phase === 2) {              // level 4: is the boss in a vulnerable phase?
                boss.hp -= 10;                  // deal damage only if ALL conditions are met
            }
        }
    }
}

#14 — JSON Objects

const playerData = {
    id: 'McArchie',               // string — character name
    src: 'assets/pirate.png',      // string — sprite image path
    SCALE_FACTOR: 10,              // number — controls sprite size
    STEP_FACTOR: 400,              // number — controls movement speed
    ANIMATION_RATE: 50,            // number — ms between animation frames
    isPlayer: true,                 // boolean — marks this as the player object
    idle: { row: 0, columns: 1 },  // nested object — idle animation config
    walk: { row: 1, columns: 4 },  // nested object — walk animation config
};