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

Getting Started - index.htm

Getting Started - running
Aquarium
I created an animated Aquarium based on https://github.com/lrusso/Aquarium.
The code includes a config object, a preload function, a create function, and an update function. I used the preload function to load the Phaser assets and the create function to add assets to the scene. The update function runs on every game loop tick and animates the fish and bubbles.

Aquarium with artwork
index.htm
HTML
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
HTML
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>