Talking about Mass Attack game, Game development, HTML5, Javascript and Phaser.
The more I use Phaser, the more I like it.
Today I want to show you how easy is to create an HTML5 game like Mass Attack just using Phaser’s tweens and some JavaScript.
Mass Attack is a very old but fun game based on the very simple idea of balancing weights on a scale. Just press the mouse button to create a spheric weight. The longer you hold down the mouse the larger the weight that is created.
It does not feature any physics engine so I will improve my Flash AS2 prototype I made seven years ago using Phaser’s tweens.
Have a look at the final project (you can also play it with your mobile phone from this link):
Click-touch and hold to create a sphere, release to drop the sphere, watch it bounce on the balance and move it accordingly. It shouldn’t be hard to perfectly create the original game out of this.
And the script was very easy to do, like all Phaser stuff I made so far. Look at the fully commented code:
<!doctype html> <html> <head> <script src="phaser.min.js"></script> <style> body{margin:0} </style> <script type="text/javascript"> window.onload = function() { var game = new Phaser.Game(320,480,Phaser.CANVAS,"",{preload:onPreload, create:onCreate, update:onUpdate}); // this array will handle the balance itself along with its graphics and data var balance = []; // are we making the ball grow? var growBall = false; // the ball itself var ball; // changing these variables will affect gameplay // ball growing speed, in pixels per frame var ballGrowingSpeed = 0.5; // variable to limit balance movement var balanceFriction = 400; // maximum ball radius var maxDiameter = 50; // preloading images function onPreload() { game.load.image("balance","assets/balance.png"); game.load.image("ball","assets/ball.png"); } // blueprint function to scale the game, you will want to use it in all your projects function scaleGame(){ game.scale.pageAlignHorizontally = true; game.scale.pageAlignVertically = true; game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL; game.scale.setScreenSize(); } function onCreate() { scaleGame(); // balance[0] will be the left balance balance[0] = game.add.group(); // set left balance weight to zero balance[0].weight = 0; // balance[1] will be the right balance balance[1] = game.add.group(); // set right balance weight to zero balance[1].weight = 0; // adding the balance sprite to left balance, a 160x20 rectangle var balanceSprite = game.add.sprite(80,240,"balance"); balanceSprite.anchor.x = 0.5; balanceSprite.anchor.y = 0.5; balance[0].add(balanceSprite); // adding the balance sprite to right balance balanceSprite = game.add.sprite(240,240,"balance"); balanceSprite.anchor.x = 0.5; balanceSprite.anchor.y = 0.5; balance[1].add(balanceSprite); // waiting for the player to click/touch the screen, then call placeBall function game.input.onDown.add(placeBall, this); } // the player clicked/touched the screen, so we are going to create a ball function placeBall(){ // add ball sprite at coordinates ("x input",0) ball = game.add.sprite(game.input.worldX,0,"ball"); ball.anchor.x = 0.5; ball.anchor.y = 0.5; // setting ball width and height to 1 ball.width=1; ball.height=1; // ball.balance = 0 if placed on the left half of the screen, else = 1 ball.balance = Math.floor(ball.x/(game.width/2)) // adding the ball to the proper group balance[ball.balance].add(ball); // placing the ball 30 pixels from the top of the stage, no matter group y position ball.y = 30-balance[ball.balance].y // don't wait anymore for the player to click/touch the screen game.input.onDown.remove(placeBall, this); // wait for the player to release click/touch, then call dropBall function game.input.onUp.add(dropBall, this); // make ball grow growBall=true; } // at every frame, we just make ball grow if the ball should grow and it still has not reached its maximum diameter function onUpdate() { if(growBall && ball.width<maxDiameter){ ball.width+=ballGrowingSpeed; ball.height+=ballGrowingSpeed; } } // function to be executed when the player released the click/touck, time to make the ball fall function dropBall(){ // the ball stops growing growBall = false; // the listener is removed game.input.onUp.remove(dropBall, this); // now it's time to calculate ball destination. // it have to land on the top of the balance, whose top side is at y=230 // ball radius is ball.height/2 // so the final destination is 230+1-radius // the +1 is to give a slight overlap effect not to make the ball seem to actually touch the balance var ballDestination = 231-ball.height/2; console.log(balance[ball.balance].y+" , "+(ball.height/2)+" -> "+ballDestination) // increase balance weight according to ball volume formula // volume = 4/3*PI*radius^3 balance[ball.balance].weight+=(4/3)*Math.PI*(ball.width/2)*(ball.width/2)*(ball.width/2); // tween the ball to its destination during two seconds with a bounce easing effect var ballTween = game.add.tween(ball).to({ y: ballDestination }, 2000, Phaser.Easing.Bounce.Out, true); // call adjustBalances function once the tween is over ballTween.onComplete.add(adjustBalances,this); } // function to adjust balances position according to weights function adjustBalances(){ // finding the weight difference between the balances and divide it by the friction var weightDifference = (balance[0].weight-balance[1].weight)/balanceFriction; // limit weight difference to prevent balances fly off the screen if(weightDifference>game.height/3){ weightDifference = game.height/3; } if(weightDifference<-game.height/3){ weightDifference = -game.height/3; } // adding tween to balances var balanceTween = game.add.tween(balance[0]).to({ y: weightDifference }, 2000, Phaser.Easing.Quadratic.Out, true); var balanceTween2 = game.add.tween(balance[1]).to({ y: -weightDifference }, 2000, Phaser.Easing.Quadratic.Out, true); // once the tween is over, you should check if the level has been completed. // I'll just let the ball fall again balanceTween.onComplete.add(allowBallFalling) } // this function will just add another listener to create next ball function allowBallFalling(){ game.input.onDown.add(placeBall, this); } }; </script> </head> <body> </body> </html>
I plan to make a couple of commercial games with Phaser, I am enjoying it every day a little more.
Download the source code of the prototype.
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.