├── .gitattributes ├── .github └── FUNDING.yml ├── .gitignore ├── img ├── fontwhite.png ├── fontwhite.xml ├── loadingbar_bg.png ├── loadingbar_fill.png ├── spritearray.json └── spritearray.png ├── index.html ├── js ├── collectobj.js ├── gamescene.js ├── menuscene.js ├── phaser.js ├── phaser.min.js ├── phaser_addon.js ├── preloader.js └── tutorial.js ├── preview.png ├── readme.md └── snd ├── btn.mp3 ├── btn.ogg ├── coin.mp3 ├── coin.ogg ├── expl.mp3 └── expl.ogg /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: ['https://www.buymeacoffee.com/bdr76'] 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows thumbnail cache files 2 | Thumbs.db 3 | ehthumbs.db 4 | ehthumbs_vista.db 5 | 6 | # Folder config file 7 | Desktop.ini 8 | 9 | # Recycle Bin used on file shares 10 | $RECYCLE.BIN/ 11 | 12 | # Windows Installer files 13 | *.cab 14 | *.msi 15 | *.msm 16 | *.msp 17 | 18 | # Windows shortcuts 19 | *.lnk 20 | 21 | # ========================= 22 | # Operating System Files 23 | # ========================= 24 | -------------------------------------------------------------------------------- /img/fontwhite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BdR76/Phaser3-example-game/0cf80f4892de834236147f97105369e1e6311287/img/fontwhite.png -------------------------------------------------------------------------------- /img/fontwhite.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /img/loadingbar_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BdR76/Phaser3-example-game/0cf80f4892de834236147f97105369e1e6311287/img/loadingbar_bg.png -------------------------------------------------------------------------------- /img/loadingbar_fill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BdR76/Phaser3-example-game/0cf80f4892de834236147f97105369e1e6311287/img/loadingbar_fill.png -------------------------------------------------------------------------------- /img/spritearray.json: -------------------------------------------------------------------------------- 1 | { 2 | "frames":[ 3 | {"filename":"coin7","frame":{"x":444,"y":117,"w":32,"h":32},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":32,"h":32},"sourceSize":{"w":32,"h":32}}, 4 | {"filename":"coin8","frame":{"x":477,"y":117,"w":32,"h":32},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":32,"h":32},"sourceSize":{"w":32,"h":32}}, 5 | {"filename":"dude","frame":{"x":485,"y":311,"w":27,"h":40},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":27,"h":40},"sourceSize":{"w":27,"h":40}}, 6 | {"filename":"bombexpl1","frame":{"x":387,"y":182,"w":32,"h":32},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":32,"h":32},"sourceSize":{"w":32,"h":32}}, 7 | {"filename":"bombexpl2","frame":{"x":387,"y":246,"w":64,"h":64},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":64,"h":64},"sourceSize":{"w":64,"h":64}}, 8 | {"filename":"phaser3","frame":{"x":0,"y":0,"w":512,"h":116},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":512,"h":116},"sourceSize":{"w":512,"h":116}}, 9 | {"filename":"bomb","frame":{"x":453,"y":182,"w":32,"h":32},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":32,"h":32},"sourceSize":{"w":32,"h":32}}, 10 | {"filename":"sparkle1","frame":{"x":387,"y":117,"w":56,"h":64},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":56,"h":64},"sourceSize":{"w":56,"h":64}}, 11 | {"filename":"sparkle2","frame":{"x":452,"y":246,"w":56,"h":64},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":56,"h":64},"sourceSize":{"w":56,"h":64}}, 12 | {"filename":"star","frame":{"x":165,"y":375,"w":24,"h":22},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":24,"h":22},"sourceSize":{"w":24,"h":22}}, 13 | {"filename":"btn_back","frame":{"x":0,"y":117,"w":128,"h":128},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":128,"h":128},"sourceSize":{"w":128,"h":128}}, 14 | {"filename":"btn_back_hl","frame":{"x":258,"y":246,"w":128,"h":128},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":128,"h":128},"sourceSize":{"w":128,"h":128}}, 15 | {"filename":"btn_close","frame":{"x":436,"y":311,"w":48,"h":48},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":48,"h":48},"sourceSize":{"w":48,"h":48}}, 16 | {"filename":"btn_close_hl","frame":{"x":387,"y":311,"w":48,"h":48},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":48,"h":48},"sourceSize":{"w":48,"h":48}}, 17 | {"filename":"btn_play","frame":{"x":129,"y":246,"w":128,"h":128},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":128,"h":128},"sourceSize":{"w":128,"h":128}}, 18 | {"filename":"btn_play_hl","frame":{"x":0,"y":246,"w":128,"h":128},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":128,"h":128},"sourceSize":{"w":128,"h":128}}, 19 | {"filename":"btn_quest","frame":{"x":129,"y":117,"w":128,"h":128},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":128,"h":128},"sourceSize":{"w":128,"h":128}}, 20 | {"filename":"btn_quest_hl","frame":{"x":258,"y":117,"w":128,"h":128},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":128,"h":128},"sourceSize":{"w":128,"h":128}}, 21 | {"filename":"coin1","frame":{"x":0,"y":375,"w":32,"h":32},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":32,"h":32},"sourceSize":{"w":32,"h":32}}, 22 | {"filename":"coin2","frame":{"x":33,"y":375,"w":32,"h":32},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":32,"h":32},"sourceSize":{"w":32,"h":32}}, 23 | {"filename":"coin3","frame":{"x":66,"y":375,"w":32,"h":32},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":32,"h":32},"sourceSize":{"w":32,"h":32}}, 24 | {"filename":"coin4","frame":{"x":99,"y":375,"w":32,"h":32},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":32,"h":32},"sourceSize":{"w":32,"h":32}}, 25 | {"filename":"coin5","frame":{"x":420,"y":182,"w":32,"h":32},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":32,"h":32},"sourceSize":{"w":32,"h":32}}, 26 | {"filename":"coin6","frame":{"x":132,"y":375,"w":32,"h":32},"rotated":false,"trimmed":false,"spriteSourceSize":{"x":0,"y":0,"w":32,"h":32},"sourceSize":{"w":32,"h":32}} 27 | ], 28 | "meta":{"app":"https://www.leshylabs.com/apps/sstool/","version":"Leshy SpriteSheet Tool v0.8.4","image":"spritesheet.png","size":{"w":512,"h":407},"scale":1} 29 | } -------------------------------------------------------------------------------- /img/spritearray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BdR76/Phaser3-example-game/0cf80f4892de834236147f97105369e1e6311287/img/spritearray.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /js/collectobj.js: -------------------------------------------------------------------------------- 1 | // Phaser3 example game 2 | // collectable object class 3 | // Typically you would have a separate class for enemies 4 | // The enemy class contains code for movement patterns etc. 5 | // This is to separate the code and keep it manageable and organised 6 | 7 | var TYPE_COIN = 1; 8 | var TYPE_BOMB = 2; 9 | 10 | class CollectObj extends Phaser.Physics.Arcade.Sprite { 11 | 12 | constructor(scene, x, y, texture, objtype) { 13 | // pass parameters to the class we are extending, call super 14 | super(scene, x, y, texture) 15 | 16 | // add to scene 17 | scene.add.existing(this) 18 | scene.physics.add.existing(this) 19 | 20 | // when scene updates, also update this object 21 | //scene.events.on('update', this.update, this) 22 | 23 | // save type for collision detection 24 | this.setData("type", objtype); // use data for overlap later 25 | 26 | // frame and animation for bomb or coin 27 | if (objtype == TYPE_BOMB) { 28 | // bomb 29 | this.setFrame('bomb'); 30 | } else { 31 | // coin, play animation with random frame offset, so that coins don't all spin exactly the same way 32 | var r = Phaser.Math.RND.between(0, 7); 33 | this.play('cointurn', null, r); // key, ignoreIfPlaying = null, startFrame = r; note: animation created in preloader scene 34 | }; 35 | } 36 | 37 | update() { 38 | //this.healthBar.follow(this) 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /js/gamescene.js: -------------------------------------------------------------------------------- 1 | // Phaser3 example game 2 | // main game scene 3 | 4 | var DIR_UP = 1; 5 | var DIR_DOWN = 2; 6 | var DIR_LEFT = 4; 7 | var DIR_RIGHT = 8; 8 | 9 | var GameScene = new Phaser.Class({ 10 | 11 | Extends: Phaser.Scene, 12 | 13 | initialize: 14 | 15 | function GameScene () 16 | { 17 | Phaser.Scene.call(this, { key: 'gamescene' }); 18 | }, 19 | 20 | preload: function () 21 | { 22 | 23 | }, 24 | 25 | create: function () 26 | { 27 | // add player sprite 28 | this.dude = this.physics.add.image(400, 200, 'sprites', 'dude'); 29 | //this.dude = this.add.sprite(400, 200, 'sprites', 'dude'); 30 | 31 | this.dude.setCollideWorldBounds(true); 32 | 33 | // add random coins and bombs 34 | this.gameitems = this.physics.add.group(); 35 | 36 | for (var i = 0; i < 20; i++) { 37 | // parameters 38 | var x = Phaser.Math.RND.between(0, 800); 39 | var y = Phaser.Math.RND.between(0, 600); 40 | var objtype = (i < 5 ? TYPE_BOMB : TYPE_COIN); 41 | 42 | // create custom sprite object 43 | var newobj = new CollectObj(this, x, y, 'sprites', objtype); 44 | 45 | this.gameitems.add(newobj); 46 | } 47 | 48 | // coin particles 49 | var sparks = this.add.particles('sprites'); 50 | this.coinspark = sparks.createEmitter({ 51 | frame: [ 'sparkle1', 'sparkle2' ], 52 | quantity: 15, 53 | scale: { start: 1.0, end: 0 }, 54 | on: false, 55 | speed: 200, 56 | lifespan: 500 57 | }); 58 | 59 | // bomb explosion particles (small) 60 | var expl1 = this.add.particles('sprites'); 61 | this.bombexpl1 = expl1.createEmitter({ 62 | frame: [ 'bombexpl1' ], 63 | frequency: 100, 64 | quantity: 10, 65 | scale: { start: 1.0, end: 0 }, 66 | speed: { min: -1000, max: 1000 }, 67 | lifespan: 800, 68 | on: false 69 | }); 70 | 71 | // bomb explosion particles (big) 72 | var expl2 = this.add.particles('sprites'); 73 | this.bombexpl2 = expl2.createEmitter({ 74 | frame: [ 'bombexpl2' ], 75 | quantity: 3, 76 | scale: { start: 2.0, end: 0 }, 77 | frequency: 500, 78 | on: false, 79 | speed: { min: -200, max: 200 }, 80 | lifespan: 1000 81 | }); 82 | 83 | // sound effects 84 | this.sfxcoin = this.sound.add('coin'); 85 | this.sfxbomb = this.sound.add('bomb'); 86 | 87 | // set up arcade physics, using `physics` requires "physics:{default: 'arcade'" when starting "new Phaser.Game(.." 88 | this.physics.add.overlap(this.dude, this.gameitems, this.doOverlapItem, null, this); 89 | 90 | // player input 91 | this.cursors = this.input.keyboard.createCursorKeys(); 92 | 93 | // quit to menu button 94 | this.btnquit = this.addButton(760, 40, 'sprites', this.doBack, this, 'btn_close_hl', 'btn_close', 'btn_close_hl', 'btn_close'); 95 | }, 96 | 97 | update: function (time, delta) 98 | { 99 | // reset velocity 100 | //this.dude.setVelocityX(0); 101 | //this.dude.setVelocityY(0); 102 | 103 | // keyboard input 104 | this.dude.setVelocity(0); 105 | if (this.cursors.up.isDown) this.movePlayer(DIR_UP); 106 | if (this.cursors.down.isDown) this.movePlayer(DIR_DOWN); 107 | if (this.cursors.left.isDown) this.movePlayer(DIR_LEFT); 108 | if (this.cursors.right.isDown) this.movePlayer(DIR_RIGHT); 109 | }, 110 | 111 | doOverlapItem: function (dud, obj) { 112 | console.log('doOverlapItem -- hit!'); 113 | 114 | if (obj.data.values.type == TYPE_COIN) { 115 | //if (obj.getData("type") == TYPE_COIN) { // does the exact same 116 | // coin 117 | // play coin sound 118 | this.sfxcoin.play(); 119 | 120 | // set emitter to coin position and emit particles 121 | this.coinspark.setPosition(obj.x, obj.y); 122 | this.coinspark.explode(); 123 | } else { 124 | // bomb 125 | // play bomb sound 126 | this.sfxbomb.play(); 127 | 128 | // set emitters for bomb explosion 129 | this.bombexpl1.setPosition(obj.x, obj.y); 130 | this.bombexpl1.explode(); 131 | 132 | this.bombexpl2.setPosition(obj.x, obj.y); 133 | this.bombexpl2.explode(); 134 | //this.bombexpl2.start(); 135 | 136 | // player dies 137 | this.playerDies(); 138 | }; 139 | 140 | // Completely destroy and remove object from memory 141 | obj.destroy(); 142 | 143 | // Hide the sprite and disable the body, 144 | // don't destroy sprite and potentially re-use memory at later time 145 | // when adding new sprites to this.gameitems 146 | //this.gameitems.killAndHide(obj); 147 | //obj.body.enable = false; 148 | }, 149 | 150 | playerDies: function () { 151 | 152 | // make player invisible 153 | this.dude.visible = false; 154 | this.dude.body.enable = false; 155 | 156 | // add game over text 157 | var txt = this.add.bitmapText(400, 300, 'fontwhite', 'Game over!'); 158 | txt.setOrigin(0.5).setCenterAlign(); 159 | 160 | // set gameover text as transparant, upside down and larger 161 | txt.setAlpha(0.0); 162 | txt.setAngle(180); 163 | txt.setScale(4.0, 4.0); 164 | 165 | // add twirl/zoom animation to gameover text 166 | var tw = this.tweens.add( 167 | { 168 | targets: txt, 169 | scaleX: 1.0, 170 | scaleY: 1.0, 171 | alpha: 1.0, 172 | angle: 0, 173 | ease: 'Power3', 174 | duration: 1000, // duration of animation; higher=slower 175 | delay: 500 // wait 500 ms before starting 176 | } 177 | ); 178 | }, 179 | 180 | 181 | movePlayer: function (dir) { 182 | 183 | // move the dude 184 | //if (dir == DIR_UP) this.dude.setVelocityY(-200); 185 | //if (dir == DIR_DOWN) this.dude.setVelocityY(+200); 186 | //if (dir == DIR_LEFT) this.dude.setVelocityX(-200); 187 | //if (dir == DIR_RIGHT) this.dude.setVelocityX(+200); 188 | if (dir == DIR_UP) this.dude.y -= 2; 189 | if (dir == DIR_DOWN) this.dude.y += 2; 190 | if (dir == DIR_LEFT) this.dude.x -= 2; 191 | if (dir == DIR_RIGHT) this.dude.x += 2; 192 | 193 | //var test = this.scene.getBounds(); 194 | // check limits 195 | if (this.dude.y < 0) this.dude.y = 0; 196 | if (this.dude.y > 600) this.dude.y = 600; 197 | if (this.dude.x < 0) this.dude.x = 0; 198 | if (this.dude.x > 800) this.dude.x = 800; 199 | }, 200 | 201 | doBack: function () 202 | { 203 | console.log('gamescene doBack was called!'); 204 | this.scene.start('mainmenu'); 205 | } 206 | 207 | }); 208 | -------------------------------------------------------------------------------- /js/menuscene.js: -------------------------------------------------------------------------------- 1 | // Phaser3 example game 2 | // mein menu scene 3 | 4 | var MainMenu = new Phaser.Class({ 5 | 6 | Extends: Phaser.Scene, 7 | 8 | initialize: 9 | 10 | function MainMenu () 11 | { 12 | Phaser.Scene.call(this, { key: 'mainmenu' }); 13 | }, 14 | 15 | preload: function () 16 | { 17 | }, 18 | 19 | create: function () 20 | { 21 | 22 | // add logo 23 | //this.sys.config.backgroundColor = '#f3cca3'; 24 | var logo = this.add.sprite(400, 200, 'sprites', 'phaser3'); 25 | 26 | // add tutorial and start button 27 | this.btnhelp = this.addButton(400-80, 400, 'sprites', this.doTutor, this, 'btn_quest_hl', 'btn_quest', 'btn_quest_hl', 'btn_quest'); 28 | this.btnstart = this.addButton(400+80, 400, 'sprites', this.doStart, this, 'btn_play_hl', 'btn_play', 'btn_play_hl', 'btn_play'); 29 | 30 | console.log('create is ready'); 31 | }, 32 | 33 | doTutor: function () 34 | { 35 | console.log('doTutor was called!'); 36 | this.scene.start('tutorscene'); 37 | }, 38 | 39 | doStart: function () 40 | { 41 | console.log('menuscene doStart was called!'); 42 | this.scene.start('gamescene'); 43 | } 44 | 45 | }); 46 | -------------------------------------------------------------------------------- /js/phaser_addon.js: -------------------------------------------------------------------------------- 1 | 2 | // add a button to a scene 3 | // similar to buttons in Phaser v2 4 | Phaser.Scene.prototype.addButton = function(x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame) 5 | { 6 | // add a button 7 | var btn = this.add.sprite(x, y, key, outFrame).setInteractive(); 8 | btn.on('pointerover', function (ptr, x, y) { this.setFrame(overFrame) } ); 9 | btn.on('pointerout', function (ptr) { this.setFrame(outFrame) } ); 10 | btn.on('pointerdown', function (ptr) { this.setScale(0.9, 0.9) } ); 11 | btn.on('pointerup', callback.bind(callbackContext)); 12 | 13 | return btn; 14 | }; 15 | -------------------------------------------------------------------------------- /js/preloader.js: -------------------------------------------------------------------------------- 1 | // Phaser3 example game 2 | // preloader and loading bar 3 | 4 | var Preloader = new Phaser.Class({ 5 | 6 | Extends: Phaser.Scene, 7 | 8 | initialize: 9 | 10 | function Preloader () 11 | { 12 | // note: the pack:{files[]} acts like a pre-preloader 13 | // this eliminates the need for an extra "boot" scene just to preload the loadingbar images 14 | Phaser.Scene.call(this, { 15 | key: 'preloader', 16 | pack: { 17 | files: [ 18 | { type: 'image', key: 'loadingbar_bg', url: 'img/loadingbar_bg.png' }, 19 | { type: 'image', key: 'loadingbar_fill', url: 'img/loadingbar_fill.png' } 20 | ] 21 | } 22 | }); 23 | }, 24 | 25 | setPreloadSprite: function (sprite) 26 | { 27 | this.preloadSprite = { sprite: sprite, width: sprite.width, height: sprite.height }; 28 | 29 | //sprite.crop(this.preloadSprite.rect); 30 | sprite.visible = true; 31 | 32 | // set callback for loading progress updates 33 | this.load.on('progress', this.onProgress, this ); 34 | this.load.on('fileprogress', this.onFileProgress, this ); 35 | }, 36 | 37 | onProgress: function (value) { 38 | 39 | if (this.preloadSprite) 40 | { 41 | // calculate width based on value=0.0 .. 1.0 42 | var w = Math.floor(this.preloadSprite.width * value); 43 | console.log('onProgress: value=' + value + " w=" + w); 44 | 45 | // sprite.frame.width cannot be zero 46 | //w = (w <= 0 ? 1 : w); 47 | 48 | // set width of sprite 49 | this.preloadSprite.sprite.frame.width = (w <= 0 ? 1 : w); 50 | this.preloadSprite.sprite.frame.cutWidth = w; 51 | 52 | // update screen 53 | this.preloadSprite.sprite.frame.updateUVs(); 54 | } 55 | }, 56 | 57 | onFileProgress: function (file) { 58 | console.log('onFileProgress: file.key=' + file.key); 59 | }, 60 | 61 | preload: function () 62 | { 63 | // setup the loading bar 64 | // note: images are available during preload because of the pack-property in the constructor 65 | this.loadingbar_bg = this.add.sprite(400, 300, "loadingbar_bg"); 66 | this.loadingbar_fill = this.add.sprite(400, 300, "loadingbar_fill"); 67 | this.setPreloadSprite(this.loadingbar_fill); 68 | 69 | // now load images, audio etc. 70 | // sprites, note: see free sprite atlas creation tool here https://www.leshylabs.com/apps/sstool/ 71 | this.load.atlas('sprites', 'img/spritearray.png', 'img/spritearray.json'); 72 | 73 | // font 74 | this.load.bitmapFont('fontwhite', 'img/fontwhite.png', 'img/fontwhite.xml'); 75 | 76 | // sound effects 77 | //this.load.audio('bg', [this.p('audio/bg.mp3'),this.p('audio/bg.ogg')]); 78 | this.load.audio('coin', ['snd/coin.mp3', 'snd/coin.ogg']); 79 | this.load.audio('bomb', ['snd/expl.mp3', 'snd/expl.ogg']); 80 | this.load.audio('btn', ['snd/btn.mp3', 'snd/btn.ogg']); 81 | 82 | // !! TESTING !! load the same image 500 times just to slow down the load and test the loading bar 83 | //for (var i = 0; i < 500; i++) { 84 | // this.load.image('testloading'+i, 'img/spritearray.png'); 85 | //}; 86 | // !! TESTING !! 87 | }, 88 | 89 | create: function () 90 | { 91 | // also create animations 92 | this.anims.create({ 93 | key: 'cointurn', 94 | frames: [ 95 | { key: 'sprites', frame: 'coin1' }, 96 | { key: 'sprites', frame: 'coin2' }, 97 | { key: 'sprites', frame: 'coin3' }, 98 | { key: 'sprites', frame: 'coin4' }, 99 | { key: 'sprites', frame: 'coin5' }, 100 | { key: 'sprites', frame: 'coin6' }, 101 | { key: 'sprites', frame: 'coin7' }, 102 | { key: 'sprites', frame: 'coin8' } 103 | ], 104 | frameRate: 15, 105 | repeat: -1 106 | }); 107 | 108 | console.log('Preloader scene is ready, now start the actual game and never return to this scene'); 109 | 110 | // dispose loader bar images 111 | this.loadingbar_bg.destroy(); 112 | this.loadingbar_fill.destroy(); 113 | this.preloadSprite = null; 114 | 115 | // start actual game 116 | this.scene.start('mainmenu'); 117 | } 118 | }); 119 | -------------------------------------------------------------------------------- /js/tutorial.js: -------------------------------------------------------------------------------- 1 | // Phaser3 example game 2 | // tutorial scene 3 | 4 | var TutorScene = new Phaser.Class({ 5 | 6 | Extends: Phaser.Scene, 7 | 8 | initialize: 9 | 10 | function TutorScene () 11 | { 12 | Phaser.Scene.call(this, { key: 'tutorscene' }); 13 | }, 14 | 15 | preload: function () 16 | { 17 | }, 18 | 19 | create: function () 20 | { 21 | // add logo 22 | //this.sys.config.backgroundColor = '#f3cca3'; 23 | var logo = this.add.sprite(400, 100, 'sprites', 'phaser3'); 24 | 25 | // text 26 | var txt = this.add.bitmapText(400, 300, 'fontwhite', 'This is an example game.\nTake a look at the code\nto see how it works.'); 27 | txt.setOrigin(0.5).setCenterAlign(); 28 | 29 | // back Button 30 | this.btnback = this.addButton(400, 520, 'sprites', this.doBack, this, 'btn_back_hl', 'btn_back', 'btn_back_hl', 'btn_back'); 31 | 32 | console.log('create is ready'); 33 | }, 34 | 35 | doBack: function () 36 | { 37 | console.log('doBack was called!'); 38 | this.scene.start('mainmenu'); 39 | } 40 | 41 | }); 42 | -------------------------------------------------------------------------------- /preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BdR76/Phaser3-example-game/0cf80f4892de834236147f97105369e1e6311287/preview.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Phaser3 game template example 2 | ============================= 3 | 4 | This is a [Phaser3](https://github.com/photonstorm/phaser) game template, a bare minimum game example. 5 | It is intended to show the structure of a typical Phaser3 game, 6 | and using some of the key features of Phaser. 7 | 8 | It's a code template showing all the important features needed to create a game in Phaser v3. 9 | Not an actual game but a starting point example. 10 | See also [this forum post](http://www.html5gamedevs.com/topic/38994-phaser3-game-example-using-scenes-a-preloader-and-a-loading-bar/). 11 | 12 | ![preview screenshot](/preview.png?raw=true "preview") 13 | 14 | This JavaScript game example shows: 15 | 16 | * Using different scenes 17 | * A loading bar 18 | * Sprite atlas loading 19 | * Sprite animation 20 | * Custom sprite object 21 | * Buttons similar to Phaser v2 22 | * Bitmaptext 23 | * Keyboard input 24 | * Mouse/touch input 25 | * Arcade overlap/collide 26 | * Sound effects 27 | * Scalemanager 28 | 29 | Questions, comments -- Bas de Reuver (bdr1976@gmail.com) 30 | -------------------------------------------------------------------------------- /snd/btn.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BdR76/Phaser3-example-game/0cf80f4892de834236147f97105369e1e6311287/snd/btn.mp3 -------------------------------------------------------------------------------- /snd/btn.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BdR76/Phaser3-example-game/0cf80f4892de834236147f97105369e1e6311287/snd/btn.ogg -------------------------------------------------------------------------------- /snd/coin.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BdR76/Phaser3-example-game/0cf80f4892de834236147f97105369e1e6311287/snd/coin.mp3 -------------------------------------------------------------------------------- /snd/coin.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BdR76/Phaser3-example-game/0cf80f4892de834236147f97105369e1e6311287/snd/coin.ogg -------------------------------------------------------------------------------- /snd/expl.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BdR76/Phaser3-example-game/0cf80f4892de834236147f97105369e1e6311287/snd/expl.mp3 -------------------------------------------------------------------------------- /snd/expl.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BdR76/Phaser3-example-game/0cf80f4892de834236147f97105369e1e6311287/snd/expl.ogg --------------------------------------------------------------------------------