OOP - Methods with Parameters
How I implement methods with multiple parameters and constructor chaining
Methods with Parameters & Constructor Chaining
Requirements
- Implement methods with parameters (e.g.,
collisionHandler(other, direction)) - Use
super()to chain constructors for parent initialization
Evidence
Constructor Chaining with super()
Ghost.js Constructor
import Enemy from '@assets/js/GameEnginev1.1/essentials/Enemy.js';
class Ghost extends Enemy {
constructor(data, gameEnv) {
super(data, gameEnv); // ← Constructor Chaining: initializes parent Enemy
this.followSpeedFactor = data?.followSpeedFactor ?? 0.4;
this.followStopDistance = data?.followStopDistance ?? 8;
this._hasTriggeredDeath = false;
}
}
How it meets the requirement:
- super(data, gameEnv): Passes parameters to parent Enemy class constructor
- Parent Initialization: Enemy class sets up collision detection, position, velocity
- Child-Specific Properties: After super(), adds Ghost-specific properties
DeathBarrier.js Constructor
import Barrier from '@assets/js/GameEnginev1.1/essentials/Barrier.js';
class DeathBarrier extends Barrier {
constructor(data, gameEnv) {
super(data, gameEnv); // ← Constructor Chaining: initializes parent Barrier
this._hasTriggeredDeath = false;
// Add static state management for grace period
if (!DeathBarrier.levelStartTime) {
DeathBarrier.levelStartTime = new Date();
}
}
}
How it meets the requirement:
- super(data, gameEnv): Initializes parent Barrier’s collision and positioning
- Parameters: data object contains configuration; gameEnv provides game context
- Extended Initialization: Adds static properties for grace period tracking
SpriteSheetCoin.js Constructor
import Coin from '@assets/js/GameEnginev1.1/Coin.js';
class SpriteSheetCoin extends Coin {
constructor(data = null, gameEnv = null) {
super(data, gameEnv); // ← Constructor Chaining: initializes parent Coin
this.spriteImagePath = data?.spriteImagePath || null;
this.spriteImage = null;
this.isImageLoaded = false;
this.spriteFrames = data?.spriteFrames || { rows: 1, columns: 1, frameIndex: 0 };
this.fallbackToCircle = data?.fallbackToCircle !== false;
if (this.spriteImagePath) {
this.loadImage();
}
}
}
How it meets the requirement:
- super(data, gameEnv): Initializes parent Coin class with position and collection logic
- Default Parameters: Uses
data = null, gameEnv = nullfor flexibility - Optional Chaining: Uses
data?.spriteImagePathto safely access nested properties
Methods with Multiple Parameters
Ghost.js - followPlayer() Method
followPlayer(player) { // ← Parameter: player object
if (!player) return;
const ghostCenter = this.getCenter();
const playerCenter = typeof player.getCenter === 'function'
? player.getCenter()
: { x: player.x || 0, y: player.y || 0 };
const dx = playerCenter.x - ghostCenter.x;
const dy = playerCenter.y - ghostCenter.y;
const distance = Math.hypot(dx, dy);
if (distance <= this.followStopDistance) {
this.velocity.x = 0;
this.velocity.y = 0;
return;
}
const baseSpeed = player?.xVelocity || (this.gameEnv?.innerWidth || 800) / 2000;
const speed = Math.max(0.3, baseSpeed * this.followSpeedFactor);
const nx = dx / distance;
const ny = dy / distance;
this.position.x += nx * speed;
this.position.y += ny * speed;
if (Math.abs(dx) >= Math.abs(dy)) {
this.direction = dx >= 0 ? 'right' : 'left';
} else {
this.direction = dy >= 0 ? 'down' : 'up';
}
}
How it meets the requirement:
- Parameter: Accepts
playerobject and checks its type - Multiple Operations: Uses player data to calculate direction and distance
- Return Value: Modifies ghost position based on player location
DeathBarrier.js - handleCollision() with Multiple Checks
update() { // Overridden method with collision logic
super.update();
if (this._hasTriggeredDeath) return; // ← Guard clause with state parameter
const player = this.gameEnv?.gameObjects?.find(obj => obj.constructor?.name === 'Player');
if (!player || !player.canvas || !this.canvas) return; // ← Multiple parameter checks
this.isCollision(player); // ← Pass player to collision method
if (this.collisionData?.hit) {
// Check grace period from level start time
const timeSinceLevelStart = new Date() - DeathBarrier.levelStartTime;
if (timeSinceLevelStart < 500) {
console.log('[MazeDebug] Grace period active:', timeSinceLevelStart, 'ms');
return; // Grace period still active
}
this._hasTriggeredDeath = true;
player.isDead = true;
console.log('[MazeDebug] DeathBarrier hit player:', this.canvas?.id || this.id || 'unknown');
console.log('[MazeDebug] Player Position:', player.x, player.y);
try {
showDeathScreen(player, 'You got lost in the maze.');
} catch (error) {
console.error('DeathBarrier failed to show death screen:', error);
this._hasTriggeredDeath = false;
player.isDead = false;
}
}
}
How it meets the requirement:
- Multiple Parameters: Checks player object’s multiple properties
- Parameter Passing: Passes player to
isCollision()for collision detection - Complex Logic: Uses parameters to determine game state and behavior
GameLevelOutside.js - applyPlayerSprite() with Parameters
const applyPlayerSprite = (player, skinKey) => { // ← Two parameters: player object, skinKey string
const spriteSrc = getPlayerSpriteSrc(skinKey);
if (!player || !spriteSrc) return;
if (player.spriteData?.src === spriteSrc) {
setStoredPlayerSkinKey(skinKey);
return;
}
const newSpriteSheet = new Image();
newSpriteSheet.onload = () => {
player.spriteSheet = newSpriteSheet; // ← Modify player object based on parameters
player.spriteReady = true;
player.spriteData = { ...(player.spriteData || {}), src: spriteSrc };
player.data = player.spriteData;
player.frameIndex = 0;
player.frameCounter = 0;
player.resize();
setStoredPlayerSkinKey(skinKey);
};
newSpriteSheet.onerror = (error) => {
console.warn('Failed to load player spritesheet:', spriteSrc, error);
};
newSpriteSheet.src = spriteSrc;
};
How it meets the requirement:
- Multiple Parameters: Takes
playerobject andskinKeystring - Parameter Usage: Uses both parameters to select and apply sprite
- State Modification: Changes player properties based on parameters
Summary
✅ Constructor Chaining - All classes use super() to initialize parents
✅ Parameter Passing - Methods accept 1-2+ parameters for flexibility
✅ Parameter Usage - Parameters modify object state and behavior
✅ Type Safety - Parameter checks ensure valid data before use
✅ Return Values - Methods return appropriate values or modify state