maze-blockly-wrapper
v0.7.6
Published
A Blockly-based maze game wrapper with editable maze generation and programming interface
Downloads
299
Maintainers
Readme
@maze/blockly-wrapper
A React-based Blockly wrapper for creating interactive maze programming games. This package provides a complete maze game environment where users can program a spider to navigate through mazes using visual programming blocks.
Features
- Interactive Maze Game: Program a spider to navigate through mazes
- Visual Programming: Uses Google Blockly for drag-and-drop programming
- Editable Mazes: Create and customize mazes with an intuitive editor
- Real-time Execution: Watch your code execute step-by-step
- Responsive Design: Works on desktop and mobile devices
- TypeScript Support: Full TypeScript definitions included
Installation
npm install maze-blockly-wrapperRequired Dependencies
This package requires the following peer dependencies:
npm install react react-dom blockly⚠️ Important Setup
Before using any components, you must initialize Blockly to avoid the recentlyCreatedOwnerStacks error:
import React, { useEffect } from 'react';
import { MazeGame, initializeBlockly } from 'maze-blockly-wrapper';
function App() {
useEffect(() => {
// CRITICAL: Initialize Blockly before using any components
initializeBlockly();
}, []);
const handleRunFinish = (result) => {
console.log('Game finished!', result);
// result contains: steps, reachedFinish, maxMovesExceeded, finalPosition, path, executionTime
};
return (
<MazeGame
isEditable={true}
onRunFinish={handleRunFinish}
maxMoves={100}
/>
);
}Quick Start
import React, { useEffect } from 'react';
import { MazeGame, initializeBlockly } from 'maze-blockly-wrapper';
function App() {
useEffect(() => {
// Initialize Blockly first
initializeBlockly();
}, []);
return <MazeGame />;
}Components
MazeGame
The main component that combines the maze, programming interface, and game logic.
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| isEditable | boolean | false | Enable maze editing mode |
| configuration | MazeConfig | undefined | Initial maze configuration |
| onChange | (config: MazeConfig) => void | undefined | Callback when maze configuration changes |
| onRunFinish | (result: RunResult) => void | undefined | Callback when game execution finishes |
| maxMoves | number | 50 | Maximum moves allowed |
| showControls | boolean | true | Show game control buttons |
| className | string | undefined | Additional CSS classes |
EditableMazeGrid
A standalone component for editing maze configurations.
import { EditableMazeGrid } from '@maze/blockly-wrapper';
<EditableMazeGrid
config={mazeConfig}
onConfigChange={handleConfigChange}
/>MazeBlocklyContainer
The Blockly programming interface component.
import { MazeBlocklyContainer } from '@maze/blockly-wrapper';
<MazeBlocklyContainer
config={blocklyConfig}
onCodeChange={handleCodeChange}
onExecuteCode={handleExecuteCode}
/>Types
MazeConfig
interface MazeConfig {
width: number;
height: number;
spiderStart: Position;
finishPosition: Position;
walls: Position[];
estimatedSteps?: number;
}RunResult
interface RunResult {
steps: number;
reachedFinish: boolean;
maxMovesExceeded: boolean;
finalPosition: Position;
path: Position[];
executionTime: number;
error?: string;
}Position
interface Position {
x: number;
y: number;
}Usage Examples
Basic Game
import { MazeGame } from '@maze/blockly-wrapper';
<MazeGame />Editable Maze with Configuration
import { MazeGame } from '@maze/blockly-wrapper';
const initialConfig = {
width: 12,
height: 10,
spiderStart: { x: 1, y: 1 },
finishPosition: { x: 10, y: 8 },
walls: [
{ x: 3, y: 2 },
{ x: 4, y: 3 },
{ x: 7, y: 5 }
]
};
<MazeGame
isEditable={true}
configuration={initialConfig}
onChange={(config) => console.log('Maze changed:', config)}
onRunFinish={(result) => console.log('Game result:', result)}
maxMoves={75}
/>Custom Blockly Configuration
import { MazeBlocklyContainer } from '@maze/blockly-wrapper';
const customConfig = {
allowedTypes: new Set(['maze_move_forward', 'maze_turn_left']),
limits: { maze_move_forward: 10, maze_turn_left: 5 },
toolbox: `<xml>...</xml>`,
initialXml: `<xml>...</xml>`
};
<MazeBlocklyContainer
config={customConfig}
onCodeChange={(code) => console.log('Code:', code)}
onExecuteCode={(commands) => console.log('Commands:', commands)}
/>Development
Building the Package
# Build library for distribution
npm run build:lib
# Build types
npm run build:types
# Build both library and app
npm run buildDevelopment Mode
npm run devContributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
License
MIT License - see LICENSE file for details.
Troubleshooting
Error: "Cannot read properties of undefined (reading 'recentlyCreatedOwnerStacks')"
This error occurs when Blockly is not properly initialized. Make sure to:
- Call
initializeBlockly()before using any components - Install Blockly as a peer dependency:
npm install blockly - Import Blockly in your project if using custom configurations:
import 'blockly/core';
import 'blockly/blocks';
import 'blockly/javascript';Multiple Blockly Instances
If you're using multiple Blockly instances in your app:
- Initialize Blockly only once at the app level
- Properly dispose of workspaces when components unmount
- Avoid reinitializing Blockly unnecessarily
Build Configuration
For bundlers like Webpack or Vite, ensure Blockly is properly externalized:
// webpack.config.js
module.exports = {
externals: {
'blockly': 'Blockly'
}
};// vite.config.ts
export default defineConfig({
build: {
rollupOptions: {
external: ['blockly']
}
}
});API Reference
Blockly Setup Utilities
initializeBlockly()- Initialize Blockly for package usageisBlocklyReady()- Check if Blockly is readygetBlockly()- Get the initialized Blockly instancegetJavaScriptGenerator()- Get the JavaScript generatorresetBlocklyInitialization()- Reset initialization state (for testing)
Support
For issues and questions, please use the GitLab issue tracker at: https://gitlab.com/smartbooksdev/blocklysbwrapper
