Get the full commented source code of

HTML5 Suika Watermelon Game

Talking about Bouncy Light game, Game development, HTML5, Javascript and Phaser.

I am not quite secure Bouncy Light is the first game to introduce this way of controlling the player, but it’s a game built with BuildBox like the one covered in Dash N Blast series so it would be nice to see how difficult can be to code a game built with a “no coding” tool.

The main concept is very similar to Bouncing Ball 2 prototype, and it’s even easier because we do not have to change ball velocity, we just have to let it bounce and scroll the platforms only when the player clicks/taps the screen.

Look at the game:

Just click/tap and hold to make ball move, release to stop it.

Obviously the ball does not move, it’s the entire environment which moves towards the ball.

The source code is even easier than the one written to build Bouncing Ball 2, have a look:

var game;
var gameOptions = {
    bounceHeight: 300,
    ballGravity: 1200,
    ballPosition: 0.2,
    platformSpeed: 650,
    platformDistanceRange: [250, 450],
    platformHeightRange: [-50, 50],
    platformLengthRange: [40, 60],
    localStorageName: "bestballscore3"
}
window.onload = function() {
    let gameConfig = {
        type: Phaser.AUTO,
        backgroundColor:0x87ceeb,
        scale: {
            mode: Phaser.Scale.FIT,
            autoCenter: Phaser.Scale.CENTER_BOTH,
            parent: "thegame",
            width: 750,
            height: 500
        },
        physics: {
            default: "arcade"
        },
        scene: playGame
    }
    game = new Phaser.Game(gameConfig);
    window.focus();
}
class playGame extends Phaser.Scene{
    constructor(){
        super("PlayGame");
    }
    preload(){
        this.load.image("ground", "ground.png");
        this.load.image("ball", "ball.png");
    }
    create(){
        this.platformGroup = this.physics.add.group();
        this.ball = this.physics.add.sprite(game.config.width * gameOptions.ballPosition, game.config.height / 4 * 3 - gameOptions.bounceHeight, "ball");
        this.ball.body.gravity.y = gameOptions.ballGravity;
        this.ball.setBounce(1);
        this.ball.body.checkCollision.down = true;
        this.ball.body.checkCollision.up = false;
        this.ball.body.checkCollision.left = false;
        this.ball.body.checkCollision.right = false;
        this.ball.setSize(30, 50, true)
        let platformX = this.ball.x;
        for(let i = 0; i < 10; i++){
            let platform = this.platformGroup.create(platformX, game.config.height / 4 * 3 + Phaser.Math.Between(gameOptions.platformHeightRange[0], gameOptions.platformHeightRange[1]), "ground");
            platform.setOrigin(0.5, 1);
            platform.setImmovable(true);
            platform.displayWidth = Phaser.Math.Between(gameOptions.platformLengthRange[0], gameOptions.platformLengthRange[1]);
            platformX += Phaser.Math.Between(gameOptions.platformDistanceRange[0], gameOptions.platformDistanceRange[1]);
        }
        this.input.on("pointerdown", this.movePlatforms, this);
        this.input.on("pointerup", this.stopPlatforms, this);
        this.score = 0;
        this.topScore = localStorage.getItem(gameOptions.localStorageName) == null ? 0 : localStorage.getItem(gameOptions.localStorageName);
        this.scoreText = this.add.text(10, 10, "");
        this.updateScore(this.score);
    }
    updateScore(inc){
        this.score += inc;
        this.scoreText.text = "Score: " + this.score + "\nBest: " + this.topScore;
    }
    movePlatforms(){
        this.platformGroup.setVelocityX(-gameOptions.platformSpeed);
    }
    stopPlatforms(){
        this.platformGroup.setVelocityX(0);
    }
    getRightmostPlatform(){
        let rightmostPlatform = 0;
        this.platformGroup.getChildren().forEach(function(platform){
            rightmostPlatform = Math.max(rightmostPlatform, platform.x);
        });
        return rightmostPlatform;
    }
    update(){
        this.physics.world.collide(this.platformGroup, this.ball);
        this.platformGroup.getChildren().forEach(function(platform){
            if(platform.getBounds().right < 0){
                this.updateScore(1);
                platform.x = this.getRightmostPlatform() + Phaser.Math.Between(gameOptions.platformDistanceRange[0], gameOptions.platformDistanceRange[1]);
                platform.displayWidth = Phaser.Math.Between(gameOptions.platformLengthRange[0], gameOptions.platformLengthRange[1]);
            }
        }, this);
        if(this.ball.y > game.config.height){
            localStorage.setItem(gameOptions.localStorageName, Math.max(this.score, this.topScore));
            this.scene.start("PlayGame");
        }
    }
}

The original game has some more features such as different tile types, spikes and coins to collect.

We’ll see them in action in next step of the series, meanwhile download the source code.

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.