CrabBoy

Advanced object positioning in the group

Recommended Posts

Hi guys!

Main character in my game is this cat:

phaser-Topic-Photo.png

Cat is composed from two parts - the torso and the head - and for each part I want to have physics body enabled, therefore I decided all parts will be inside a group. During the gameplay, I apply certain amount of velocity to the cat torso and cat then should rotate around its own axis, clock-wise and counter clockwise.

I chose the approach to apply velocity to the torso and I want to position the head according the torso in the update method. Basically I want to achieve the same behaviour as Sprite.addChild() (add head as a child of a torso), but I want to do it in a group. I imagine basic (pseudo)code should look like this:

export class Cat extends Phaser.Group {

    private _torso: Phaser.Sprite;
    private _catHead: Phaser.Sprite;
    private _torsoHeadDistance: number;

    public constructor(game: Phaser.Game, startPosY: number) {
      super(game);
      //torso
      this._torso = game.add.sprite(game.world.centerX, startPosY, "torso");
      this._torso.anchor.setTo(0.5);
      this._torso.scale.setTo(0.5);

      //head
      this._catHead = game.add.sprite(this._torso.x, this._torso.top, "head");
      this._catHead.anchor.setTo(0.5, 0.7);
      this._catHead.scale.setTo(0.3);

      this.add(this._torso);
      this.add(this._catHead);

      game.physics.enable(this._torso, Phaser.Physics.ARCADE);
      game.physics.enable(this._catHead, Phaser.Physics.ARCADE);


      //Get the distance between both parts
      this._torsoHeadDistance = this.game.physics.arcade.distanceBetween(this._torso, this._catHead, true);
    }

    //This will be called when player interacts with the game
    public AddVelocity(angle, speed, angularVel: number) {
      this._game.physics.arcade.velocityFromAngle(angle, speed, this._torso.body.velocity);
      this._torso.body.angularVelocity = angularVel;
    }

    //Called from update each frame
    public UpdatePosition(){
      //pseudo code
      this._catHead.position = this._torso.position + _torsoHeadDistance;
      this._catHead.rotation = this._torso.rotation;
    }
}

Basically I just want retain the same distance between both sprites in the group within the time. The problem is that I am not able to figure out the code which should be in UpdatePosition() method. I know it should be something with vectors and normalizing, but I already spent few hours solving this without success. Can someone point me closer to the solution, please? I start to be desperate...

Thanks in advance!

Share this post


Link to post
Share on other sites
On 10/25/2018 at 11:25 PM, samme said:

Thanks for the hint, but I don´t think this is the right way to do it, or at least I don´t know how to use it properly - can you provide some code snippet if you still think this is the right way to go?

In the meantime, I discovered this article and I implemented it as follows:

//in the constructor:
this._catHeadDist =  this.game.physics.arcade.distanceBetween(this._catHead, this._torso, false, false);

//in the update method:
this._catHead.x = Math.cos((this._torso.angle) * Math.PI / 180) * this._catHeadDist + this._torso.x;
this._catHead.y = Math.sin((this._torso.angle) * Math.PI / 180) * this._catHeadDist + this._torso.y;
this._catHead.rotation = this._torso.rotation;

I got the behaviour as desired, but it is still not perfect - the head is somehow changing the distance from the body in certain angles and basically it behaves like a spring joint instead of distance joint. Sometimes it is ok but sometimes it is not, as you can see on the image below:

phaser-Topic-Photo-Cat-Not-OK.png

Any other advices? Thanks!

Share this post


Link to post
Share on other sites
53 minutes ago, samme said:

Phaser.Point.rotate(catHead, torso.x, torso.y, torso.angle, true, catHeadDist);

Use anchor (0.5, 0.5) for both sprites.

catHeadDist should be constant, I think.

If I call this this from update method, that basically means I want to rotate my head by the current angle of the torso. You call this 60times within a second and the only thing you see is the head rotating around the body as crazy. Better approach would be getting angle difference since last update call and rotate the head by this difference. Anyway I tried this approach and it did not work for some reasons...

In the end I was able to achieve the behaviour I wanted by calling my code above (the one with sin and cos) from the postUpdate method instead of update. The problem was that physics calculations was always called after my code in update, so I was one step ahead the physics. Calling the code from postUpdate solved my problem.

Thanks for your hints anyway!

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.