Get the full commented source code of

HTML5 Suika Watermelon Game

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. memdot 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;
               }
          }
     }
}
Next time I will show you how to create a full working game, meanwhile download the source code and obviously play the original game.

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.