I have an object (a character) wich moves randomly around the screen. Also I have four animations (left, right, up and down) and I should select the respective animation accordingly to the direction the object is going to.
Thus I need a way of detecting what direction my object is moving to. Of course if it’s moving in diagonal (say to top-right) and it’s going “more” to the top than to the right I would select the top animation. And so on.
Any idea on how can I detect in which direction it’s moving?
But it’s returning me Uncaught TypeError: Cannot read property ‘velocity’ of null
I made a couple tests and figured that aEnemies[0].body returns null.
Here is the code I am using to instantiate enemies dinamically (it works fine, the animations, path, sprite, all runs well):
AddEnemy = (enemy,aPaths,path,pathduration) => {
// __MOVES contains the 4 animations references (left,right,up,down)
// aPaths is an array with different paths which object can follow randomly
// path is the index of aPaths array of the default path to be used
// pathduration is the value in ms to run the path
// create the 4 animations (left,right,up,down)
for (var m=0;m<=__MOVES.length-1;m++) {
this.anims.create({
key: enemy+__MOVES[m],
frames: this.anims.generateFrameNumbers(enemy+__MOVES[m]),
frameRate: __ENEMYFRAMERATE,
repeat: -1
});
}
// add enemy
this[enemy] = this.add.sprite(0, 0);
// set path
this[enemy].pathFollower = this.plugins.get('rexpathfollowerplugin').add(this[enemy], {
path: aPaths[path],
t: 0,
rotateToPath: false
});
// add tween
this.tweens.add({
targets: this[enemy].pathFollower,
t: 1,
ease: 'Linear',
duration: parseInt(pathduration),
repeat: 0,
yoyo: false
});
this[enemy].play(enemy+"Right");
aEnemies.push(this[enemy]);
}
this.AddEnemy(__CIRCLE,aPaths,3,10000); // __CIRCLE just holds the string "Circle"
You could check the x/y of this[enemy].pathFollower in the tween onUpdate callback.
Compare if with the previous x/y, and you know the direction.
You’ll be one step behind though
To fix that you would need to set pathFollower.t yourself. (or use Path.Getpoint).
Or even simpler, just use Path.getTangent.
The OP didn’t specify exactly that they were using arcade physics but it shouldn’t matter at all because you just need to get the objects velocity which should be possible when using arcade physics.
Samme, I think that your approach will be very useful to me! I played with the code and adapted it to my own code and it works to change left-right and it does that by comparing if the tan.x is negative (left) or positive (right). I would like to transform tan.x in angles.
Samme, your post with the running example plus the tan.angle() gave me enough to solve my issue.
Given that the tan.angle() will return a value between 0 and 6.4 I just had to divide it by 4 and get the ranges. This is the simplified code for whose may have the same difficulty:
preload() {
this.load.spritesheet('Right','assets/animations/Right.png', { frameWidth: 60, frameHeight: 56 });
// add the other spritesheets here (Left, Up and Down)...
}
create() {
var path = new Phaser.Curves.Path(50,150).lineTo(150,50).lineTo(250,50).lineTo(350,150).lineTo(350,250).lineTo(250,350).lineTo(150,350).lineTo(50,250).lineTo(50,150);
path.draw(graphics);
// create animations
this.anims.create({
key: 'Right',
frames: this.anims.generateFrameNumbers('Right'),
frameRate: 15,
repeat: -1
});
// create the other animations here (Left, Up and Down)...
// add the character
this.mycharacter = this.add.follower(path, -20, 200, 'Right').startFollow({
duration: 10000,
loop: 0,
});
}
update() {
var anim = "";
var tan = this.path.getTangent(this.mycharacter.pathTween.getValue());
if ((tan.angle() >= 2.4) && (tan.angle() <= 4))
anim = "Left";
if (((tan.angle() >= 0) && (tan.angle() <= 0.8)) || ((tan.angle() >= 5.6) && (tan.angle() <= 6.4)))
anim = "Right";
if ((tan.angle() > 4) && (tan.angle() < 5.6))
anim = "Up";
if ((tan.angle() > 0.8) && (tan.angle() < 2.4))
anim = "Down";
if ((this.mycharacter.anim != anim) && (anim != "")) {
this.mycharacter.anim = anim;
this.mycharacter.play(anim);
}
}