Sign in to follow this  
karneekarnay

Endless Runner Problem

Recommended Posts

Hi Guys, I'm following the tutorial to create an Endless Runner game in Phaser (Link Here)

I've followed the tutorial so far, but for whatever reason the blocks I've added that should be moving towards the player, will not move. Here is my game code below:

 

/*global Phaser*/

class Game extends Phaser.State
{
    preload() {
        
        this.style = { font: "30px Courier", fill: "#000", boundsAlignH: "center", boundsAlignV: "middle" };
        this.loadingLabel = this.game.add.text(this.game.world.centerX, this.game.world.centerY, "loading...",this.style);
        this.loadingLabel.anchor.setTo(0.5);
         
    }
 
    create() {
        //  A simple background for our game
        this.game.add.sprite(0, 0, 'sky');
    
        //  The platforms group contains the ground and the 2 ledges we can jump on
        this.platforms = this.game.add.group();
    
        //  We will enable physics for any object that is created in this group
        this.platforms.enableBody = true;
    
        // Here we create the ground.
        this.ground = this.platforms.create(0, this.game.world.height - 64, 'ground');
    
        //  Scale it to fit the width of the game (the original sprite is 400x32 in size)
        this.ground.scale.setTo(2, 2);
    
        this.power = 0;
        
        //add the hero in 
        this.hero = this.game.add.sprite(32, this.game.world.height - 89, "hero");
        //add the power bar just above the head of the hero
        this.powerBar = this.game.add.sprite(this.hero.x + 25, this.hero.y - 25, "star");
        this.powerBar.width = 0;
        
        //start the physics engine
        this.game.physics.startSystem(Phaser.Physics.ARCADE);
        //enable the hero for physics
        this.game.physics.enable(this.hero, Phaser.Physics.ARCADE);
        this.game.physics.enable(this.ground, Phaser.Physics.ARCADE);
        
        this.hero.body.gravity.y = 200;
        this.hero.body.collideWorldBounds = true;
        //this.hero.body.bounce.set(0, 0.2);
        
        //  This stops it from falling away when you jump on it
        this.ground.body.immovable = true;
        //record the initial position
        this.startY = this.hero.y;
    
        //set listeners
        this.game.input.onDown.add(this.mouseDown, this);
        
        this.blocks = this.game.add.group();
        this.makeBlocks();
    }
 
    update() {
        this.game.physics.arcade.collide(this.hero, this.ground);

        //
        //collide the hero with the blocks
        //
        this.game.physics.arcade.collide(this.hero, this.blocks);
        //
        //colide the blocks with the ground
        //
        this.game.physics.arcade.collide(this.ground, this.blocks);
        //
        //when only specifying one group, all children in that
        //group will collide with each other
        //
        this.game.physics.arcade.collide(this.blocks);
        //
        //get the first child
        var fchild = this.blocks.getChildAt(0);
        //if off the screen reset the blocks
        if (fchild.x < -this.game.width) {
            this.moveBlocks();
        }
    }
    
    mouseDown () 
    {
        if (this.hero.y != this.startY) {
            return;
        }
        this.game.input.onDown.remove(this.mouseDown, this);
        this.timer = this.game.time.events.loop(Phaser.Timer.SECOND / 1000, this.increasePower, this);
        this.game.input.onUp.add(this.mouseUp, this);
    }
    mouseUp () {
        this.game.input.onUp.remove(this.mouseUp, this);
        this.doJump();
        this.game.time.events.remove(this.timer);
        this.power = 0;
        this.powerBar.width = 0;
        this.game.input.onDown.add(this.mouseDown, this);
    }
    increasePower() {
        this.power++;
        this.powerBar.width = this.power;
        if (this.power> 50) {
            this.power = 50;
        }
    }
    doJump() {
        this.hero.body.velocity.y = -this.power * 12;
    }
    
    makeBlocks() {
        this.blocks.removeAll();
        this.wallHeight=this.game.rnd.integerInRange(1, 4);
        this.wallPosition=this.blockOffset();
        for (var i = 0; i < this.wallHeight; i++) {
            this.block = this.game.add.sprite(this.wallPosition, (this.game.height-89)-i * 25 , "block");
            this.blocks.add(this.block);
        }
    }
    
    moveBlocks()
    {
        this.blocks.x = this.game.width - this.blocks.width
        this.blocks.y = this.ground.y - 50;
        //
        //Loop through each block
        //and apply physics
        var container = this;
        this.blocks.forEach(function(block) {
            //enable physics
            container.game.physics.enable(block, Phaser.Physics.ARCADE);
            //set the x velocity to -160
            block.body.velocity.x = -150;
            //apply some gravity to the block
            //not too much or the blocks will bounce
            //against each other
            block.body.gravity.y = 4;
            //set the bounce so the blocks
            //will react to the runner
            block.body.bounce.set(1, 1);
        });
    }
    
   blockOffset()
    {
        return this.hero.x + 100;
    }
}

The important part is the moveBlocks() function. that's where it should be moving the blocks, but it's not. 

 

Also is there a cleaner way to refer to the original object instead of using a contrainer var?

Share this post


Link to post
Share on other sites

Looking at the names of the functions and the comment, I guess 

//if off the screen reset the blocks
        if (fchild.x < -this.game.width) {
            this.moveBlocks();
        }
    }
    

Should be 

//if off the screen reset the blocks
        if (fchild.x < -this.game.width) {
            this.makeBlocks();
        }
    }
    

(Note: it's makeBlocks not moveBlocks) 

Because that's the part were you destroy old blocks and create new blocks (look at the tutorial again).

The moveBlocks call should probably go after that if statement but you should recheck the tutorial (didn't find the call but I didn't spend to much time searching ether...) 

Share this post


Link to post
Share on other sites
1 hour ago, michebn said:

Looking at the names of the functions and the comment, I guess 


//if off the screen reset the blocks
        if (fchild.x < -this.game.width) {
            this.moveBlocks();
        }
    }
    

Should be 


//if off the screen reset the blocks
        if (fchild.x < -this.game.width) {
            this.makeBlocks();
        }
    }
    

(Note: it's makeBlocks not moveBlocks) 

Because that's the part were you destroy old blocks and create new blocks (look at the tutorial again).

The moveBlocks call should probably go after that if statement but you should recheck the tutorial (didn't find the call but I didn't spend to much time searching ether...) 

Thanks michebn.

 

The moveblock was my attempt to solve an earlier problem. If I attempt to combine the make & make functions into one, as per the tutorial.

makeBlocks() {
        this.blocks.removeAll();
        this.wallHeight=this.game.rnd.integerInRange(1, 4);
        this.wallPosition=this.blockOffset();
        for (var i = 0; i < this.wallHeight; i++) {
            this.block = this.game.add.sprite(this.wallPosition, (this.game.height-89)-i * 25 , "block");
            this.blocks.add(this.block);
        }
        
        this.blocks.x = this.game.width - this.blocks.width
        this.blocks.y = this.ground.y - 50;
        //
        //Loop through each block
        //and apply physics
        var container = this;
        this.blocks.forEach(function(block) {
            //enable physics
            container.game.physics.enable(block, Phaser.Physics.ARCADE);
            //set the x velocity to -160
            block.body.velocity.x = -150;
            //apply some gravity to the block
            //not too much or the blocks will bounce
            //against each other
            block.body.gravity.y = 4;
            //set the bounce so the blocks
            //will react to the runner
            block.body.bounce.set(1, 1);
        });
    }

 I am unable to create the sprites or if I do, I can't see them. The tutorial want's the function to look like this:

makeBlocks() {
        this.blocks.removeAll();
        this.wallHeight=this.game.rnd.integerInRange(1, 4);
        this.wallPosition=this.blockOffset();
        for (var i = 0; i < this.wallHeight; i++) {
            this.block = this.game.add.sprite(this.wallPosition, (this.game.height-89)-i * 25 , "block");
            this.blocks.add(this.block);
        }
        
        this.blocks.x = this.game.width - this.blocks.width
        this.blocks.y = this.ground.y - 50;
        //
        //Loop through each block
        //and apply physics
       
        this.blocks.forEach(function(block) {
            //enable physics
            this.game.physics.enable(block, Phaser.Physics.ARCADE);
            //set the x velocity to -160
            block.body.velocity.x = -150;
            //apply some gravity to the block
            //not too much or the blocks will bounce
            //against each other
            block.body.gravity.y = 4;
            //set the bounce so the blocks
            //will react to the runner
            block.body.bounce.set(1, 1);
        });
    }

Note the var container line and it's reference is gone.  When I do this, I get complaints about the this.game.physics.enable(block, Phaser.Physics.ARCADE); line. Specifically that the game object can't be found. 

Any ideas?

Share this post


Link to post
Share on other sites

I'm still new to js so I can't help you with the this vs. Container problem.

From an algorithm point of view here is what I would try:

First: In your create function, call makeBlocks and moveBlocks because currently, you initialize your blocks but don't add force to them so the don't move and your if clause will never be true (the affor mentioned if clause is true if the block has moved out of the left side, so no movement no if) 

Second: in the if clause you have to call makeBlocks as well (bevor the move call) so that a new row of blocks will be created (and force added to them).

I.e. The make and the move call always have to go together otherwise you ether add new blocks without force (movement) or you set movement to old / gone blocks 

 

Edit: you might actually not get an error currently because your move function is never called... 

Share this post


Link to post
Share on other sites

Midway through writing this saying that I think you've got it right I realised wtf went wrong. 

 

KIDS. LET THIS BE A LESSON TO YOU ALL. NEVER COPY AND PASTE FROM THE TUTORIAL UNLESS YOU HAVE TO. 

 

The issue was that my code was place the sprites underground... The container var worked fine. It was just that because I've been trying to make the code work with a template I made earlier, I made changes the differed from the tutorial, so the Y & X placements were completely off. I fixed up the function, changed the x & y and it worked fine. 

 

@michebn I wouldn't have got here without you. Cheers bud. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.