asalinasci

Problem with camera and moveToXy

Recommended Posts

(Sorry for my English) In a Phaser game,  I have some sprites moving automaticly and randomly in a world bigger than the game size using moveToXY. And they work fine.

I add an sprite "player" controlled with the mouse and the camera follows it. When this "player" moves the camera, the other sprites start to "trembling" without moving. If the "player" return to the initial screen, every sprites start to moving fine. 

It looks like the camera moving affect to moveToXY. Is this possible? Is there a way to avoid this behaviour?

Share this post


Link to post
Share on other sites
2 hours ago, asalinasci said:

It looks like the camera moving affect to moveToXY. Is this possible? Is there a way to avoid this behaviour?

Did you apply camera.follow() to the other sprites as well?

Can you please show us some code? :)

Share this post


Link to post
Share on other sites

I don't apply camera.follow() to the other objects. 

This is the code for the objects randomly moving:

var Burbuja=function(radio, color, auxGame){    
    this.radio=radio||50;
    this.color=color||0x00ff00;
    var gr=auxGame.add.graphics();
    gr.beginFill(this.color);           
    gr.drawRect(0, 0, this.radio, this.radio);
    
    Phaser.Sprite.call(this, auxGame, Math.random()*750, 630 + Math.random()*250, gr.generateTexture());               
    this.anchor.setTo(0.5, 0.5);    
    gr.destroy();
    
    auxGame.physics.enable(this, Phaser.Physics.ARCADE);
    auxGame.add.existing(this);
    
    this.auxGame=auxGame;
    this.TURN_RATE = 2;
    this.velocidad=150;
    
    this.enableBody = true;
    this.physicsBodyType = Phaser.Physics.ARCADE;
    //this.body.collideWorldBounds=true;
    
    this.objetivo=new Phaser.Point();
    this.body.y=600+Math.random()*260;
    this.body.x=50+(Math.random()*this.auxGame.world.width-50);
    this.nuevoObjetivo();
    
    this.volando=true;
}

Burbuja.prototype=Object.create(Phaser.Sprite.prototype);
Burbuja.prototype.constructor=Burbuja;

Burbuja.prototype.nuevoObjetivo=function(){ //random change fly direction
    var signo=this.auxGame.rnd.integerInRange(0, 1)?-1:1;
    var inc= signo*this.auxGame.rnd.integerInRange(75, 250);
    this.objetivo.x=((this.body.x + inc)<this.auxGame.world.width && (this.body.x + inc)>0)?this.body.x+inc:this.body.x-inc;
    
    signo=this.auxGame.rnd.integerInRange(0, 1)?-1:1;
    inc= signo*this.auxGame.rnd.integerInRange(75, 250);
    this.objetivo.y=((this.body.y + inc)<this.auxGame.world.height && (this.body.y + inc)>0)?this.body.y+inc:this.body.y-inc;

};
Burbuja.prototype.update=function(){
    if(this.volando){
        this.auxGame.physics.arcade.moveToXY(this, this.objetivo.x, this.objetivo.y, this.velocidad);
        
        var targetAngle = this.auxGame.math.angleBetween(this.body.x, this.body.y, this.objetivo.x, this.objetivo.y)+Math.PI/2;
        if (this.rotation !== targetAngle) {
            var delta = targetAngle - this.rotation;

            if (delta > Math.PI) delta -= Math.PI * 2;
            if (delta < -Math.PI) delta += Math.PI * 2;

            if (delta > 0) {                
                this.angle += this.TURN_RATE ;
            } else {                
                this.angle -= this.TURN_RATE ;
            }

            if (Math.abs(delta) < this.game.math.degToRad(this.TURN_RATE)) {
                this.rotation = targetAngle;
            }            
        }
        
        if(Juego.puntoDentro(this.objetivo,this)){  //when arrives to the target, random generate a new targete
            this.nuevoObjetivo();            
        }

    }
}

Share this post


Link to post
Share on other sites

(Sorry for don't use the code tag, it's my first time in the forum)

this.jugador=this.game.add.sprite(Juego._WIDTH*.5, Juego._HEIGHT, gr.generateTexture());
this.jugador.radio=100;
this.game.physics.enable(this.jugador, Phaser.Physics.ARCADE);
this.jugador.enableBody = true;
this.jugador.physicsBodyType = Phaser.Physics.ARCADE;
this.jugador.body.collideWorldBounds=true;
this.jugador.anchor.setTo(0.5, 0.5);    
gr.destroy();
       
this.game.world.resize(1920, 960);
this.game.camera.follow(this.jugador);

And the update function:

update: function(){  
        var distance = this.game.math.distance(this.jugador.body.x, this.jugador.body.y, this.camera.x + this.game.input.x, this.camera.y + this.game.input.y);

        // If the distance > MIN_DISTANCE then move
        if (distance > this.MIN_DISTANCE) {
            // Calculate the angle to the target
            var rotation = this.game.math.angleBetween(this.jugador.body.x, this.jugador.body.y, this.camera.x + this.game.input.x, this.camera.y + this.game.input.y);

            // Calculate velocity vector based on rotation and this.MAX_SPEED
            this.jugador.body.velocity.x = Math.cos(rotation) * this.MAX_SPEED;
            this.jugador.body.velocity.y = Math.sin(rotation) * this.MAX_SPEED;
        } else {
            this.jugador.body.velocity.setTo(0, 0);
        }
        
    },

 

Share this post


Link to post
Share on other sites

Can you put a console.log function in this code?

 if(Juego.puntoDentro(this.objetivo,this)){  //when arrives to the target, random generate a new targete
  this.nuevoObjetivo();            
}

Or, put a console.log in nuevoObjectivo, to see how often it is getting called. I wonder if something is wrong with puntoDentro? Like it's paying attention to the camera coordinates somehow?

Share this post


Link to post
Share on other sites

I have put a console.log inside the "if" and before "this.nuevoObjetivo". When starts the "problem", never execute the console.log. It is like when this happen, the x properties of the objects increment/decrement constantly.

I put "this.game.camera.x++" without condition, always execute. 

I'm going to make my own "moveToXY" and give it a try.

Share this post


Link to post
Share on other sites

You should know that the update() executes a frame per second meaning that it is running game.camera.x++ every frame per second which is causing your problem. Keep that in mind. Let me do a sandbox for you and we can see if that sorts your problem. brb.

I will load a sprite that is moved using moveToXY() and another that I will move using the mouse pointer and use a game.follow() on him :)

Share this post


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

Thanks. I will try another way to do the same. 

I'm sorry I was in a meeting.

Here's what I'd suggest you try.

Create 2 sprites. 1 is moved using the moveToXY() function and the other moves to the mouse pointer (where you click). Use camera.follow() on the latter.

When you use moveToXY(), you can set the time you want your sprite to take to reach its destination. Something like this

game.physics.arcade.moveToXY(sprite,x,y,velocity,time in ms);

Now usually the sprite doesn't stop unless you tell it to so assuming you do something like this

game.physics.arcade.moveToXY(sprite,200,200,20,2000);

You're basically telling the sprite to move to (200,200) at a velocity of 20 within 2 seconds.

Just do a timeout that sets the sprite's velocity to 0 in order to stop the sprite from moving

setTimeout(function(){
  sprite.body.velocity.x=0;
  sprite.body.velocity.y=0;
},2000);

The sprite will stop after 2 secs giving it time to reach its target.

So far nothing is in the update().

Second sprite (ex: sprite2)

sprite2 = game.add.sprite(200,500,'sprite');
game.physics.arcade.enable(sprite2);
game.camera.follow(sprite2);

Now on every mouse click, make it move to mouse pointer (x,y) and use the same method to stop the sprite from moving more than it should and see if the problem is still there.

Try to avoid putting things in the update() if you can do them in the create().

Share this post


Link to post
Share on other sites

Thanks @Batzi for your answers, I have learned a lot with your suggestions. And I remove some code from update functions. But @drhayes has put me on the road to the solution. I use the "puntoDentro" function to know if the sprite has arrived to the random target. I use getBounds to make a rectangle with the bounds and test if the target point is inside it. And the problem is that getBounds give the coordinates in the "screen" not in the "world". I added the camera coordinates to the rectangle coordinates and now works fine.

Old bad version:

Juego.puntoDentro=function(punto, sprite){
    var a=new Phaser.Rectangle(punto.x, punto.y, 1, 1);
    var b = sprite.getBounds();
    return Phaser.Rectangle.intersects(a, b);
};

New good version:

var a=new Phaser.Rectangle(this.objetivo.x, this.objetivo.y, 1, 1);
        var b = this.getBounds();
        b.x += this.auxGame.camera.x;
        b.y += this.auxGame.camera.y;
        if(Phaser.Rectangle.intersects(a, b)){  //when arrives to the target, random generate a new targete
            this.nuevoObjetivo();  
        }

Thanks a lot.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.