Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

6 years ago by wands

I want my entity to be able to know which direction to rotate base on my mouse location

for example.
My object's angle zero is pointing at 3 'o clock

If my mouse is located on the 12 o' clock, it will turn CCW. nearest turn
well, basically, my problem now is, what is the logic to tell the object to rotate in fastest manner?

Currently, my object is pointing at 9 o' clock, and my mouse is at 12 o'clock. the fastest is to rotate CW direction. However, it's now moving CCW instead.

6 years ago by Joncom

Sounds like you've already got some code that orients an entity angle to the mouse position. Mind sharing what you have so far?

6 years ago by wands

So, what I have is this. just a quick run down

var newAngle = Math.atan();

if(this.currentAnim.angle > newAngle)
//turn CCW

else
//turn CW

But I'm not sure what is the best way to code this, so that when it turns, it will turn at CW or CCW with minimum time, instead of turning a full circle

6 years ago by Apiheld

So, this is quick and dirty and needs fine-tuning, but it should do the trick:

/><br />
<br />
Overall idea:<br />
<br />
- On click, save the targetAngle<br />
- in update(), if currentAngle is not equal as targetAngle, step + or - (CW or CCW)<br />
- to determine if CW or CCW, you have to find the <strong>distance</strong> between the current angle and the target angle. depending on which distance is smaller, you turn - (CCW) or + (CW)<br />
<br />
Code:<br />
<br />
<pre class= update: function() { this.parent(); if (ig.input.pressed('shoot')) { var radians = Math.atan2(this.pos.y - ig.input.mouse.y, this.pos.x - ig.input.mouse.x); this.targetAngle = radians; } var source = this.toAngle(this.currentAnim.angle); var dest = this.toAngle(this.targetAngle); var factor = (((source-dest+360) % 360)>180)?0.1:-0.1; if (Math.abs(this.currentAnim.angle - this.targetAngle) > 0.3) { this.currentAnim.angle += factor; } }, toAngle: function( x ) { return (x > 0 ? x : (2*Math.PI + x)) * 360 / (2*Math.PI); }
Ugly:
- converts to 0..360 degrees, probably unnecessary
- updates the target angle too often. there's a threshold of 0.3 right now. if the distance is smaller than that, it shouldn't turn. however, this probably needs to be fine-tuned
- probably better: make a isTurning state for the entity

Res:
- http://gamedev.stackexchange.com/questions/11905/rotating-an-object-from-sourceangle-to-destangle-both-0-359-clockwise-or-count
- http://stackoverflow.com/questions/1311049/how-to-map-atan2-to-degrees-0-360

You probably want to read this:
- http://www.raywenderlich.com/35866/trigonometry-for-game-programming-part-1

6 years ago by wands

Quote from Apiheld
So, this is quick and dirty and needs fine-tuning, but it should do the trick:

/><br />
<br />
Overall idea:<br />
<br />
- On click, save the targetAngle<br />
- in update(), if currentAngle is not equal as targetAngle, step + or - (CW or CCW)<br />
- to determine if CW or CCW, you have to find the <strong>distance</strong> between the current angle and the target angle. depending on which distance is smaller, you turn - (CCW) or + (CW)<br />
<br />
Code:<br />
<br />
<pre class= update: function() { this.parent(); if (ig.input.pressed('shoot')) { var radians = Math.atan2(this.pos.y - ig.input.mouse.y, this.pos.x - ig.input.mouse.x); this.targetAngle = radians; } var source = this.toAngle(this.currentAnim.angle); var dest = this.toAngle(this.targetAngle); var factor = (((source-dest+360) % 360)>180)?0.1:-0.1; if (Math.abs(this.currentAnim.angle - this.targetAngle) > 0.3) { this.currentAnim.angle += factor; } }, toAngle: function( x ) { return (x > 0 ? x : (2*Math.PI + x)) * 360 / (2*Math.PI); }
Ugly:
- converts to 0..360 degrees, probably unnecessary
- updates the target angle too often. there's a threshold of 0.3 right now. if the distance is smaller than that, it shouldn't turn. however, this probably needs to be fine-tuned
- probably better: make a isTurning state for the entity

Res:
- http://gamedev.stackexchange.com/questions/11905/rotating-an-object-from-sourceangle-to-destangle-both-0-359-clockwise-or-count
- http://stackoverflow.com/questions/1311049/how-to-map-atan2-to-degrees-0-360

You probably want to read this:
- http://www.raywenderlich.com/35866/trigonometry-for-game-programming-part-1




Excellent reply!

Thank you so much for the input. Extremely helpful!

6 years ago by wands

I just want to point out that the code provided was really good. But I found a fundamental problem in your code. If your source angle is say -2.6 in radians and your destination angle is 2.5 in radians. The object will rotate CCW. Your code works in this portion.

However, it will calculate the total distance to travel is 5.1 in radians. This will cause the object to spin non-stop CCW. currentAnim.angle will continuously increase to a large amount becoming unstoppable.

After much understanding of how objects rotate in Javascript. We should normalize the rotation back to 0

Here is my code this one works perfectly no bugs in it. Someone please analyse and let me know if I'm wrong. :)

       turn: function(factor){

         var diff = Math.abs(this.newAngle-this.currentAnim.angle);

         if(diff>Math.PI){
            diff = Math.PI*2 - diff; //Normalize the difference in case it goes beyond a  full circle
            
         }
        //if (Math.abs(this.currentAnim.angle - this.newAngle) > 0.3) {
         if(diff.round(1) != 0){
                this.currentAnim.angle += factor; //Add the direction of spin, CW or CCW
                this.currentAnim.angle %= (Math.PI*2);//In case too much spin is apply onto one direction, makes sure we normalize the radian. 
                                                      //So when it hits 1 full cicle, we set it back to 0. rather than going beyond 6.24
          }
            

       
         // ig.log('curr '+this.currentAnim.angle.round(1));
        //  ig.log('new '+this.newAngle.round(1));
        //  ig.log('diff '+diff.round(1));


       },
Page 1 of 1
« first « previous next › last »