Forum Topic: Flash and Rotating

(176 views • 8 replies)

This topic is 1 page long.

<< < > >>
None

Wurmy

Reply To Post Reply & Quote

Posted at: 10/6/09 06:22 PM

Wurmy LIGHT LEVEL 28

Sign-Up: 06/20/06

Posts: 2,308

So once more I have a problem.

I'll illustrate it with this flash: Link.

Just move your mouse around and the arrow will follow. Here's the problem: when you cross the +/- 180, it goes all the way around rather than crossing over. I know why this happens (see code) but I can't think of a solution.

I know there's been a question on this exact same thing before but I cannot find it. Help/suggestions?

Here's the simple code:

// arr is the arrow on the stage
// output is the dynamic text box

addEventListener(Event.ENTER_FRAME, Loop, false, 0, true);

var rot:Number = arr.rotation;

function Loop(e:Event):void {
	
	var dy:Number = mouseY - arr.y;
	var dx:Number = mouseX - arr.x;
	
	var finalAngle:Number = 180 / Math.PI * Math.atan2(dy, dx);
	
	if (rot > finalAngle) rot -= 5;
	if (rot < finalAngle) rot += 5;
	
	arr.rotation = rot;
	
	output.text = "Mouse Rotation: " + Math.round(finalAngle).toString() + "\nCurrent Rotation Variable: " + Math.round(rot).toString() + "\nRotation of Arrow: " + Math.round(arr.rotation).toString();
	
}
BBS Signature

Expressionless

zuperxtreme

Reply To Post Reply & Quote

Posted at: 10/6/09 06:53 PM

zuperxtreme NEUTRAL LEVEL 08

Sign-Up: 01/02/05

Posts: 1,629

Umm. Why not just:

var finalAngle:Number = 180 / Math.PI * Math.atan2(dy, dx);
arr.rotation = finalAngle;

?


None

Techno

Reply To Post Reply & Quote

Posted at: 10/6/09 07:00 PM

Techno DARK LEVEL 24

Sign-Up: 08/11/06

Posts: 4,934

You are making it way too hard for yourself.

stage.addEventListener(Event.ENTER_FRAME, arrowRoatate)
function arrowRoatate(e:Event):void
{
    var angle:Number = Math.atan2 (mouseY - arrow.y, mouseX - arrow.x);
    arrow.rotation = angle * 180 / Math.PI;
    
    if (arrow.rotation < -180 ||arrow.rotation > 180)
        {
            stage.removeEventListener(Event.ENTER_FRAME, arrowRoatate)
        }
        else
        {
            stage.addEventListener(Event.ENTER_FRAME, arrowRoatate)
        }
}

This simple code allows you to do this, without all the revert-ish effect you were experiencing.

Hope this helped.

.

BBS Signature

None

Wurmy

Reply To Post Reply & Quote

Posted at: 10/8/09 08:13 PM

Wurmy LIGHT LEVEL 28

Sign-Up: 06/20/06

Posts: 2,308

At 10/6/09 07:00 PM, Techno wrote: stuff

Thing is, I don't want it to automatically rotate to point at the mouse, I want it to move to that angle at a certain rate. Your code just makes it point at the mouse.

BBS Signature

None

Wurmy

Reply To Post Reply & Quote

Posted at: 10/8/09 09:55 PM

Wurmy LIGHT LEVEL 28

Sign-Up: 06/20/06

Posts: 2,308

Bump.. I feel dumb

BBS Signature

None

Tree-SkyLark-BCE

Reply To Post Reply & Quote

Posted at: 10/9/09 12:55 AM

Tree-SkyLark-BCE LIGHT LEVEL 35

Sign-Up: 08/06/05

Posts: 209

I just realized the ridiculousness of this solution. I am clearly not thinking logically at this hour.

const DEGRAD:Number = Math.PI / 180;
const SIN5:Number = Math.sin(5 * DEGRAD);
const COS5:Number = Math.cos(5 * DEGRAD);

addEventListener(Event.ENTER_FRAME, Loop, false, 0, true);

var rot:Number = arr.rotation;

private	function Loop(e:Event):void
{
	var dy:Number = mouseY - arr.y;
	var dx:Number = mouseX - arr.x;
	
	var finalAngle:Number = Math.atan2(dy, dx);
	var rcos:Number = Math.cos(rot * DEGRAD);
	var rsin:Number = Math.sin(rot * DEGRAD);
	var fcos:Number = Math.cos(finalAngle);
	var fsin:Number = Math.sin(finalAngle);
	var rp5cos:Number = rcos * COS5 - rsin * SIN5;
	var rp5sin:Number = rsin * COS5 + SIN5 * rcos;
	var rm5cos:Number = rcos * COS5 + rsin * SIN5;
	var rm5sin:Number = rsin * COS5 - SIN5 * rcos;
	if ((fcos - rcos) * (fcos - rcos) + (fsin - rsin) * (fsin - rsin) < .007)
	{
		return;
	}
	if ((fcos - rp5cos) * (fcos - rp5cos) + (fsin - rp5sin) * (fsin - rp5sin) > (fcos - rm5cos) * (fcos - rm5cos) + (fsin - rm5sin) * (fsin - rm5sin))
	{
		rot -= 5;
	}
	else
	{
		rot += 5;
	}
	
	arr.rotation = rot;
}
BBS Signature

None

Tree-SkyLark-BCE

Reply To Post Reply & Quote

Posted at: 10/9/09 01:46 AM

Tree-SkyLark-BCE LIGHT LEVEL 35

Sign-Up: 08/06/05

Posts: 209

This solution is more logical:

RADDEG:Number = 180 / Math.PI;

addEventListener(Event.ENTER_FRAME, Loop, false, 0, true);

var rot:Number = arr.rotation;

private	function Loop(e:Event):void
{
	var dy:Number = mouseY - arr.y;
	var dx:Number = mouseX - arr.x;
	
	var finalAngle:Number = Math.atan2(dy, dx) * RADDEG;
	if (rot < finalAngle + 5 && rot > finalAngle - 5) return;
	if (rot > 0 && finalAngle < 0)
	{
		if (360 - rot + finalAngle < 180)
		{
			if (rot + 5 > 180)
			{
				rot = -360 + rot + 5;
			}
			else
			{
				rot += 5;
			}
		}
		else
		{
			rot -= 5;
		}
	}
	else if (rot < 0 && finalAngle > 0)
	{
		if (360 + rot - finalAngle < 180)
		{
			if (rot - 5 < -180)
			{
				rot = 360 + rot - 5;
			}
			else
			{
				rot -= 5;
			}
		}
		else
		{
			rot += 5;
		}
	}
	else if (rot > finalAngle) rot -= 5;
	else if (rot < finalAngle) rot += 5;
	arr.rotation = rot;
}
BBS Signature

None

Wurmy

Reply To Post Reply & Quote

Posted at: 10/10/09 07:03 PM

Wurmy LIGHT LEVEL 28

Sign-Up: 06/20/06

Posts: 2,308

Jesus.. well it works like a charm. It's kind of nice to know that there was no simple way of making it work (since I thought there was and couldn't think of such a way).

So thank you very much tree. If anybody cares, here's a handly little function (from Tree's code)

function RotateTo(To:Number, CurrentAngle:Number, Rate:Number):Number {
			
			var Final:Number = CurrentAngle;
			
			if (CurrentAngle < To + Rate && CurrentAngle > To - Rate) return Final;
			
			if (CurrentAngle > 0 && To < 0){
				
				if (360 - CurrentAngle + To < 180) {
					
					if (CurrentAngle + Rate > 180)
						Final = -360 + CurrentAngle + Rate;
					else
						Final += Rate;
						
				} else
					Final -= Rate;
				
			} else if (CurrentAngle < 0 && To > 0) {
				
				if (360 + CurrentAngle - To < 180) {
					
					if (CurrentAngle - Rate < -180)
						Final = 360 + CurrentAngle - Rate;
					else
						Final -= Rate;
				}
				else
					Final += Rate;
			}
			
			else if (CurrentAngle > To) Final -= Rate;
			else if (CurrentAngle < To) Final += Rate;
			
			return Final;
		}
BBS Signature

None

Yambanshee

Reply To Post Reply & Quote

Posted at: 10/10/09 11:56 PM

Yambanshee DARK LEVEL 11

Sign-Up: 10/05/08

Posts: 1,607

At 10/10/09 07:03 PM, Wurmy wrote: Jesus.. well it works like a charm. It's kind of nice to know that there was no simple way of making it work (since I thought there was and couldn't think of such a way).

Actually, i needed this for a airplane AI and i just did all the angle Calcs with a +180 at the end so threres no negative numbers, and then the final angle variable -180 again.

AS2||AS3||Motox
Thanks to hdxmike for the sig :]

BBS Signature

All times are Eastern Standard Time (GMT -5) | Current Time: 11:12 PM

<< Back

This topic is 1 page long.

<< < > >>
You need a Grounds Gold Account to post on the NG BBS! If you don't have one, click here to sign up now! It's fast, free, and easy — and opens up tons of great NG features!