standalone character\u00a0download.<\/a> You can download those files if you wish to use them to follow along with this post.<\/p>\nLoad the Sprite Sheet<\/h3>\n
After copying the explorer.png and explorer.json files to the images folder, we now need to assign the hero key to the sprite sheet instead of our temporary hero.png. I’ve commented out the old code and added one to load the sprite sheet.<\/p>\n
preload: function() {\r\n game.load.image(\"ground\", \"images\/ground.png\");\r\n \/\/ game.load.image(\"hero\", \"images\/hero.png\");\r\n game.load.image(\"bar\", \"images\/powerbar.png\");\r\n game.load.image(\"block\", \"images\/block.png\");\r\n game.load.image(\"bird\", \"images\/bird.png\");\r\n game.load.image(\"playAgain\", \"images\/playAgain.png\");\r\n game.load.image(\"clouds\", \"images\/clouds.png\");\r\n\r\n game.load.atlasJSONHash('hero', 'images\/explorer.png', 'images\/explorer.json'); \r\n\r\n },<\/pre>\nAdd The Animations<\/h3>\n
Next, we need to add the animations. I’ve left out the slide and idle animations as we won’t be needing them.<\/p>\n
I’ve also added a support function called makeArray so we don’t have to type out [31,32,33,…<\/p>\n
Place this just after the create function<\/p>\n
makeArray:function(start,end)\r\n {\r\n var myArray=[];\r\n for (var i = start; i < end; i++) {\r\n myArray.push(i);\r\n }\r\n return myArray;\r\n }<\/pre>\nAdd these lines inside your create function to define the animations<\/p>\n
\u00a0this.hero.animations.add(\"die\",this.makeArray(0,10),12,false);\r\n this.hero.animations.add(\"jump\",this.makeArray(20,30),12,false); \r\n this.hero.animations.add(\"run\",this.makeArray(30,40),12,true);<\/pre>\nNext, we set the hero’s animation to running.<\/p>\n
this.hero.animations.play(\"run\");<\/pre>\nAt the end of the mouseUp function, we can play the jump animation<\/p>\n
this.hero.animations.play(\"jump\");<\/pre>\nTo detect when the hero is back on the ground we need to add a function to the collision detection between the hero and the ground called onGround<\/p>\n
game.physics.arcade.collide(this.hero, this.ground,this.onGround,null,this);<\/pre>\nIf the onGround\u00a0function\u00a0is called, it sets the hero’s animation back to running. For some reason, this was being called even before the hero sprite was being created, so I’ve put a quick if-then to check that the hero already exists.<\/p>\n
onGround()\r\n {\r\n if (this.hero)\r\n {\r\n this.hero.animations.play(\"run\");\r\n } \r\n }<\/pre>\nIn the delayOver function we will play the die animation for when the hero gets hit<\/p>\n
if (this.hero) {\r\nthis.hero.animations.play(\"die\");\r\nthis.hero.body.velocity.y = 100;\r\n}<\/pre>\nScaling the Runner<\/h3>\n
To make up for the changes in height I’ve put\u00a0the hero on the ground by changing:<\/p>\n
this.hero = game.add.sprite(game.width * .2, this.ground.y-25, \"hero\");<\/pre>\nto<\/p>\n
this.hero = game.add.sprite(game.width * .2, this.ground.y, \"hero\");<\/pre>\nAnd to resize the hero I’ve made it 1\/12 of the game’s with and scaled it proportionately and set the anchor so the foot is at the y position of the hero.<\/p>\n
this.hero.width=game.width\/12;\r\nthis.hero.scale.y=this.hero.scale.x;\r\nthis.hero.anchor.set(0.5,1);<\/pre>\nThis is the entire StateMain.js<\/p>\n
var StateMain = {\r\n preload: function() {\r\n game.load.image(\"ground\", \"images\/ground.png\");\r\n \/\/ game.load.image(\"hero\", \"images\/hero.png\");\r\n game.load.image(\"bar\", \"images\/powerbar.png\");\r\n game.load.image(\"block\", \"images\/block.png\");\r\n game.load.image(\"bird\", \"images\/bird.png\");\r\n game.load.image(\"playAgain\", \"images\/playAgain.png\");\r\n game.load.image(\"clouds\", \"images\/clouds.png\");\r\n game.load.atlasJSONHash('hero', 'images\/explorer.png', 'images\/explorer.json');\r\n },\r\n create: function() {\r\n this.clickLock = false;\r\n this.power = 0;\r\n \/\/turn the background sky blue\r\n game.stage.backgroundColor = \"#00ffff\";\r\n \/\/add the ground\r\n this.ground = game.add.sprite(0, game.height * .9, \"ground\");\r\n \/\/add the hero in \r\n this.hero = game.add.sprite(game.width * .2, this.ground.y, \"hero\");\r\n \/\/make animations\r\n this.hero.animations.add(\"die\", this.makeArray(0, 10), 12, false);\r\n this.hero.animations.add(\"jump\", this.makeArray(20, 30), 12, false);\r\n this.hero.animations.add(\"run\", this.makeArray(30, 40), 12, true);\r\n this.hero.animations.play(\"run\");\r\n this.hero.width = game.width \/ 12;\r\n this.hero.scale.y = this.hero.scale.x;\r\n this.hero.anchor.set(0.5, 1);\r\n \/\/add the power bar just above the head of the hero\r\n this.powerBar = game.add.sprite(this.hero.x + this.hero.width \/ 2, this.hero.y - this.hero.height \/ 2, \"bar\");\r\n this.powerBar.width = 0;\r\n \/\/add the clouds\r\n this.clouds = game.add.sprite(0, 0, \"clouds\");\r\n this.clouds.width = game.width;\r\n \/\/start the physics engine\r\n game.physics.startSystem(Phaser.Physics.ARCADE);\r\n \/\/enable the hero for physics\r\n game.physics.enable(this.hero, Phaser.Physics.ARCADE);\r\n game.physics.enable(this.ground, Phaser.Physics.ARCADE);\r\n \/\/game.physics.arcade.gravity.y = 100;\r\n this.hero.body.gravity.y = 200;\r\n this.hero.body.collideWorldBounds = true;\r\n \/\/this.hero.body.bounce.set(0, .2);\r\n this.ground.body.immovable = true;\r\n \/\/record the initial position\r\n this.startY = this.hero.y;\r\n \/\/set listeners\r\n game.input.onDown.add(this.mouseDown, this);\r\n this.blocks = game.add.group();\r\n this.makeBlocks();\r\n this.makeBird();\r\n },\r\n makeArray: function(start, end) {\r\n var myArray = [];\r\n for (var i = start; i < end; i++) { myArray.push(i); } return myArray; }, mouseDown: function() { if (this.clickLock == true) { return; } if (this.hero.y != this.startY) { return; } game.input.onDown.remove(this.mouseDown, this); this.timer = game.time.events.loop(Phaser.Timer.SECOND \/ 1000, this.increasePower, this); game.input.onUp.add(this.mouseUp, this); }, mouseUp: function() { game.input.onUp.remove(this.mouseUp, this); this.doJump(); game.time.events.remove(this.timer); this.power = 0; this.powerBar.width = 0; game.input.onDown.add(this.mouseDown, this); this.hero.animations.play(\"jump\"); }, increasePower: function() { this.power++; this.powerBar.width = this.power; if (this.power > 50) {\r\n this.power = 50;\r\n }\r\n },\r\n doJump: function() {\r\n this.hero.body.velocity.y = -this.power * 12;\r\n },\r\n makeBlocks: function() {\r\n this.blocks.removeAll();\r\n var wallHeight = game.rnd.integerInRange(1, 4);\r\n for (var i = 0; i < wallHeight; i++) {\r\n var block = game.add.sprite(0, -i * 50, \"block\");\r\n this.blocks.add(block);\r\n }\r\n this.blocks.x = game.width - this.blocks.width\r\n this.blocks.y = this.ground.y - 50;\r\n \/\/\r\n \/\/Loop through each block\r\n \/\/and apply physics\r\n this.blocks.forEach(function(block) {\r\n \/\/enable physics\r\n game.physics.enable(block, Phaser.Physics.ARCADE);\r\n \/\/set the x velocity to -160\r\n block.body.velocity.x = -150;\r\n \/\/apply some gravity to the block\r\n \/\/not too much or the blocks will bounce\r\n \/\/against each other\r\n block.body.gravity.y = 4;\r\n \/\/set the bounce so the blocks\r\n \/\/will react to the runner\r\n block.body.bounce.set(1, 1);\r\n });\r\n },\r\n makeBird: function() {\r\n \/\/if the bird already exists \r\n \/\/destory it\r\n if (this.bird) {\r\n this.bird.destroy();\r\n }\r\n \/\/pick a number at the top of the screen\r\n \/\/between 10 percent and 40 percent of the height of the screen\r\n var birdY = game.rnd.integerInRange(game.height * .1, game.height * .4);\r\n \/\/add the bird sprite to the game\r\n this.bird = game.add.sprite(game.width + 100, birdY, \"bird\");\r\n \/\/enable the sprite for physics\r\n game.physics.enable(this.bird, Phaser.Physics.ARCADE);\r\n \/\/set the x velocity at -200 which is a little faster than the blocks\r\n this.bird.body.velocity.x = -200;\r\n \/\/set the bounce for the bird\r\n this.bird.body.bounce.set(2, 2);\r\n },\r\n onGround() {\r\n if (this.hero) {\r\n this.hero.animations.play(\"run\");\r\n }\r\n },\r\n update: function() {\r\n game.physics.arcade.collide(this.hero, this.ground, this.onGround, null, this);\r\n \/\/\r\n \/\/collide the hero with the blocks\r\n \/\/\r\n game.physics.arcade.collide(this.hero, this.blocks, this.delayOver, null, this);\r\n \/\/\r\n \/\/collide the blocks with the ground\r\n \/\/\r\n game.physics.arcade.collide(this.ground, this.blocks);\r\n \/\/\r\n \/\/when only specifying one group, all children in that\r\n \/\/group will collide with each other\r\n \/\/\r\n game.physics.arcade.collide(this.blocks);\r\n \/\/colide the hero with the bird\r\n \/\/\r\n game.physics.arcade.collide(this.hero, this.bird, this.delayOver, null, this);\r\n \/\/\r\n \/\/get the first child\r\n var fchild = this.blocks.getChildAt(0);\r\n \/\/if off the screen reset the blocks\r\n if (fchild.x < -game.width) {\r\n this.makeBlocks();\r\n }\r\n \/\/if the bird has flown off screen\r\n \/\/reset it\r\n if (this.bird.x < 0) {\r\n this.makeBird();\r\n }\r\n if (this.hero.y < this.hero.height) {\r\n this.hero.body.velocity.y = 200;\r\n this.delayOver();\r\n }\r\n },\r\n delayOver: function() {\r\n this.clickLock = true;\r\n if (this.hero) {\r\n this.hero.animations.play(\"die\");\r\n this.hero.body.velocity.y = 100;\r\n }\r\n game.time.events.add(Phaser.Timer.SECOND, this.gameOver, this);\r\n },\r\n gameOver: function() {\r\n game.state.start(\"StateOver\");\r\n }\r\n}<\/pre>\nHere is the result:<\/p>\n
<\/p>\n
Click Here to Play<\/a><\/p>\n\t