Skip to content

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 state
const prevState = getPreviousMapEntry(gameStates, 'playing'); // ['menu', {...}]
// Get next state
const 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 entry
const firstState = getFirstMapEntry(gameStates); // ['menu', {...}]
// Get last entry
const 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

  1. Use map utilities for ordered collections where sequence matters:

    // Good: Using map for ordered states
    const gameStates = new Map([
    ['intro', introState],
    ['gameplay', gameplayState],
    ['ending', endingState],
    ]);
    // Less ideal: Using object where order matters
    const gameStates = {
    intro: introState,
    gameplay: gameplayState,
    ending: endingState,
    };
  2. Handle undefined cases:

    const nextEntry = getNextMapEntry(map, currentKey);
    if (nextEntry) {
    const [key, value] = nextEntry;
    // Process next entry
    } else {
    // Handle end of sequence
    }
  3. 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);
    }
    }