In this article I will give you basic introduction to the MightyEditor and development process that surrounds it. Tutorial will show how to actually prototype a mini-game within an hour.
Requirements
Newest Google Chrome browser. You can try other browsers, but we don’t test them yet.
What is MightyEditor?
MightyEditor is open-source cloud based solution for creating and hosting HTML5 games. It is compatible with Phaser game development framework, but you can also use it with other tools. Main features of the editor are: asset management, map editing, code editor, data export.
How does MightyEditor work?
Design process of using editor works by following steps:
- Create a project
- Upload assets
- Drag and drop assets to the map
- Group assets in layers e.g. background, blocks…
- Add collisions and functionality in code editor
- Open game and export data
Why should I use MightyEditor?
Having a browser based tool with all of the basic functionality of map and code editor allows you to focus on fast prototyping of games. Open a link in browser and you are good to go. There is no hassle with installing and configuring various software solutions thus saving your precious time.
Cooperation with designer, another team member or a client has been made as easy as sharing link to the project. You can really work as a team, assign an illustrator to dealing with assets while game designer creates different levels in map editor and developer adds functionality with JavaScript code.
MightyEditor does not require your project to depend on it. All assets and code can be exported at any time. Whats even better – the editor is open-source and data can be moved to your local machine with local version of editor. The source code can be found on github https://github.com/TheMightyFingers/mightyeditor.
Idea of mini-game
In this tutorial we will create a simple mini-game called Digger. The game is about a little miner who digs dirt block for gold and sells various minerals at the store. Arrow keys will be used for navigation and a simple physics and collision will be added to miner object.
Creating a project
Open the link http://mightyeditor.mightyfingers.com. Enter project title – in this case it will be Digger.

On the bottom right panel enter game dimensions: worldWidth, worldHeight 640 x 640. For sake of simplicity we will set view-port sizes the same 640 x 640.

Upload game assets
In the following part of tutorial we will use assets that you can download here. On the top right panel from select list use upload file option and add files. Alternatively you can drag and drop files on to the panel and the assets will upload automatically.

Create a map
Click stamp icon on the left tool panel and then select background_sky.png in assets panel and then click on map thus creating background (hold Ctrl button for snapping to grid). You can change position of background by selecting arrow from the left tool panel. For more accurate positioning change x, y position in the settings panel.
Then repeat this step with following assets: background_city.png, background_hill1.png, background_hill2.png, background_grass.png. At the end everything should look like it’s shown in the following image

Create group
Let’s create group for newly created background objects. On right panel Objects section from select list choose Add Group. Rename group to bg and drag objects to this group. To drag multiple objects hold Shift key.

Add rest of graphics
Let’s create 5 rows of blocks under background. There are four different types of them: rock, ground, grass, gold. Gold blocks are collectible and you can’t dig rocks. Objects have to be added in blocks group.

Finally we need to add character and shop objects. As for the character asset – the image contains multiple frames. We need to define frame width and height in bottom right panel Settings panel. The size is 90 x 90. Separated frames can be viewed at bottom assetPreview panel. Also edit anchorX and anchorY. Set them both to 0.5

You can also define your own variables for object. Open userData tab in the same panel and add gold parameter with 0 value;

Select text icon on left tools panel and put a text object on top right corner of map. Write “0” as text will represent points. Rename text object in Objects panel on the right side.

Now we are ready to add objects and finish working with map editing. Character and shop objects are added like in image below

We have finished graphical part of tutorial. Next we’ll go in to coding and adding functionality like character controls, collisions, etc.
Source editor
Switch to source editor on top left side.

On the left side menu with game files are displayed. You will have to code mostly in state/play.js file. You can find key shortcodes for the editor here.
Game states
For coding we are going to use Phaser development framework. The states in Phaser are a separate parts of the game logic. By default editor gives you a template with four states boot, load, menu, play. For each state there are some predefined methods: preload, create, update, render. For demo purposes you should know that create method is called right after all assets are loaded and update method is called by game loop 60 times a second. You can learn more in documentation.
By default template calls load state. We need to redirect to play state. For this edit menu.js file under create method.
window.Digger.state.load = {
preload: function(){
...
},
create: function() {
this.game.state.start("play");
}
}
Open game
First open game from top panel Open game button. At the moment there is only black screen. To display just made objects we have to initialize them in play.js file create method.
create: function() {
this.bg = mt.create("bg");
this.blocks = mt.create("blocks");
this.shop = mt.create("shop");
this.character = mt.create("character");
this.points = mt.create("points");
}
Initializing is done with mt.create function. “bg” and “blocks” represent group names in object panel on the right side. “shop” and “character” represent sprite names in the same panel and finally “points” represent text. As you see all objects group, sprite and text are initialized with the same method.
Open the game now and initialized objects will be visible on the screen.
Adding physics
By default physics are disabled in Phaser for better performance reasons. We will enable the lightest and fastest physics from all available – Arcade physics. Open physics tab in bottom right corner. Change parameter enable to 1 and rest of parameters will appear below. Set character body size width: 60 and height 60. Enable gravity and set y to 1000. At last set collideWorldBounds parameter to 1.

Opening game you will see character falling down to the bottom of the screen.
Character controls
Initialize cursor keys in create method.
this.cursors = this.game.input.keyboard.createCursorKeys();
This function give us an object with the four arrow keys to play with: up, down, left and right. In update method we will track when left/right/up arrow key is pressed and give a velocity to character or stop it keys are not inactive.
update: function() {
if (this.cursors.left.isDown) {
this.character.body.velocity.x = -200;
} else if (this.cursors.right.isDown) {
this.character.body.velocity.x = 200;
} else {
this.character.body.velocity.x = 0;
} if (this.cursors.up.isDown) {
this.character.body.velocity.y = -300;
}
}
Open game and try arrow keys to control character.
Collision between character and blocks
Enable physics for blocks and set them immovable in the Map editor bottom right physics panel.

Next add collision detection in update method. First two arguments declare that we will check collision between sprite object and group of object. Third argument is a 2 argument function which is called on collision.
this.game.physics.arcade.collide(this.character, this.blocks, function(character, block) {
console.log('Collision between', character, block);
}, null, this);
Opening game you will see character won’t fall to the end of screen, but will land on top of the blocks.
Character animations
First we need to define frames in spritesheet for different types of animations. Add these lines in create method.
this.character.animations.add('stand', [0, 1, 2, 3], 10, true);
this.character.animations.add('fly', [4, 5, 6, 7], 10, true);
this.character.animations.add('run', [8, 9, 10], 10, true);
this.character.animations.add('fall', [12, 13, 14, 15], 10, true);
this.character.animations.add('dig', [16, 17, 18], 10, false);
this.character.animations.add('dig_down', [20, 21, 22], 10, false);
this.character.animations.play('stand');
Last line of code starts play default animation stand.
For rest of animations we have to change update method and add play specific animation for each key press. Note that we have the same animation for left and right run. In order to flip horizontally sprite we are using scale -1.
if (this.cursors.left.isDown) {
this.character.body.velocity.x = -200;
this.character.animations.play('run');
this.character.scale.x = -1;
} else if (this.cursors.right.isDown) {
this.character.body.velocity.x = 200;
this.character.animations.play('run');
this.character.scale.x = 1;
} else {
this.character.body.velocity.x = 0;
this.character.animations.play('stand');
} if (this.cursors.up.isDown) {
this.character.body.velocity.y = -300;
this.character.animations.play('fly');
}
Destroying blocks
In order to dig blocks we need to add functionality to our collide function:
this.game.physics.arcade.collide(this.character, this.blocks, function(character, block) {
if (this.cursors.left.isDown) {
if (block.body.touching.right) {
this.destroyBlock(block);
}
}
else if (this.cursors.right.isDown) {
if (block.body.touching.left) {
this.destroyBlock(block);
}
}
else if (this.cursors.down.isDown) {
if (block.body.touching.up) {
this.destroyBlock(block);
}
}
}, null, this);
Various blocks need to be handled differently. Grass and ground blocks are simply destroyed, rocks are indestructible and we can collect gold and save it in character gold parameter. Add destroyBlock method under play state.
destroyBlock: function(block) {
switch (block.key) {
case '/rock.png':
break;
case '/grass.png':
case '/ground.png':
block.destroy();
break;
case '/gold.png':
this.character.getData().userData.gold++;
block.destroy();
break;
}
},
Overlapping and selling gold
In the next step we need to sell collected gold at the shop. At first you need to go back to map editor and set physics for shop object similar how it was done with character. Set parameters enable: 1, gravity->allow: 0, immovable: 1. After that go to source editor and change update method with following lines:
this.game.physics.arcade.overlap(this.character, this.shop,
function(character, shop) {
if (character.getData().userData.gold > 0) {
var newPoints = parseInt(this.points._text) + character.getData().userData.gold;
this.points.setText(newPoints);
character.getData().userData.gold = 0;
}
}, null, this
);
Refactoring and adding final animations
We will add digging animations as final step of this tutorial and re-factor update method to meet our needs of good looking game. Given previous samples the code below should be self explaining.
"use strict";
window.Digger.state.play = {
create: function(){
this.cursors = this.game.input.keyboard.createCursorKeys();
this.bg = mt.create("bg");
this.blocks = mt.create("blocks");
this.shop = mt.create("shop");
this.character = mt.create("character");
this.points = mt.create("points");
this.character.animations.add('stand', [0, 1, 2, 3], 10, true);
this.character.animations.add('fly', [4, 5, 6, 7], 10, true);
this.character.animations.add('run', [8, 9, 10], 10, true);
this.character.animations.add('fall', [12, 13, 14, 15], 10, true);
this.character.animations.add('dig', [16, 17, 18], 10, false);
this.character.animations.add('dig_down', [20, 21, 22], 10, false);
this.character.animations.play('stand');
},
update: function(){
var collideDown = false;
this.game.physics.arcade.collide(this.character, this.blocks,
function(character, block){
if(this.dig) return;
if(this.cursors.left.isDown){
if(block.body.touching.right){
this.dig = this.character.animations.play('dig');
this.dig.onComplete.addOnce(function(){
this.destroyBlock(block);
}, this);
} else {
this.character.animations.play('run');
}
}
else if(this.cursors.right.isDown){
if(block.body.touching.left){
this.dig = this.character.animations.play('dig');
this.dig.onComplete.addOnce(function(){
this.destroyBlock(block);
}, this);
} else {
this.character.animations.play('run');
}
}
else if(this.cursors.down.isDown){
if(block.body.touching.up){
this.dig = this.character.animations.play('dig_down');
this.dig.onComplete.addOnce(function(){
this.destroyBlock(block);
}, this);
} else {
this.character.animations.play('stand');
}
}
if(block.body.touching.up){
collideDown = true;
}
}, null, this);
if(this.dig){
return;
}
if(this.cursors.left.isDown){
this.character.scale.x = -1;
this.character.body.velocity.x = -200;
}
else if(this.cursors.right.isDown){
this.character.scale.x = 1;
this.character.body.velocity.x = 200;
}
else {
this.character.body.velocity.x = 0;
}
if(this.cursors.up.isDown){
this.character.body.velocity.y = -300;
this.character.animations.play('fly');
} else {
if(!collideDown){
this.character.animations.play('fall');
}
else if(this.character.body.velocity.x === 0){
this.character.animations.play('stand');
}
}
this.game.physics.arcade.overlap(this.character, this.shop,
function(character, shop){
if(character.getData().userData.gold > 0){
var newPoints = parseInt(this.points._text) + character.getData().userData.gold;
this.points.setText(newPoints);
character.getData().userData.gold = 0;
}
}, null, this
);
},
destroyBlock: function(block){
this.dig = false;
switch(block.key){
case '/rock.png':
break;
case '/grass.png':
case '/ground.png':
block.destroy();
break;
case '/gold.png':
this.character.getData().userData.gold++;
block.destroy();
break;
}
},
stopDig: function(){
this.dig = false;
}
};
Full game project is available here: http://mightyeditor.mightyfingers.com/#pde5-copy
Final game here: http://mightyeditor.mightyfingers.com/data/projects/pde5/phaser/index.html
iframe: