Phaser
Neil Haddley • January 23, 2022
2D game framework used for making HTML5 games
Getting Started
A getting started sample includes a config object, a preload function and a create function.
The preload function is used to load the Phaser assets.
The create function is used to add assets to the scene/game.

Getting Started - index.htm

Getting Started - running
Aquarium
I created an animated Aquarium based on https://github.com/lrusso/Aquarium.
The Aquarium code includes a config object, a preload function, a create function and an update function.
Again the preload function is used to load the Phaser assets.
Again the create function is used to add assets to the scene/game.
Here the update function is called (over and over again) as the main/game loop runs.
The update function animates the scene (moving the fish and the bubbles).

Aquarium with artwork
index.htm
TEXT
1<!DOCTYPE html> 2<html> 3 4<head> 5 <script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser-arcade-physics.min.js"></script> 6</head> 7 8<body> 9 10 <script> 11 var config = { 12 13 type: Phaser.AUTO, 14 15 width: 800, 16 height: 600, 17 18 scale: { 19 20 mode: Phaser.Scale.FIT, 21 autoCenter: Phaser.Scale.CENTER_BOTH, 22 23 }, 24 25 physics: { 26 default: 'arcade', 27 arcade: { 28 gravity: { y: 200 } 29 } 30 }, 31 32 scene: { 33 preload: preload, 34 create: create 35 } 36 }; 37 38 var game = new Phaser.Game(config); 39 40 function preload() { 41 this.load.setBaseURL('https://labs.phaser.io'); 42 43 this.load.image('sky', 'assets/skies/space3.png'); 44 this.load.image('logo', 'assets/sprites/phaser3-logo.png'); 45 this.load.image('red', 'assets/particles/red.png'); 46 } 47 48 function create() { 49 this.add.image(400, 300, 'sky'); 50 51 var particles = this.add.particles('red'); 52 53 var emitter = particles.createEmitter({ 54 speed: 100, 55 scale: { start: 1, end: 0 }, 56 blendMode: 'ADD' 57 }); 58 59 var logo = this.physics.add.image(400, 100, 'logo'); 60 61 logo.setVelocity(100, 200); 62 logo.setBounce(1, 1); 63 logo.setCollideWorldBounds(true); 64 65 emitter.startFollow(logo); 66 } 67 </script> 68 69</body> 70 71</html>
Index.html
TEXT
1<!DOCTYPE html> 2<html> 3 4<head> 5 <script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser-arcade-physics.min.js"></script> 6</head> 7 8<body style="background-color: black;"> 9 10 <script> 11 12 function getRandomBubbleX(columnIndex) { 13 if (columnIndex == 1) { 14 return this.getRandomInteger(70, 90); 15 } 16 else if (columnIndex == 2) { 17 return this.getRandomInteger(250, 275); 18 } 19 else if (columnIndex == 3) { 20 return this.getRandomInteger(450, 470); 21 } 22 } 23 24 function getRandomBubbleY() { 25 return this.getRandomInteger(450, 800); 26 } 27 28 function getRandomAngle() { 29 var randomValue = this.getRandomInteger(1, 100); 30 31 if (randomValue < 33) { 32 // RETURNING A LOOKING FORWARD FISH ANGLE ORIENTATION 33 return 0; 34 } 35 else if (randomValue < 66) { 36 // RETURNING A LOOKING DOWN FISH ANGLE ORIENTATION 37 return 20; 38 } 39 else { 40 // RETURNING A LOOKING UP FISH ANGLE ORIENTATION 41 return -20; 42 } 43 } 44 45 function getRandomX() { 46 // GETTING A RANDOM NUMBER BETWEEN 60 AND 500 (THE GAME WIDTH WITH A MARGIN) 47 return this.getRandomInteger(60, 500); 48 } 49 50 function getRandomY() { 51 // GETTING A RANDOM NUMBER BETWEEN 60 AND 300 (THE GAME HEIGHT WITH A MARGIN) 52 return this.getRandomInteger(60, 300); 53 } 54 55 function getRandomInteger(min, max) { 56 return Math.floor(Math.random() * (max - min + 1)) + min; 57 } 58 59 var config = { 60 61 type: Phaser.AUTO, 62 63 width: 576, height: 432, 64 65 scale: { 66 67 mode: Phaser.Scale.FIT, 68 autoCenter: Phaser.Scale.CENTER_BOTH, 69 70 }, 71 72 scene: { 73 preload: preload, 74 create: create, 75 update: update 76 } 77 }; 78 79 bubbles = [] 80 fishCount = 16 81 82 var game = new Phaser.Game(config) 83 84 function preload() { 85 86 // LOAD THE IMAGES 87 this.load.image("imageBackground", 'imageBackground.jpeg'); 88 this.load.image("imageBubbles", 'imageBubbles.png'); 89 90 for (let i = 0; i < fishCount; i++) { 91 this.load.image("imageFish" + (i + 1), "fish" + (i + 1) + "_64.png"); 92 } 93 94 // LOAD THE AUDIO 95 this.load.audio('audioBubbles', 'audioBubbles.mp3'); 96 97 } 98 99 function create() { 100 101 // ADD THE AUDIO 102 this.bubbles = this.sound.add('audioBubbles', { volume: 0.1, loop: true }); 103 this.bubbles.play(); 104 105 // ADD THE BACKGROUND IMAGE 106 this.add.sprite(576 / 2, 432 / 2, "imageBackground"); 107 108 fishes = [] 109 110 // ADD THE FISH 111 for (let i = 0; i < fishCount; i++) { 112 const fish = this.add.sprite(getRandomX(), getRandomY(), "imageFish" + (i + 1)); 113 fish.fishSpeed = 1; 114 fish.angle = getRandomAngle(); 115 fish.inputEnabled = true; 116 fishes.push(fish); 117 } 118 119 // ADD BUBBLES 120 for (var column = 0; column < 3; column++) { 121 for (var i = 0; i < 9; i++) { 122 var tempBubble = this.add.sprite(getRandomBubbleX(column + 1), getRandomBubbleY(), "imageBubbles"); 123 tempBubble.columnIndex = column + 1; 124 tempBubble.alpha = 0.7; 125 tempBubble.setScale(.5); 126 bubbles.push(tempBubble); 127 } 128 } 129 130 131 } 132 133 function update() { 134 135 if (game.sound.context.state === 'suspended') { 136 game.sound.context.resume(); 137 } 138 139 // LOOP FOR EVERY FISH 140 for (var i = 0; i < fishes.length; i++) { 141 142 // GET A FISH 143 var fish = fishes[i]; 144 145 // CHECK THE FISH ORIENTATION 146 if (fish.scale == 1) { 147 // MOVING THE FISH TO THE RIGHT 148 fish.x = fish.x + fish.fishSpeed; 149 } 150 else { 151 // MOVING THE FISH TO THE LEFT 152 fish.x = fish.x - fish.fishSpeed; 153 } 154 155 // CHECK IF THE FISH IS NOT VISIBLE (RIGHT SIDE) 156 if (fish.x > 650) { 157 // RESTORING THE ORIGINAL FISH SPEED 158 fish.fishSpeed = 1; 159 160 // CHANGING THE FISH ORIENTATION 161 fish.scale = -1; 162 163 // CHANGING THE FISH Y POSITION TO A RANDOM VALUE 164 fish.y = getRandomY(); 165 166 // CHANGING THE FISH ANGLE TO A RANDOM VALUE 167 fish.angle = getRandomAngle(); 168 } 169 170 // CHECK IF THE FISH IS NOT VISIBLE (LEFT SIDE) 171 else if (fish.x < -70) { 172 // RESTORING THE ORIGINAL FISH SPEED 173 fish.fishSpeed = 1; 174 175 // CHANGING THE FISH ORIENTATION 176 fish.scale = 1; 177 178 // CHANGING THE FISH Y POSITION TO A RANDOM VALUE 179 fish.y = getRandomY(); 180 181 // CHANGING THE FISH ANGLE TO A RANDOM VALUE 182 fish.angle = getRandomAngle(); 183 } 184 185 // CHECK IF THE FISH IS NOT VISIBLE (TOP SIDE) 186 if (fish.y < -70) { 187 // MOVING THE FISH TO THE LEFT SIDE 188 fish.x = -70; 189 190 // CHANGING THE FISH Y POSITION TO A RANDOM VALUE 191 fish.y = getRandomY(); 192 193 // RESTORING THE FISH ANGLE 194 fish.angle = 0; 195 } 196 197 // CHECK IF THE FISH IS NOT VISIBLE (BOTTOM SIDE) 198 else if (fish.y > 650) { 199 // MOVING THE FISH TO THE RIGHT SIDE 200 fish.x = 650; 201 202 // CHANGING THE FISH Y POSITION TO A RANDOM VALUE 203 fish.y = getRandomY(); 204 205 // RESTORING THE FISH ANGLE 206 fish.angle = 0; 207 } 208 209 // CHECK THE FISH SCALE AND ANGLE AND MOVING UP OR DOWN ACCORDINGLY 210 if ((fish.scale == 1 && fish.angle == 20) || (fish.scale == -1 && fish.angle == -20)) { 211 fish.y = fish.y + fish.fishSpeed / 2; 212 } 213 else if ((fish.scale == 1 && fish.angle == -20) || (fish.scale == -1 && fish.angle == 20)) { 214 fish.y = fish.y - fish.fishSpeed / 2; 215 } 216 } 217 218 // LOOP FOR EVERY BUBBLE 219 for (var i = 0; i < bubbles.length; i++) { 220 // GET A BUBBLE 221 var bubble = bubbles[i]; 222 223 // MOVE THE BUBBLE 224 bubble.y = bubble.y - 1; 225 226 // CHECK IF THE BUBBLE IS NOT VISIBLE 227 if (bubble.y < -150) { 228 // MOVE THE BUBBLE DOWN 229 bubble.x = getRandomBubbleX(bubble.columnIndex); 230 bubble.y = getRandomBubbleY(); 231 } 232 } 233 } 234 235 </script> 236 237</body> 238 239</html>