Map Utilities
Overview
Map utilities provide functions for working with JavaScript’s Map
data structure. These utilities are particularly useful for managing collections of game objects, state machines, and sequential data.
Map Navigation
Getting Adjacent Entries
Navigate between map entries using getPreviousMapEntry
and getNextMapEntry
:
import { getPreviousMapEntry, getNextMapEntry } from 'dill-pixel';
const gameStates = new Map([ [ 'menu', { /* ... */ }, ], [ 'playing', { /* ... */ }, ], [ 'paused', { /* ... */ }, ], [ 'gameover', { /* ... */ }, ],]);
// Get previous stateconst prevState = getPreviousMapEntry(gameStates, 'playing'); // ['menu', {...}]
// Get next stateconst nextState = getNextMapEntry(gameStates, 'playing'); // ['paused', {...}]
Getting Boundary Entries
Access the first and last entries of a map:
import { getFirstMapEntry, getLastMapEntry } from 'dill-pixel';
// Get first entryconst firstState = getFirstMapEntry(gameStates); // ['menu', {...}]
// Get last entryconst lastState = getLastMapEntry(gameStates); // ['gameover', {...}]
Common Use Cases
State Machine Implementation
import { getNextMapEntry } from 'dill-pixel';
class GameStateMachine { private states = new Map([ ['idle', { enter: () => console.log('Entering idle') }], ['running', { enter: () => console.log('Starting to run') }], ['jumping', { enter: () => console.log('Jumping!') }], ]);
private currentState = 'idle';
transitionToNext() { const nextEntry = getNextMapEntry(this.states, this.currentState); if (nextEntry) { const [nextState, handlers] = nextEntry; this.currentState = nextState; handlers.enter(); } }}
Level Progression
import { getNextMapEntry, getLastMapEntry } from 'dill-pixel';
class LevelManager { private levels = new Map([ [1, { name: 'Tutorial', difficulty: 'easy' }], [2, { name: 'First Steps', difficulty: 'easy' }], [3, { name: 'Challenge', difficulty: 'medium' }], ]);
private currentLevel = 1;
progressToNextLevel() { const nextLevel = getNextMapEntry(this.levels, this.currentLevel); if (nextLevel) { const [levelNumber, levelData] = nextLevel; this.currentLevel = levelNumber; return levelData; } return null; // No more levels }
isLastLevel() { const [lastLevelNumber] = getLastMapEntry(this.levels) ?? []; return this.currentLevel === lastLevelNumber; }}
UI Navigation
import { getPreviousMapEntry, getNextMapEntry } from 'dill-pixel';
class MenuSystem { private menuItems = new Map([ ['play', { label: 'Play Game', action: () => {} }], ['options', { label: 'Options', action: () => {} }], ['credits', { label: 'Credits', action: () => {} }], ]);
private selectedItem = 'play';
navigateUp() { const prevItem = getPreviousMapEntry(this.menuItems, this.selectedItem); if (prevItem) { const [itemKey] = prevItem; this.selectedItem = itemKey; } }
navigateDown() { const nextItem = getNextMapEntry(this.menuItems, this.selectedItem); if (nextItem) { const [itemKey] = nextItem; this.selectedItem = itemKey; } }}
Type Safety
The map utilities are fully typed and support generic types:
interface GameState { name: string; onEnter: () => void; onExit: () => void;}
const states = new Map<string, GameState>();const nextState = getNextMapEntry(states, 'current'); // Type: [string, GameState] | undefined
Best Practices
-
Use map utilities for ordered collections where sequence matters:
// Good: Using map for ordered statesconst gameStates = new Map([['intro', introState],['gameplay', gameplayState],['ending', endingState],]);// Less ideal: Using object where order mattersconst gameStates = {intro: introState,gameplay: gameplayState,ending: endingState,}; -
Handle undefined cases:
const nextEntry = getNextMapEntry(map, currentKey);if (nextEntry) {const [key, value] = nextEntry;// Process next entry} else {// Handle end of sequence} -
Consider caching results for performance:
class Navigator {private cachedNext: Map<string, [string, any]> = new Map();getNextCached(key: string) {if (!this.cachedNext.has(key)) {const next = getNextMapEntry(this.items, key);if (next) this.cachedNext.set(key, next);}return this.cachedNext.get(key);}}