Примерно так должно получиться:
private function projectLocation(center:point, radius:uint, radian:Number):Point
{
var result:Point = new Point();
//obtain X
result.x = center.x + radius * Math.cos(radian));
//obtain Y
result.y = center.y + radius * Math.sin(radian));
return result;
}
Очевидно, измените по мере необходимости, но вам просто нужно отправить в центральную точку, радиус, а затем радиан (вы можете получить с помощью angle * (Math.PI / 180)
). Вы можете легко жестко кодировать в первых двух параметрах, если они не меняются. Что меняет, так это радиан, и это то, что вам нужно будет менять со временем, когда мышь перетаскивает (определяется расстоянием mouseX до центральной точки - положительное или отрицательное).
Надеюсь, это поможет вам начать -
обновление
Вот как я работал над этим - хотя это была небольшая ошибка в том, что шайба сбрасывается до 0 градусов, когда начинается последовательность. Это сказанное, я только что видел это - @Nox понял это правильно. В любом случае я опубликую то, к чему я пришел, используя функцию projectLocation;)
package com.b99.testBed.knob
{
import com.b99.testBed.Main;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
/**
* ...
* @author bosworth99
*/
public class Knob extends Sprite
{
private var _puck :Sprite;
private var _track :Sprite;
private const DIAMETER :uint = 100;
private const RADIUS :uint = DIAMETER / 2;
public function Knob()
{
super();
init();
}
private function init():void
{
assembleDisplayObjects();
addEventHandlers();
}
private function assembleDisplayObjects():void
{
_track = new Sprite();
with (_track)
{
graphics.beginFill(0xffffff, 1);
graphics.lineStyle(1, 0x000000);
graphics.drawEllipse(-RADIUS, -RADIUS, DIAMETER, DIAMETER);
graphics.endFill();
}
this.addChild(_track);
_track.x = Main.stage.stageWidth / 2;
_track.y = Main.stage.stageHeight / 2;
_puck = new Sprite();
with (_puck)
{
graphics.beginFill(0x2DFE07, 1);
graphics.drawEllipse(-8, -8, 16, 16);
graphics.endFill();
x = _track.x;
y = _track.y - _track.width / 2;
buttonMode = true;
}
this.addChild(_puck);
}
private function addEventHandlers():void
{
Main.stage.addEventListener(MouseEvent.MOUSE_DOWN, activate);
Main.stage.addEventListener(MouseEvent.MOUSE_UP, deactivate);
}
private function deactivate(e:MouseEvent):void
{
Main.stage.removeEventListener(MouseEvent.MOUSE_MOVE, update);
}
private var _origin:uint;
private function activate(e:MouseEvent):void
{
Main.stage.addEventListener(MouseEvent.MOUSE_MOVE, update);
_origin = mouseX;
}
private function update(e:MouseEvent):void
{
var distance:Number;
(mouseX < _origin)? distance = -(_origin - mouseX) : distance = mouseX - _origin;
if(distance > 40){distance = 40};
if(distance < -220){distance = -220};
var angle:Number = distance; //modify?
var radian:Number = angle * (Math.PI / 180);
var center:Point = new Point(_track.x, _track.y);
var loc:Point = projectLocation(center, RADIUS, radian);
_puck.x = loc.x;
_puck.y = loc.y;
}
private function projectLocation(center:Point, radius:uint, radian:Number):Point
{
var result:Point = new Point();
//obtain X
result.x = center.x + radius * Math.cos(radian);
//obtain Y
result.y = center.y + radius * Math.sin(radian);
return result;
}
}
}
Основное отличие заключается в том, что я получаю угол с помощью горизонтального (x) перемещения, а не проверяю угол курсора. Тхос, отслеживание значений вручную, кажется довольно хакерским по сравнению с @Nox, очень хороший выбор. Я бы убрался, если бы продолжал;)
Хороший вопрос - ура