Overview of JS OOP Assets (Mario)
Fundamentals of OOP. This describes outline of game object, game levels, and game control.
JS OOP Assets
GameEnv
| ├── Attributes:
│ | ├── levels
│ | ├── gameObjects
| │ └── canvas
| |
| ├── Purpose:
│ | ├── update: updates objects, draws objects on canvas
│ | ├── destroy: destroys all gameObjects in reverse order
│ | └── canvas: creates canvas, sets bounds, resizes canvas
│
├── GameObject
| └── Allows for collision detecton, animation, and resizing
│ ├── Player: animates, controls with wasd
│ ├── Background: fit to screen, scrolling
│ └── Platform: fixed to bottom, scrolling
│
├── GameLevel
│ ├── Attributes:
│ | ├── playerAssets
│ | ├── backgroundAssets
│ | ├── platformAssets
│ | └── objectAssets
| |
│ └── Methods:
│ | ├── load: loads "new" GameObject created from assets
│ | ├── loads player, platform, background
| | └── possibly changes player speed, object speed, etc.
|
└── GameControl
│ ├── Methods:
| | ├── gameLoop: keeps game running, main "backbone" in code
| | ├── destroy: destroys objects from previous levels
│ | └── transitionToLevel: destroys and creates objects for game
Mr. Mort’s code below
Game Environment
GameEnv is the overarching environment class that holds the game levels, game objects, and manages environment updates.
class GameEnv {
// defined and current game levels
static levels = [];
static currentLevel = null;
// active Game Objects
static gameObjects = [];
// initialize for Game Environment
static initialize() {
// store width and height based on screen size
this.setTop();
this.setBottom();
// ...
}
// resize Game Objects
static resize() {
this.initialize(); // Update dimensions
// Call the sizing method on all game objects
for (var gameObj of GameEnv.gameObjects){
gameObj.size();
}
}
// gameLoop method to update Game Objects
static update() {
// Update game state, including all game objects
for (const gameObject of this.gameObjects) {
gameObject.update();
gameObject.draw();
}
}
}
GameObject
GameObject is the base class for all objects in the game. It contains common attributes and methods.
// Common attributes, methods, prototype methods for all objects in the Game.
class GameObject {
constructor(canvas, config) {
this.x = config.x;
this.y = config.y;
this.canvas = canvas;
this.ctx = canvas.getContext('2d');
this.image = config.image;
this.frame = config.frame;
this.width = config.width;
this.height = config.height;
this.aspect_ratio = this.width / this.height;
this.speedRatio = config.speedRatio;
this.speed = GameEnv.gameSpeed * this.speedRatio;
this.collisionWidth = 0;
this.collisionHeight = 0;
this.collisionData = {};
GameObject.gameObjects.push(this);
}
destroy() {
const index = GameObject.gameObjects.indexOf(this);
if (index !== -1) {
// Remove the canvas from the DOM
this.canvas.parentNode.removeChild(this.canvas);
GameObject.gameObjects.splice(index, 1);
}
}
update() { }
draw() { }
size() { }
isCollision(object) { }
collisionAction(object) { }
handleCollision(object) {
if (this.isCollision(object)) {
this.collisionAction(object);
}
}
}
Player
Player is a class specific to the player character, extending GameObject and adding properties like speed, jump height, etc.
// Create a class specifically for the player character, extending the GameObject class.
class Player extends GameObject {
constructor(canvas, config) {
super(canvas, config);
this.speed = config.speed;
this.jumpHeight = config.jumpHeight;
this.health = config.health;
// Set up event listeners for user input
document.addEventListener('keydown', this.handleKeyDown.bind(this));
document.addEventListener('keyup', this.handleKeyUp.bind(this));
}
handleKeyDown(event) {
// Handle key down events (e.g., move left or right, jump)
switch (event.key) {
case 'ArrowLeft':
this.moveLeft();
break;
case 'ArrowRight':
this.moveRight();
break;
case 'Space':
this.jump();
break;
// Handle other keys as needed
}
}
handleKeyUp(event) {
// Handle key up events (e.g., stop moving)
switch (event.key) {
case 'ArrowLeft':
case 'ArrowRight':
this.stopMoving();
break;
// Handle other keys as needed
}
}
moveLeft() { /* Implement left movement logic */ }
moveRight() { /* Implement right movement logic */ }
stopMoving() { /* Implement stop movement logic */ }
jump() { /* Implement jump logic */ }
attack() { /* Implement attack logic */ }
}
Platform
Platform is a class for platforms that the player can stand on, extending GameObject.
// Create a class for platforms that the player can stand on.
class Platform extends GameObject {
constructor(canvas, config) {
super(canvas, config);
}
// Additional platform-specific methods or properties
}
Game Level
GameLevel stores the assets and attributes specific to a particular level. It has properties like background, platforms, player, …
// Store the assets and attributes of the Game at the specific GameLevel.
class GameLevel {
constructor(tag) {
this.tag = tag;
this.backgroundImg = null;
this.platformImg = null;
this.playerImg = null;
this.isComplete = null; // function that determines if level is complete
}
setBackgroundFile(file) {
this.backgroundImg = file;
}
// ...
setIsComplete(callBack) {
this.isComplete = callBack; // callBack is function to test for level completion
}
// Load level data
load() { /* Load level data */ }
// ...
// Add a GameLevel to the array levels
static create(tag, backgroundFile, platformFile, playerFile, isComplete) {
const newLevel = new GameLevel(tag);
newLevel.setBackgroundFile(backgroundFile);
newLevel.setPlatformFile(platformFile);
newLevel.setPlayerFile(playerFile);
newLevel.setIsComplete(isComplete);
GameEnv.levels.push(newLevel);
}
}
Game Control
The gameLoop and the setup and teardown between game levels
const GameControl = {
// Level transition method (destroy then newlevel)
async transitionToLevel(newLevel) {
this.inTransition = true;
// Destroy existing game objects
GameEnv.destroy();
// Load GameLevel objects
await newLevel.load();
GameEnv.currentLevel = newLevel;
// Trigger a resize to redraw canvas elements
window.dispatchEvent(new Event('resize'));
// Update invert property, twice means same as before
toggleCanvasEffect.dispatchEvent(new Event('click'));
toggleCanvasEffect.dispatchEvent(new Event('click'));
this.inTransition = false;
},
// Game control loop
gameLoop() {
// Turn game loop off during transitions
if (!this.inTransition) {
// Get current level
GameEnv.update();
const currentLevel = GameEnv.currentLevel;
// currentLevel is defined
if (currentLevel) {
// run the isComplete callback function
if (currentLevel.isComplete && currentLevel.isComplete()) {
const currentIndex = GameEnv.levels.indexOf(currentLevel);
// next index is in bounds
if (currentIndex !== -1 && currentIndex + 1 < GameEnv.levels.length) {
// transition to the next level
this.transitionToLevel(GameEnv.levels[currentIndex + 1]);
}
}
// currentLevel is null, (ie start or restart game)
} else {
// transition to beginning of game
this.transitionToLevel(GameEnv.levels[0]);
}
}
// recycle gameLoop, aka recursion
requestAnimationFrame(this.gameLoop.bind(this));
},
};