Do you like my tutorials?

Then consider supporting me on Ko-fi

Talking about Circular endless runner game, Game development, HTML5, Javascript and Phaser.

Today I am coming with something quite new, I’ve seen a lot of games using this kind of movement, but now I can’t find any of them to show you, I also googled for it with no luck, so if you know a game which reminds this prototype, just let me know. Anyway, it’s a circular endless runner, which means you character will run on some kind of planet, and can also jump or double jump, this way:
Click or tap to jump and double jump. The funny part is I built it without using any physics engine, but only good old trigonometry. Player position and rotation are calculated frame by frame using sine and cosine, while jumps and double jumps are just an offset to be added to player position which increases with a “force” and decreases due to “gravity”. Obviously there is no “force” and there isn’t any “gravity”, but the game works well anyway, as it’s meant to be an hyper casual game where a perfect physics simulation is not required. The source code, with room for customization – you can even set jump and double jump to apply different “forces” – is short and still uncommented although easy to understand:
var game;

var gameOptions = {
    bigCircleRadius: 500,
    playerRadius: 50,
    playerSpeed: 1,
    worldGravity: 0.8,
    jumpForce: [12, 8]
}

window.onload = function() {
    var gameConfig = {
        thpe: Phaser.CANVAS,
        width: 800,
        height: 800,
        scene: [playGame]
    }
    game = new Phaser.Game(gameConfig);
    window.focus()
    resize();
    window.addEventListener("resize", resize, false);
}
class playGame extends Phaser.Scene{
    constructor(){
        super("PlayGame");
    }
    preload(){
        this.load.image("bigcircle", "bigcircle.png");
        this.load.image("player", "player.png");
    }
    create(){
        this.bigCircle = this.add.sprite(game.config.width / 2, game.config.height / 2, "bigcircle");
        this.bigCircle.displayWidth = gameOptions.bigCircleRadius;
        this.bigCircle.displayHeight = gameOptions.bigCircleRadius;
        this.player = this.add.sprite(game.config.width / 2, (game.config.height - gameOptions.bigCircleRadius - gameOptions.playerRadius) / 2, "player");
        this.player.displayWidth = gameOptions.playerRadius;
        this.player.displayHeight = gameOptions.playerRadius;
        this.player.currentAngle = -90;
        this.player.jumpOffset = 0;
        this.player.jumps = 0;
        this.player.jumpForce = 0;
        this.input.on("pointerdown", function(e){
            if(this.player.jumps < 2){
                this.player.jumps ++;
                this.player.jumpForce = gameOptions.jumpForce[this.player.jumps - 1];
            }
        }, this);
    }
    update(){
        if(this.player.jumps > 0){
            this.player.jumpOffset += this.player.jumpForce;
            this.player.jumpForce -= gameOptions.worldGravity;
            if(this.player.jumpOffset < 0){
                this.player.jumpOffset = 0;
                this.player.jumps = 0;
                this.player.jumpForce = 0;
            }
        }
        this.player.currentAngle = Phaser.Math.Angle.WrapDegrees(this.player.currentAngle + gameOptions.playerSpeed);
        var radians = Phaser.Math.DegToRad(this.player.currentAngle);
        var distanceFromCenter = (gameOptions.bigCircleRadius + gameOptions.playerRadius) / 2 + this.player.jumpOffset;
        this.player.x = this.bigCircle.x + distanceFromCenter * Math.cos(radians);
        this.player.y = this.bigCircle.y + distanceFromCenter * Math.sin(radians);
        var revolutions = gameOptions.bigCircleRadius / gameOptions.playerRadius + 1;
        this.player.angle = this.player.currentAngle * revolutions;
    }
}

// pure javascript to scale the game
function resize() {
    var canvas = document.querySelector("canvas");
    var windowWidth = window.innerWidth;
    var windowHeight = window.innerHeight;
    var windowRatio = windowWidth / windowHeight;
    var gameRatio = game.config.width / game.config.height;
    if(windowRatio < gameRatio){
        canvas.style.width = windowWidth + "px";
        canvas.style.height = (windowWidth / gameRatio) + "px";
    }
    else{
        canvas.style.width = (windowHeight * gameRatio) + "px";
        canvas.style.height = windowHeight + "px";
    }
}
And we have the basics for a circular endless runner in about 30 lines of code – the ones used in create and update methods. How would you continue the game? Let me know and I will be glad to add features to the prototype, without using any physics engine, 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.