Talking about Memdot game, Game development, HTML5, Javascript and Phaser.
Did you play Memdot by Appsolute Games, the same team behind Dashy Panda game I already explained? It’s a tiny free iOSgame which has been featured on the app store. Some colored circles enter the stage in a fancy way. The the stage fades out to a random color and circles disappear. You have to touch all circles with the same color as stage color. Easier to play than to explain, as usual. This game is also perfect to start a new tutorial series, we will see how to create the engine which manages circles entering the stage, background color fading in, and you selecting the circle (or the circles) matching background color. Again, it’s way simpler playing than explaining, to test it you may need to reload the game and focus the canvas: Once the circles disappear, touch the circles with the same color of the background to make them disappear, if you fail you will see the actual color of the circle. I used a lot of ArrayUtils methods to populate arrays with circles positions and colors then randomly draw and remove them from the array. You will find ArrayUtils very useful, as you can see the full commented source code:
// the game
var game;
// size of each tile, in pixels
var gridSize = 40;
// colors to be used in game
var colorsInGame = [0xff0000, 0xff8800, 0x00ff00, 0x0000ff, 0xff00ff, 0x555555];
// how many circles in game?
var circlesInGame = 3;
// creation of the game
window.onload = function() {
game = new Phaser.Game(320, 480);
game.state.add("PlayGame", playGame);
game.state.start("PlayGame");
}
var playGame = function(game){}
playGame.prototype = {
preload: function(){
// preloading the assets
game.load.spritesheet("circles", "circles.png", gridSize, gridSize);
game.load.image("background", "background.png");
},
create: function(){
// set background color to white
game.stage.backgroundColor = "#ffffff";
// adding a group containing all circles
this.circleGroup = game.add.group();
// possibleColors will contain the same items as colorsInGame array,
// just repeated (circlesInGame - 1) times.
// we want to have more circles with the same color, but not ALL circle with the same color
this.possibleColors = [];
for(var i = 0; i < colorsInGame.length; i++){
for(var j = 0; j < circlesInGame - 1; j++){
this.possibleColors.push(colorsInGame[i])
}
}
// boardWidth and boardHeight will determine the width and height of the game board,
// according to game size and grid size.
// we subtract 2 from both boardWidth and boardHeight because we don't want
// tiles to be at the very edge of the canvas
var boardWidth = game.width / gridSize - 2;
var boardHeight = game.height / gridSize - 2;
// creation of an array with all possible grid positions
this.positionsArray = [];
for(var i = 0; i < (boardWidth) * (boardHeight); i++){
this.positionsArray.push(i);
}
// pickedColors is the array which will contain all colors actually used in this game
this.pickedColors = [];
// repeating this loop circlesInGame times
for(var i = 0; i < circlesInGame; i++){
// choosing a random position for the circle.
// this position won't be available anymore as we remove it from positionsArray
var randomPosition = Phaser.ArrayUtils.removeRandomItem(this.positionsArray);
// determining circle x and y position in pixels
var posX = (1 + randomPosition % (boardWidth)) * gridSize;
var posY = (1 + Math.floor(randomPosition / boardWidth)) * gridSize;
// creating the circle as a button which calls circleSelected function
var circle = game.add.button(posX, posY, "circles", this.circleSelected, this);
// adding the circle to circleGroup group
this.circleGroup.add(circle);
// tinting the circle with a possible color and removing the color
// from the array of possible colors.
// we also save its tint color in a property called tintColor
circle.tintColor = Phaser.ArrayUtils.removeRandomItem(this.possibleColors)
circle.tint = circle.tintColor;
// adding the tint color to pickedColors array, if not already in the array
if(this.pickedColors.indexOf(circle.tint) == -1){
this.pickedColors.push(circle.tint);
}
// choosima a random direction: 1 = left, 2 = up, 3 = right, 4 = down
var randomDirection = game.rnd.integerInRange(1, 4);
// a temporary object which will be used to handle circle tween
var tweenObject = {};
// according to random direction...
switch(randomDirection){
case 1:
// left: circle is placed just outside left border and the tween
// will bring it to its initial x position
circle.x = - gridSize;
tweenObject.x = posX;
break;
case 2:
// up: circle is placed just outside upper border and the tween
// will bring it to its initial y position
circle.y = - gridSize;
tweenObject.y = posY;
break;
case 3:
// left: circle is placed just outside right border and the tween
// will bring it to its initial x position
circle.x = game.width + gridSize;
tweenObject.x = posX;
break;
case 4:
// left: circle is placed just outside bottom border and the tween
// will bring it to its initial y position
circle.y = game.height + gridSize;
tweenObject.y = posY;
break;
}
// adding the tween to circle. This will create the "enter in the stage" effect
game.add.tween(circle).to(tweenObject, 500, Phaser.Easing.Cubic.Out, true);
}
// after two seconds, let's cover the screen
game.time.events.add(Phaser.Timer.SECOND * 2, this.fadeOut, this);
},
// this function will cover the screen with a random color
fadeOut: function(){
// filling the entire canvas with a tile sprite
this.cover = game.add.tileSprite(0, 0, game.width, game.height, "background");
// giving the cover a tint color picked among circle colors
this.cover.tint = Phaser.ArrayUtils.getRandomItem(this.pickedColors);
// setting the cover to transparent
this.cover.alpha = 0;
// tweening the cover to fully opaque
var coverTween = game.add.tween(this.cover).to({
alpha: 1
}, 200, Phaser.Easing.Linear.None, true);
// once the cover is fully opaque...
coverTween.onComplete.add(function(){
// bring to top circleGroup as it was hidden by the cover
game.world.bringToTop(this.circleGroup);
// for each circle in circleGroup group...
this.circleGroup.forEach(function(item){
// tinting it white
item.tint = 0xffffff;
// setting it to frame 1 to show just a white ring
item.frame = 1;
})
}, this)
},
// this function will be called each time a circle is touched
// b is the circle
circleSelected: function(b){
// if the screen is already fully covered...
if(this.cover != undefined && this.cover.alpha == 1){
// if the circle has the same tint color of the cover...
// (we use tintColor property we previously saved, because circle tint color now is white)
if(b.tintColor == this.cover.tint){
// then destrot it
b.destroy();
}
else{
// if not, show the actual color of the circle
b.tint = b.tintColor
b.frame = 0;
}
}
}
}
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.