今回、
var lastMouse:Point;
var angularVelocity:Number = 5 * Math.PI / 180; // 一定値
function xDrag(eventObject:Event):void {
var currentMouse:Point = new Point(parent.mouseX, parent.mouseY);
var myMatrix:Matrix = transform.matrix;
myMatrix.translate(-lastMouse.x, -lastMouse.y);
myMatrix.rotate(angularVelocity); // 回転
myMatrix.translate(currentMouse.x, currentMouse.y);
transform.matrix = myMatrix;
lastMouse = currentMouse.clone();
}
後編の今回は、
ドラッグする位置と向きと速さによって回転を加速する
前編で、
![図1 インスタンスを回す速さはふたつのベクトルで決まる 図1 インスタンスを回す速さはふたつのベクトルで決まる](/assets/images/dev/serial/01/as3/0059/001.gif)
インスタンスのドラッグで回転を加速するアニメーションのリスナー関数
var lastMouse:Point;
var angularVelocity:Number = 0;
var deceleration:Number = 0.8;
var ratio:Number = 5 / width / height;
function xDrag(eventObject:Event):void {
var currentMouse:Point = new Point(parent.mouseX, parent.mouseY);
var myMatrix:Matrix = transform.matrix;
var position:Point = new Point(x, y);
// 外積を求めるふたつのベクトルの計算
var radius:Point = lastMouse.subtract(position);
var force:Point = currentMouse.subtract(lastMouse);
var moment:Number = crossProduct2D(radius, force);
angularVelocity += moment * ratio;
myMatrix.translate(-lastMouse.x, -lastMouse.y);
myMatrix.rotate(angularVelocity);
myMatrix.translate(currentMouse.x, currentMouse.y);
transform.matrix = myMatrix;
lastMouse = currentMouse.clone();
angularVelocity *= deceleration;
}
function crossProduct2D(point0:Point, point1:Point):Number {
var vector0:Vector3D = new Vector3D(point0.x, point0.y, 0);
var vector1:Vector3D = new Vector3D(point1.x, point1.y, 0);
var crossProduct3D:Vector3D = vector0.crossProduct(vector1);
return crossProduct3D.z;
}
ベクトルはPointオブジェクトで定めた。インスタンスの基準点は中心に定めたので、
引かれるPointオブジェクト.subtract(引くPointオブジェクト)
新たに加えた関数
ただし、
これで、
// フレームアクション: マウスでドラッグして回すMovieClipシンボル
var lastMouse:Point;
var angularVelocity:Number = 0;
var deceleration:Number = 0.8;
var ratio:Number = 5 / width / height;
addEventListener(MouseEvent.MOUSE_DOWN, xMouseDown);
function xMouseDown(eventObject:MouseEvent):void {
lastMouse = new Point(parent.mouseX, parent.mouseY);
addEventListener(Event.ENTER_FRAME, xDrag);
stage.addEventListener(MouseEvent.MOUSE_UP, xMouseUp);
}
function xMouseUp(eventObject:MouseEvent):void {
removeEventListener(Event.ENTER_FRAME, xDrag);
stage.removeEventListener(MouseEvent.MOUSE_UP, xMouseUp);
}
function xDrag(eventObject:Event):void {
var currentMouse:Point = new Point(parent.mouseX, parent.mouseY);
var myMatrix:Matrix = transform.matrix;
var position:Point = new Point(x, y);
var radius:Point = lastMouse.subtract(position);
var force:Point = currentMouse.subtract(lastMouse);
var moment:Number = crossProduct2D(radius, force);
angularVelocity += moment * ratio;
myMatrix.translate(-lastMouse.x, -lastMouse.y);
myMatrix.rotate(angularVelocity);
myMatrix.translate(currentMouse.x, currentMouse.y);
transform.matrix = myMatrix;
lastMouse = currentMouse.clone();
angularVelocity *= deceleration;
}
function crossProduct2D(point0:Point, point1:Point):Number {
var vector0:Vector3D = new Vector3D(point0.x, point0.y, 0);
var vector1:Vector3D = new Vector3D(point1.x, point1.y, 0);
var crossProduct3D:Vector3D = vector0.crossProduct(vector1);
return crossProduct3D.z;
}
![図2 マウスのドラッグでインスタンスの回る速さが加速する 図2 マウスのドラッグでインスタンスの回る速さが加速する](/assets/images/dev/serial/01/as3/0059/002.gif)
マウスボタンを放したら慣性で減速しながら移動する
仕上げは、
慣性で移動するリスナー関数
var velocity:Point;
function xMouseUp(eventObject:MouseEvent):void {
// ...[中略]...
addEventListener(Event.ENTER_FRAME, xThrow);
}
function xDrag(eventObject:Event):void {
// ...[中略]...
velocity = force;
}
function xThrow(eventObject:Event):void {
var myMatrix:Matrix = transform.matrix;
myMatrix.translate(-x, -y);
myMatrix.rotate(angularVelocity);
myMatrix.translate(x + velocity.x, y + velocity.y);
transform.matrix = myMatrix;
velocity.normalize(velocity.length * deceleration);
angularVelocity *= deceleration;
if (Math.abs(angularVelocity) < 0.1 && velocity.length < 0.1) {
removeEventListener(Event.ENTER_FRAME, xThrow);
}
}
少し細かい処理を補っておこう。慣性で動くとき、
慣性のベクトル
// フレームアクション: マウスでドラッグして回すMovieClipシンボル
var lastMouse:Point;
var angularVelocity:Number = 0;
var velocity:Point;
var deceleration:Number = 0.8;
var ratio:Number = 5 / width / height;
addEventListener(MouseEvent.MOUSE_DOWN, xMouseDown);
function xMouseDown(eventObject:MouseEvent):void {
lastMouse = new Point(parent.mouseX, parent.mouseY);
addEventListener(Event.ENTER_FRAME, xDrag);
stage.addEventListener(MouseEvent.MOUSE_UP, xMouseUp);
}
function xMouseUp(eventObject:MouseEvent):void {
removeEventListener(Event.ENTER_FRAME, xDrag);
stage.removeEventListener(MouseEvent.MOUSE_UP, xMouseUp);
addEventListener(Event.ENTER_FRAME, xThrow);
}
function xDrag(eventObject:Event):void {
var currentMouse:Point = new Point(parent.mouseX, parent.mouseY);
var myMatrix:Matrix = transform.matrix;
var position:Point = new Point(x, y);
var radius:Point = lastMouse.subtract(position);
var force:Point = currentMouse.subtract(lastMouse);
var moment:Number = crossProduct2D(radius, force);
angularVelocity += moment * ratio;
myMatrix.translate(-lastMouse.x, -lastMouse.y);
myMatrix.rotate(angularVelocity);
myMatrix.translate(currentMouse.x, currentMouse.y);
transform.matrix = myMatrix;
lastMouse = currentMouse.clone();
angularVelocity *= deceleration;
velocity = force;
}
function xThrow(eventObject:Event):void {
var myMatrix:Matrix = transform.matrix;
myMatrix.translate(-x, -y);
myMatrix.rotate(angularVelocity);
myMatrix.translate(x + velocity.x, y + velocity.y);
transform.matrix = myMatrix;
velocity.normalize(velocity.length * deceleration);
angularVelocity *= deceleration;
if (Math.abs(angularVelocity) < 0.1 && velocity.length < 0.1) {
removeEventListener(Event.ENTER_FRAME, xThrow);
}
}
function crossProduct2D(point0:Point, point1:Point):Number {
var vector0:Vector3D = new Vector3D(point0.x, point0.y, 0);
var vector1:Vector3D = new Vector3D(point1.x, point1.y, 0);
var crossProduct3D:Vector3D = vector0.crossProduct(vector1);
return crossProduct3D.z;
}
回転の加速と減速の度合いは変数
剛体を回す力の働き - 力のモーメント
かたちの変わらない固いもの
太いドライバに力が加えやすいのは、
![図3 てこと力を加える向き 図3 てこと力を加える向き](/assets/images/dev/serial/01/as3/0059/thumb/TH800_003.gif)
力がてこ
![図4 てこに加えられた力はてこに平行と垂直なふたつのベクトルに分けられる 図4 てこに加えられた力はてこに平行と垂直なふたつのベクトルに分けられる](/assets/images/dev/serial/01/as3/0059/thumb/TH800_004.gif)
インスタンスを回転する働きは、
ここで、
外積はふたつのベクトルのどちらにも垂直なベクトルだった。つまり、
もっとも、
Flash Professional CS6が発表された。そこでこの本編のつぎ
今回解説した次のサンプルファイルがダウンロードできます。
- スクリプト1~2のサンプルファイル
(CS5形式/約98KB)