Numbers · Strings · Booleans · Arrays · Objects (JSON)
Every piece of game state is stored as one of five data types. The type isn't just a label — it determines what operations are valid and how the game logic behaves with that value.
Numbers track everything that changes in quantity — health points, pixel positions, velocities, timestamps, and frame counts. Using the correct numeric type and range is critical: health must never go below 0, positions must stay within the canvas bounds, and timestamps must be compared accurately to enforce cooldowns.
// Position, velocity, score tracking — all Numbers
this.health = data?.health ?? 3; // Number — HP counter
this.maxHealth = this.health; // Number — max HP for HUD bar
this.moveSpeed = data?.moveSpeed ?? 0.8; // Number — pixels/frame chase speed
this.lastDamagedAt = 0; // Number — Date.now() timestamp
this.invulnerabilityMs = 300; // Number — cooldown window ms
// Position coordinates — Numbers used in every frame calculation
INIT_POSITION: { x: width * 0.72, y: height * 0.66 }
laser.x += laser.vx; // Number + Number = new position
laser.life -= 1; // Number decrement each frame
Run this to see number operations from the game. Try changing health to 0 or amount to 10.
Strings store character names, asset file paths, game state labels, and CSS filter values. Getting a string wrong — like a misspelled image path — causes a sprite to fail to load and appear as a broken image or red rectangle.
// Character names, sprite paths, game states — Strings
enemyName: 'Daddy Pig', // String — display name
enemyGreeting: 'You shall not pass!', // String — dialogue
enemyImage: 'daddy-pig.png', // String — asset filename
// Template literals build full paths dynamically
src: `${path}/images/gamify/${config.enemyImage}`,
// CSS filter string applied to canvas element on defeat
this.canvas.style.filter = 'grayscale(1) brightness(0.8)';
this.canvas.style.opacity = '0.6';
// String concatenation in console logging for debugging
console.log(`[Boss] Hit! HP: ${this.health}/${this.maxHealth}`);
`${path}/images/gamify/${config.enemyImage}` builds the full sprite path at runtime. Change config.enemyImage and a different sprite loads automatically.
Run this to see template literals and string operations. Try changing the enemy name and see how the path updates.
Boolean flags control every major game state. They act as gates — when a flag is false, entire code paths are skipped. When it flips to true, new behavior activates.
// Boolean flags — isJumping, isPaused, isVulnerable equivalents in this game
this.isDefeated = false; // stops movement, accepts no damage, triggers win check
this.isVulnerable = true; // false during 300ms invulnerability window
this.showHitbox = false; // toggled for debug visualization
this.battleEnded = false; // stops entire update() loop when true
this.attackRequested = false; // set true by SPACE keydown listener
// isPlayerLaser determines who takes damage on collision
laser.isPlayerLaser = true; // player fired it → damages boss
laser.isPlayerLaser = false; // boss fired it → damages player
// Boolean logic in conditionals
if (boss.isDefeated && !this.battleEnded) {
this.battleEnded = true;
this.showWinScreen();
}
isDefeated is the most important boolean in the game. When it flips to true, the boss stops moving, stops taking damage, grays out, and triggers the win condition.
Run this to see boolean flags controlling game state. Try setting isDefeated = true before takeDamage().
Arrays hold collections of game objects that need to be processed together every frame. The laser array is the most performance-critical — it's iterated, drawn, and spliced 60 times per second.
// Game object collections — Arrays
this.lasers = []; // Array — all active projectiles currently on screen
// Pushing a new laser object into the array
this.lasers.push({
x: fromX, y: fromY,
vx: normX * speed, vy: normY * speed,
isPlayerLaser: true,
life: 60, maxLife: 60
});
// Level class array — tells the engine which levels to load in order
gameLevelClasses: [PeppaLevel1, PeppaLevel2, PeppaLevel3]
// this.classes array — instantiated by the engine when a level starts
this.classes = [
{ class: GamEnvBackground, data: image_data_background },
{ class: Player, data: sprite_data_player },
{ class: PeppaBossEnemy, data: sprite_data_enemy }
];
this.lasers grows when projectiles spawn and shrinks when they expire. Removing them promptly with splice keeps the per-frame iteration fast.
Run this to see the laser array in action — spawning, updating every frame, and removing expired lasers.
Configuration objects are JSON-style object literals that centralize all the data for one entity in one place. Instead of hard-coding values scattered across files, a single config object controls everything about a boss — name, sprite, health, speed, and position.
// Configuration objects — Object literals (JSON-style)
const sprite_data_enemy = {
id: config.enemyName, // String
greeting: config.enemyGreeting, // String
src: `${path}/images/gamify/${config.enemyImage}`,
SCALE_FACTOR: config.enemyScale ?? 4, // Number
ANIMATION_RATE: 18, // Number
INIT_POSITION: { x: width * 0.72, y: height * 0.66 }, // Nested object
health: config.enemyHealth, // Number
moveSpeed: config.enemySpeed, // Number
hitbox: { widthPercentage: 0.45, heightPercentage: 0.6 } // Nested object
};
// Each laser is also a JSON object pushed into the lasers array
{ x: 300, y: 200, vx: 3.5, vy: -1.2, isPlayerLaser: true, life: 60, maxLife: 60 }
sprite_data_enemy object is passed to PeppaBossEnemy's constructor as the data parameter. The constructor reads data.health, data.moveSpeed, etc. to set up the boss. This means Level 1 (George Pig) and Level 3 (Daddy Pig) use the exact same class with different config objects — the data drives the difficulty, not the code.
This code uses all five data types from the game. Run it, then try modifying a value (e.g. change health to 0) to see how booleans and numbers interact.
Arrays Homework — Demonstrates array manipulation, indexing, and iteration, used throughout the game for laser arrays, level configurations, and leaderboard data.
Booleans Homework — Demonstrates boolean logic and state management for flags like isDefeated, isVulnerable, and battleEnded.
Strings Homework — Demonstrates string manipulation through player names, console logging, and template literals for dynamic messages.
Data Abstraction Homework — Shows how to design abstract data types and encapsulate state, similar to how config objects and class properties manage complex game state.