flash on 2010-3-26
先日作った「おばけだぞぉ」
http://wonderfl.net/code/8bcb34c6470564e094889100d6c61cb09c9b7dc1
の仕組みを再構成してみました
赤いマルはドラッグできます
本当は黒いマルもドラッグできるようにしたいのだけど、
傾いた直線上にドラッグの範囲を制限する方法がわかりません
/**
* Copyright tenasaku ( http://wonderfl.net/user/tenasaku )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/uKBj
*/
// 先日作った「おばけだぞぉ」
// http://wonderfl.net/code/8bcb34c6470564e094889100d6c61cb09c9b7dc1
// の仕組みを再構成してみました
// 赤いマルはドラッグできます
// 本当は黒いマルもドラッグできるようにしたいのだけど、
// 傾いた直線上にドラッグの範囲を制限する方法がわかりません
package {
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import flash.geom.*;
public class Main extends Sprite {
private const ctlPtColor:uint = 0xff0000; // 制御点の表示色
private const basePtColor:uint = 0x000066; // 起点の表示色
private const guideColor:uint = 0x666600; // 外接三角形の表示色
private const paintColor:uint = 0x0066ff; // 卵形線内部の描画色
private const bgColor:uint = 0xffffff; // 背景色
private const boundsRect:Rectangle
= new Rectangle (
BullsEye.RADIUS*1.2,
BullsEye.RADIUS*1.2,
465-BullsEye.RADIUS*2.4,
465-BullsEye.RADIUS*2.4
);
private var c0:BullsEye,c1:BullsEye,c2:BullsEye; // 制御点
private var p0:BullsEye,p1:BullsEye,p2:BullsEye; // 起点
private var t0:Number,t1:Number,t2:Number; // 起点の位置を示す座標値
// 全体の描画
private function draw():void {
this.visible = false;
this.graphics.clear();
this.graphics.beginFill(bgColor);
this.graphics.drawRect(0,0,465,465);
this.graphics.endFill();
this.graphics.lineStyle(0,guideColor);
this.graphics.moveTo(c0.x,c0.y);
this.graphics.lineTo(c1.x,c1.y);
this.graphics.lineTo(c2.x,c2.y);
this.graphics.lineTo(c0.x,c0.y);
p0.x = t0*c1.x + (1-t0)*c2.x;
p0.y = t0*c1.y + (1-t0)*c2.y;
p1.x = t1*c2.x + (1-t1)*c0.x;
p1.y = t1*c2.y + (1-t1)*c0.y;
p2.x = t2*c0.x + (1-t2)*c1.x;
p2.y = t2*c0.y + (1-t2)*c1.y;
this.graphics.lineStyle(NaN);
this.graphics.beginFill(paintColor);
this.graphics.moveTo(p0.x,p0.y);
this.graphics.curveTo(c1.x,c1.y,p2.x,p2.y);
this.graphics.curveTo(c0.x,c0.y,p1.x,p1.y);
this.graphics.curveTo(c2.x,c2.y,p0.x,p0.y);
this.graphics.endFill();
this.visible = true;
}
// プログラム初期化
private function initialize(e:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, initialize);
// ステージの左上隅を合わせる. 縮尺させない.
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
// 制御点BullsEyeオブジェクトの生成
c0 = new BullsEye(ctlPtColor);
c1 = new BullsEye(ctlPtColor);
c2 = new BullsEye(ctlPtColor);
// 起点BullsEyeオブジェクトの生成
p0 = new BullsEye(basePtColor);
p1 = new BullsEye(basePtColor);
p2 = new BullsEye(basePtColor);
// 起点は見えればよいので小さめに表示
p0.scaleX = p0.scaleY = 0.667;
p1.scaleX = p1.scaleY = 0.667;
p2.scaleX = p2.scaleY = 0.667;
// 制御点の初期値を(正三角形に)設定
c0.x = 232.5 + 80*0;
c0.y = 232.5 - 80*2;
c1.x = 232.5 + 80*Math.sqrt(3);
c1.y = 232.5 + 80;
c2.x = 232.5 - 80*Math.sqrt(3);
c2.y = 232.5 + 80;
// BullsEyeオブジェクトを表示リストへ登録
this.addChild(p0);
this.addChild(p1);
this.addChild(p2);
this.addChild(c0);
this.addChild(c1);
this.addChild(c2);
// 制御点をドラッグ可能にする
c0.addEventListener(MouseEvent.MOUSE_DOWN, whenMouseDown);
c1.addEventListener(MouseEvent.MOUSE_DOWN, whenMouseDown);
c2.addEventListener(MouseEvent.MOUSE_DOWN, whenMouseDown);
// アニメーションの処理ルーチンを登録
stage.addEventListener(Event.ENTER_FRAME, atEveryFrame);
}
// マウスボタンが押されたときの手続き
private function whenMouseDown(e:MouseEvent):void {
var cp:BullsEye; // クリックされた制御点?
if ( c0.isPointedBy(e) ){
cp = c0;
} else if ( c1.isPointedBy(e) ){
cp = c1;
} else if (c2.isPointedBy(e) ) {
cp = c2;
} else {
cp = null;
}
if (cp) {
cp.startDrag(true,boundsRect);
cp.addEventListener(MouseEvent.MOUSE_MOVE,whenYoureDragging);
stage.addEventListener(MouseEvent.MOUSE_UP,whenMouseUp);
}
}
// ドラッグ中の手続き
private function whenYoureDragging(e:MouseEvent):void {
e.updateAfterEvent();
}
// マウスボタンが離されたときの手続き
// どうなるかわからんが, ひとまず全部のボタンに解除動作をさせてみる
private function whenMouseUp(e:MouseEvent):void {
c0.stopDrag();
c0.removeEventListener(MouseEvent.MOUSE_MOVE,whenYoureDragging);
c1.stopDrag();
c1.removeEventListener(MouseEvent.MOUSE_MOVE,whenYoureDragging);
c2.stopDrag();
c2.removeEventListener(MouseEvent.MOUSE_MOVE,whenYoureDragging);
stage.removeEventListener(MouseEvent.MOUSE_UP, whenMouseUp);
}
// アニメーション処理
private function atEveryFrame(e:Event):void {
var th0:Number = getTimer()/4000*Math.PI;
var th1:Number = getTimer()/4100*Math.PI;
var th2:Number = getTimer()/2300*Math.PI;
th0 -= Math.floor(th0/(Math.PI*2))*Math.PI*2;
th1 -= Math.floor(th1/(Math.PI*2))*Math.PI*2;
th2 -= Math.floor(th2/(Math.PI*2))*Math.PI*2;
// 起点は二つの制御点を結ぶ線分上を浮動する
t0 = (1+0.9*Math.sin(th0))/2;
t1 = (1-0.9*Math.sin(th1))/2;
t2 = (1+0.9*Math.sin(th2))/2;
// 起点を動かして再描画
draw();
}
// エントリー・ポイント
public function Main():void {
if ( stage != null ) {
initialize(null);
} else {
this.addEventListener(Event.ADDED_TO_STAGE, initialize);
}
}
} // end of class Main
} // end of package
import flash.display.*;
import flash.events.*;
import flash.geom.*;
// 点の標識として表示されるスプライトのクラス
class BullsEye extends Sprite {
public static const RADIUS:Number = 6;
public static const DEFAULT_COLOR:uint = 0x000000;
private var color:uint;
public function draw():void {
this.graphics.clear();
this.graphics.beginFill(0xffffff);
this.graphics.lineStyle(0,this.color);
this.graphics.drawCircle(0,0,RADIUS);
this.graphics.endFill();
this.graphics.beginFill(this.color);
this.graphics.drawCircle(0,0,RADIUS/5*3);
this.graphics.endFill();
}
// MouseEventオブジェクトの座標を調べ, 自分がポイントされていたら true を返す
public function isPointedBy(e:MouseEvent):Boolean {
var mp:Point = new Point(e.stageX,e.stageY);
var cp:Point = new Point(this.x,this.y);
return ( Point.distance(cp,mp) <= RADIUS );
}
public function BullsEye(c:uint):void {
this.color = c;
this.draw();
}
}