Create an HTML5 game like Mass Attack with Phaser just using tweens (well, almost)

Read all posts about "" game

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.

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

215 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stairs
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers