HTML5 “Down the Mountain” prototype made with Phaser updated: adding a player character, recycling assets and getting rid of arrays

Read all posts about "" game
Here we go with another step in Down the Mountain series, introducing three new features: 1) A player character. This time you control a real (fake) 3D character going down the mountain. Being some kind of isometric game using hexagon rather than a real 3D game, we can’t simply flip the sprite when we move to the left or to the right, because of the source of light. I needed to create two frames, one for the character facing left, one for the character facing right. 2) I am recycling assets rather than destroying old hexagons and creating new ones. Now hexagons which disappear from the top are simply moved to the bottom. This way the game does not need to create any more sprites other than the ones already in the game at the moment it starts. This will allow us to save memory and CPU, especially when dealing with mobile devices. 3) The code does not rely anymore on arrays to save the game field. Although this is not a killer improvement, it will make you easier to port the game into other language or frameworks. Let’s have a look at the game:
Tap or click on the left or on the right half of the canvas to move the player down left/right. The source code is still a bit in need to be otpimized, so it does not have comments yet, but it’s not that hard to understand:
var game;
var hexagonWidth = 70;
var hexagonHeight = 80;
var minRow = 0;
var gridSizeX = 5;
var gridSizeY = 14;
var marker;
var hexagonGroup;
var playerCol = 2;
var playerRow = 0;
var playerMove = true;

window.onload = function() {
    game = new Phaser.Game(480, 480);
    game.state.add("PlayGame", playGame);
    game.state.start("PlayGame");
}
var playGame = function(game){}
playGame.prototype = {
    preload: function(){
        game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
        game.scale.pageAlignHorizontally = true;
        game.scale.pageAlignVertically = true;
        game.load.image("hexagon", "hexagon.png");
        game.load.spritesheet("marker", "marker.png", 56, 64);
    },
    create: function(){
        this.hexagonPool = [];
        hexagonGroup = game.add.group();
        game.stage.backgroundColor = "#ffffff";
        for(var i = 0; i < gridSizeY; i ++){
            this.addHexagonRow(i);
        }
        hexagonGroup.x = (game.width - hexagonWidth * gridSizeX) / 2;
        hexagonGroup.y = 20;
        marker = game.add.sprite(hexagonGroup.width / 2, 6, "marker");
        marker.anchor.setTo(0.5);
        hexagonGroup.add(marker);
        game.input.onDown.add(function(e){
            if(playerMove){
                if(e.x < (game.width / 2) && (playerCol > 0 || (playerRow % 2 == 1))){
                    placeMarker(playerCol - (1 - playerRow % 2), playerRow + 1);
                    marker.frame = 0;
                }
                if(e.x >= (game.width / 2) &&  playerCol < gridSizeX - 1){
                    placeMarker(playerCol + (playerRow % 2), playerRow + 1);
                    marker.frame = 1;
                }
            }
        }, this)
    },
    update: function(){
        if(marker.world.y > 60){
            var distance = 60 - marker.world.y
            hexagonGroup.y += distance / 25;
        }
        hexagonGroup.forEach(function(item){
            if(item.world.y < 0){
                item.y += hexagonHeight * (gridSizeY * 3 / 4);
                item.row += gridSizeY;
                item.children[0].text = item.row + "," + item.col;
            }
        }, this);
    },
    addHexagonRow: function(i){
        for(var j = 0; j < gridSizeX - i % 2; j ++){
            var hexagonX = hexagonWidth * j + (hexagonWidth / 2) * (i % 2);
            var hexagonY = hexagonHeight * i / 4 * 3;
            var hexagon = game.add.sprite(hexagonX, hexagonY, "hexagon");
            hexagon.row = i;
            hexagon.col = j;
            var hexagonText = game.add.text(0 + hexagonWidth / 3 + 5, 0 + 15, i + "," + j);
            hexagonText.font = "arial";
            hexagonText.align = "center";
            hexagonText.fontSize = 10;
            hexagon.addChild(hexagonText);
            hexagonGroup.add(hexagon);
        }
    }
}
function placeMarker(posX, posY){
    playerRow = posY;
    playerCol = posX;
    var nextX = hexagonWidth * (2 * posX + 1 + posY % 2) / 2;
    var nextY = hexagonHeight * (3 * posY + 1) / 4 - 14;
    playerMove = false;
    var bezierX = hexagonWidth;
    if(marker.x > nextX){
        bezierX *= -1;
    }
    var playerTween = game.add.tween(marker).to({
        x: [marker.x, marker.x + bezierX, nextX, nextX],
        y: [marker.y, marker.y, nextY, nextY]
    }, 100, Phaser.Easing.Linear.None, true).interpolation(function(v, k){
        return Phaser.Math.bezierInterpolation(v, k);
    });
    playerTween.onComplete.add(function(){
        playerMove = true;
    });
    marker.bringToTop();
}
Next time I’ll introduce some obstacles and start commenting the code, meanwhile download the source code.

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