SuperMarco Posted October 2, 2014 Share Posted October 2, 2014 Hi, I have searched inside the documention but I couldn't find anything about it. I'm using the method moveToPointer to move my character (so it will follow the mouse and shoot in that direction).And what I was trying to achieve is that to set a different animation depending of the direction that my sprite is going. I already know how to set and play the animation but, is there is any way to know if my sprite is going left, right, up or down ? I could try to do a trick such as looking the position of the mouse and compare it to the sprite, but I'm not really sure its really pretty to do it this way. Thanks for the help ! Link to comment Share on other sites More sharing options...
Sebi Posted October 2, 2014 Share Posted October 2, 2014 That's exactly how you do it.You can also calculate the angle between sprite position and mouse position. If it's 45 degree to 135 degree -> face right, 135 degree to 225 degree -> face down, 225 to 315 face left and else face top. Link to comment Share on other sites More sharing options...
SuperMarco Posted October 2, 2014 Author Share Posted October 2, 2014 Oh ok then . But when you say calculate the angle between the sprite and the mouse, its also counting the origin point ? *removing the dust from old math books* Link to comment Share on other sites More sharing options...
SuperMarco Posted October 2, 2014 Author Share Posted October 2, 2014 SebastianNette, I manage to set up the calcul but I have one problem, the angle doesn't go over 180 degrees. I made a small example to explain : if I put my mouse at the point where the 2 arrow touch, it will be 180 degrees. but if I go on one way or the other, the angle decrease instead of increasing on one side, and decrease on the other. Is there is a trick to avoid this problem ? Link to comment Share on other sites More sharing options...
Sebi Posted October 2, 2014 Share Posted October 2, 2014 Well you don't really need angles. You could just compare the position of the sprite and the mouse. The angle is calculated like this: var angle = Math.atan2(mouse y - sprite y, mouse x - sprite x ) * (180/Math.PI); Where the sprite coordinates have to be at the center of the sprite. SuperMarco 1 Link to comment Share on other sites More sharing options...
SuperMarco Posted October 2, 2014 Author Share Posted October 2, 2014 Where the sprite coordinates have to be at the center of the sprite. Damn ok, I did something so much complicated instead of something simple.. To get the center of my sprite, there is a method in the doc ? or I should find it by myself hard coded ? Thank you very much for your help !! Link to comment Share on other sites More sharing options...
xerver Posted October 2, 2014 Share Posted October 2, 2014 To test if a point is in front of or behind you, just dot product the two points. If it is positive, the point is in front of you; if negative it is behind you; if zero the point is directly on the same Y axis:var val = (new Phaser.Point()).copyFrom(player).dot(mousePosition);if (val < 0) { /* BEHIND */ }else if (val > 0) { /* IN FRONT */ }else { /* SAME Y PLANE */ }Similarly to check if they are right or left, you take the dot product of your position with the vector perpendicular to the target:var val = (new Phaser.Point()).copyFrom(player).dot(Phaser.Point.perp(mousePosition));if (val < 0) { /* LEFT */ }else if (val > 0) { /* RIGHT */ }else { /* SAME X PLANE */ }You will probably want to change that to use the center of the sprite instead of the x/y values, but you get the idea. Link to comment Share on other sites More sharing options...
lewster32 Posted October 2, 2014 Share Posted October 2, 2014 The moveToPointer function returns the angle (in radians) that the object needs to move to reach the pointer, so that calculation is already done for you. What you need to do is quantise that value to determine cardinal directions. The value, being in radians, will be between -Math.PI and Math.PI. Here's a little example with some probably rather poor and inefficient maths, but it works and demonstrates a possible way to do it: http://jsfiddle.net/lewster32/vL7r71z9/ michaelcalkins 1 Link to comment Share on other sites More sharing options...
SuperMarco Posted October 2, 2014 Author Share Posted October 2, 2014 The moveToPointer function returns the angle (in radians) that the object needs to move to reach the pointer, so that calculation is already done for you. What you need to do is quantise that value to determine cardinal directions. The value, being in radians, will be between -Math.PI and Math.PI. Here's a little example with some probably rather poor and inefficient maths, but it works and demonstrates a possible way to do it: http://jsfiddle.net/lewster32/vL7r71z9/ Thanks lewster32 ! Unfortunately I decided to change the way to move my character, so it no longer use moveToPointer (at least for now). But this will be very useful for my ennemies in the game ! (but I will use the technic of the carnidal point ^^ To test if a point is in front of or behind you, just dot product the two points. If it is positive, the point is in front of you; if negative it is behind you; if zero the point is directly on the same Y axis:var val = (new Phaser.Point()).copyFrom(player).dot(mousePosition);if (val < 0) { /* BEHIND */ }else if (val > 0) { /* IN FRONT */ }else { /* SAME Y PLANE */ }Similarly to check if they are right or left, you take the dot product of your position with the vector perpendicular to the target:var val = (new Phaser.Point()).copyFrom(player).dot(Phaser.Point.perp(mousePosition));if (val < 0) { /* LEFT */ }else if (val > 0) { /* RIGHT */ }else { /* SAME X PLANE */ }You will probably want to change that to use the center of the sprite instead of the x/y values, but you get the idea. I didn't manage to make it work this way, it keep telling me that "Uncaught TypeError: undefined is not a function" I don't know why... Well you don't really need angles. You could just compare the position of the sprite and the mouse. The angle is calculated like this: var angle = Math.atan2(mouse y - sprite y, mouse x - sprite x ) * (180/Math.PI); Where the sprite coordinates have to be at the center of the sprite. Thank you SebastianNette, I will use your way I think Just a last question (I know I'm a newbie...), to set the coordinate of the sprite at its center it's sprite.anchor.setTo(0.5, 0.5) ? Because I feel like my sprite loose in quality .. Link to comment Share on other sites More sharing options...
xerver Posted October 2, 2014 Share Posted October 2, 2014 I didn't manage to make it work this way, it keep telling me that "Uncaught TypeError: undefined is not a function" I don't know why... Obviously you need to change "player" and "mousePosition" to your objects. Calculating the angle via arctan is expensive, and overkill if all you want is up/down/right/left. If you need the exact angle though, you will need to use arctan. Thanks lewster32 ! Unfortunately I decided to change the way to move my character, so it no longer use moveToPointer (at least for now). But this will be very useful for my ennemies in the game ! (but I will use the technic of the carnidal point ^^ I didn't manage to make it work this way, it keep telling me that "Uncaught TypeError: undefined is not a function" I don't know why... Thank you SebastianNette, I will use your way I think Just a last question (I know I'm a newbie...), to set the coordinate of the sprite at its center it's sprite.anchor.setTo(0.5, 0.5) ? Because I feel like my sprite loose in quality ..It will make it seems like your coords are at the center of the texture, but it doesn't move the position it moves the texture around. The coords are still the top-left of your sprite, the texture has just moved up-left so the middle of the texture (0.5,0.5) is on the coords origin (top-left). Which may be good enough for your purposes. Link to comment Share on other sites More sharing options...
SuperMarco Posted October 2, 2014 Author Share Posted October 2, 2014 Obviously you need to change "player" and "mousePosition" to your objects... Of course I did , but I still got the error.. Link to comment Share on other sites More sharing options...
xerver Posted October 2, 2014 Share Posted October 2, 2014 Of course I did , but I still got the error..Can you give any more information than "I got an error"? Code that you used, the error and line that caused it, etc? "Undefined is not a function" with no context is not helpful at all. I ran the code I posted above on a couple objects and it worked fine. Link to comment Share on other sites More sharing options...
SuperMarco Posted October 2, 2014 Author Share Posted October 2, 2014 Can you give any more information than "I got an error"? Code that you used, the error and line that caused it, etc? "Undefined is not a function" with no context is not helpful at all. I ran the code I posted above on a couple objects and it worked fine.I apologies, I'm using my code into classes, here is the Player one : ( I removed some line, to make it cleaner (such as input keys etc..))Player = function(game) { this.game = game; this.sprite = null; this.group = null;};Player.prototype = { preload: function() { this.game.load.spritesheet('survivor', 'assets/survivor.png', 23, 46); }, create: function() { this.group = this.game.add.group(); this.sprite = this.group.create(300, 28, 'survivor'); this.sprite.anchor.setTo(0.5, 0.5); this.sprite.animations.add('left', [0, 1, 2, 3], 10, true); this.sprite.animations.add('down', [4, 5, 6, 7], 10, true); this.sprite.animations.add('up', [8, 9, 10, 11], 10, true); this.sprite.animations.add('right', [12, 13, 14, 15], 10, true); }, update: function() { var mouse = game.input.mousePointer; var val = (new Phaser.Point()).copyFrom(this.sprite).dot(mouse); console.log(val); }};With this code, the console is giving me this error : Uncaught TypeError: undefined is not a function Player.js:37Player.update Player.js:37update (index):41b.StateManager.update phaser.min.js:6b.Game.update phaser.min.js:8b.RequestAnimationFrame.updateRAF phaser.min.js:11window.requestAnimationFrame.forceSetTimeOut._onLoop phaser.min.js:11 I did something wrong probably, but I don't know where :S [Edit] I did some test, and it seems that is coming from the dot method. Link to comment Share on other sites More sharing options...
xerver Posted October 2, 2014 Share Posted October 2, 2014 You are using an old version of phaser, the dot method was added in v2.0.4. The latest version is v2.1.1, you should probably upgrade. SuperMarco 1 Link to comment Share on other sites More sharing options...
SuperMarco Posted October 2, 2014 Author Share Posted October 2, 2014 You are using an old version of phaser, the dot method was added in v2.0.4. The latest version is v2.1.1, you should probably upgrade. You were right ! I thought that I download the one from git... hmm weird.However, the value return but the point are very big, and always over 0, how is that possible ? :s Link to comment Share on other sites More sharing options...
SuperMarco Posted October 3, 2014 Author Share Posted October 3, 2014 I had a closer look to the dot and the source code too to see what's everything were doing, and I also try to test by myself the calculus that the dot is doing and I don't get the same result as you said xerver. For example, my origin is upper left give me 0.The point down the origin (down left corner) is 18000 ish.The point corner up right is 32000.And the point bottom right is around 50000.(When my sprite is in the middle or my plan) I did the same thing as you did I guess here : var val = new Phaser.Point().copyFrom(this.sprite).dot(this.game.input.mousePointer); console.log(val);I also tried the second calculus to detect left or right, but my map is divided in 2 part in diagonal like this: The red line is moving with my sprite, so if I move my char up, the positive area become smaller, but it always start from the origin..The value over the right line is positive, and the value below is negative. It seems that the perp line is not set properly or something ? Link to comment Share on other sites More sharing options...
xerver Posted October 3, 2014 Share Posted October 3, 2014 I though you were trying to get left/right, which is: new Phaser.Point().copyFrom(this.sprite).dot(Phaser.Point.perp(this.game.input.mousePointer));Also this is linear algebra, not calculus. Look it up "how to find if vector is left of another vector" it is a pretty common problem. Link to comment Share on other sites More sharing options...
Recommended Posts