forked from: 【AS100本ノック】3回目:ヒモ
普通のヒモです。
* フィルターで質感を付けてます。
* もう少し気持ちよさを足したい。
*
* wonderflにはfl.motion.BezierSegmentが無いみたいなので
* http://wonderfl.net/code/6008b371d9af079b91c08020d4cfed2db68f640d
* のBezierSegmentクラスに少し手を加えて使わせていただきました。
/**
* Copyright mex_takagi ( http://wonderfl.net/user/mex_takagi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/oG7y
*/
/**
*
* 普通のヒモです。
* フィルターで質感を付けてます。
* もう少し気持ちよさを足したい。
*
* wonderflにはfl.motion.BezierSegmentが無いみたいなので
* http://wonderfl.net/code/6008b371d9af079b91c08020d4cfed2db68f640d
* のBezierSegmentクラスに少し手を加えて使わせていただきました。
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.filters.DropShadowFilter;
import flash.filters.BevelFilter;
/**
* @author Mao Takagi
*/
public class Main extends Sprite
{
private var _rope:Sprite;
private var _marker:Marker;
private var _rootPoint:Point;
private var _rootControlPoint:Point;
private var _endPoint:Point;
private var _endControlPoint:Point;
private var _centerPoint:Point;
/**
* constructor
*/
public function Main():void
{
_marker = new Marker(this);
_rope = new Sprite();
_rootPoint = new Point(0, 0);
_rootControlPoint = new Point(stage.stageWidth * 0.5, stage.stageHeight * 0.5);
_endPoint = new Point(0, 0);
_endControlPoint = new Point(stage.stageWidth * 0.5, stage.stageHeight * 0.5);
_centerPoint = new Point(0, 0);
_rope.filters = [new DropShadowFilter(30, 160, 0x000000, 0.5, 8, 8, 1, 3, false, false, false),
new BevelFilter(3, -155, 0xFF926B, 0.67, 0x190500, 1, 6, 6, 1, 3, "inner", false)];
addChild(_rope);
_rope.addChild(_marker);
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
_rope.y = -20;
}
/**
* enterFrameHandler
* @param event Event
*/
private function enterFrameHandler(event:Event):void
{
onUpdateHandler();
}
/**
* onUpdateHandler
*/
private function onUpdateHandler():void
{
_rootPoint.x = stage.stageWidth / 2;
_rootPoint.y = 0;
_endPoint.x = _marker.x;
_endPoint.y = _marker.y;
_centerPoint.x = (_rootPoint.x + _endPoint.x) * 0.5;
_centerPoint.y = (_rootPoint.y + _endPoint.y) * 0.5;
_rootControlPoint.x += (_centerPoint.x - _rootControlPoint.x) * 0.1;
_rootControlPoint.y += (_centerPoint.y - _rootControlPoint.y) * 0.08;
_endControlPoint.x += (_centerPoint.x - _endControlPoint.x) * 0.1;
_endControlPoint.y += (_centerPoint.y - _endControlPoint.y) * 0.08;
var bezier:BezierSegment = new BezierSegment(_rootPoint, _rootControlPoint, _endControlPoint, _endPoint);
var tCnt:int = 100;
_rope.graphics.clear();
_rope.graphics.moveTo(_rootPoint.x, _rootPoint.y);
_rope.graphics.lineStyle(10, 0x400000);
for (var t = 0; t <= tCnt; t++)
{
var tmpPt:Point = bezier.getValue(t / tCnt);
_rope.graphics.lineTo(tmpPt.x, tmpPt.y);
}
_rope.graphics.beginFill(0x400000);
_rope.graphics.drawCircle(_endPoint.x, _endPoint.y, 20);
_rope.graphics.endFill();
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
class Marker extends Sprite
{
private var _container:Main;
private var _targetX:Number;
private var _targetY:Number;
private var _spring:Number;
private var _vx:Number;
private var _vy:Number;
private var _friction:Number;
private var _gravity:Number;
/**
* constructor
* @param container Main
*/
public function Marker(container:Main)
{
_container = container;
_targetX = _container.stage.stageWidth / 2;
_targetY = _container.stage.stageHeight / 2 - 50;
_spring = 0.1;
_vx = 0;
_vy = 0;
_friction = 0.95;
_gravity = 10;
x = _container.stage.stageWidth / 2;
y = _targetY;
alpha = 0;
//graphics.lineStyle(10, 0x000000)
graphics.beginFill(0x400000);
graphics.drawCircle(0, 0, 20);
graphics.endFill();
buttonMode = true;
addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
addEventListener(MouseEvent.MOUSE_UP, upHandler);
addEventListener(MouseEvent.CLICK, upHandler);
_container.stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);
}
/**
* マウスダウン時、ドラッグ準備。
* @param event MouseEvent
*/
private function downHandler(event:MouseEvent):void
{
startDrag();
addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
if (hasEventListener(Event.ENTER_FRAME)) removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
/**
* マウスムーブ時、ドラッグ。
* @param event MouseEvent
*/
private function moveHandler(event:MouseEvent):void
{
x = _container.stage.mouseX;
y = _container.stage.mouseY;
}
/**
* マウスアップ時、ドラッグ停止。
* @param event MouseEvent
*/
private function upHandler(event:MouseEvent):void
{
stopDrag();
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
}
/**
* バネ。
* @param event Event
*/
private function enterFrameHandler(event:Event):void
{
var dx:Number = _targetX - x;
var dy:Number = _targetY - y;
var ax:Number = dx * _spring;
var ay:Number = dy * _spring;
_vx += ax;
_vy += ay;
_vy += _gravity;
_vx *= _friction;
_vy *= _friction;
x += _vx;
y += _vy;
if (Math.abs(_targetX - x) <= 0.1 && Math.abs(_targetY - y) <= 0.1)
{
x = _targetX;
y = _targetY;
removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
}
}
import flash.geom.Point;
class BezierSegment
{
private var _anchor0:Point;
private var _anchor1:Point;
private var _controll0:Point;
private var _controll1:Point;
public function BezierSegment(anchor0:Point, controll0:Point, controll1:Point, anchor1:Point)
{
_anchor0 = anchor0;
_anchor1 = anchor1;
_controll0 = controll0;
_controll1 = controll1;
}
public function getValue(per:Number):Point
{
if (per < 0 || 1 < per)
{
throw new Error('0<=per<=1で');
}
var p:Number = 1 - per;
return new Point(p * p * p * _anchor0.x + 3 * p * p * per * _controll0.x + 3 * p * per * per * _controll1.x + per * per * per * _anchor1.x,p * p * p * _anchor0.y + 3 * p * p * per * _controll0.y + 3 * p * per * per * _controll1.y + per * per * per * _anchor1.y);
}
}