FoxsukeTail
狐の尻尾です。ちょっとプルプルしすぎです。
細かい修正や、説明コメントはまだ
キーボードのLで、ロック解除
キーボードのDで、骨組み表示
改造次第で、IEにも、Safariにもなる気がします。もれなくプルプルしてると思いますが。
画像:http://foxkeh.jp/downloads/parts/
Thanks!
経緯
tail_y:なんで人間には尻尾ついてないんだろうね?いいじゃんね、尻尾くらいあってもさ。
alumican_net:@tail_y テイルズみたいに飛べる尻尾がほしい
AtuyL:@tail_y 尻尾あったら「しっぽアート」とか「ゆるフワしっぽで激モテ」とかで経済効果が見込めますね
coppieee:@tail_y ちょっと尻尾ほしくなった。
tail_y:こんだけASerに尻尾好きがいるってことはwonderflに尻尾コンテンツ投下したら大人気じゃね!?
/**
* Copyright paq ( http://wonderfl.net/user/paq )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7zig
*/
package
{
/*
狐の尻尾です。ちょっとプルプルしすぎです。
細かい修正や、説明コメントはまだ
キーボードのLで、ロック解除
キーボードのDで、骨組み表示
改造次第で、IEにも、Safariにもなる気がします。もれなくプルプルしてると思いますが。
画像:http://foxkeh.jp/downloads/parts/
Thanks!
*/
/*
経緯
tail_y:なんで人間には尻尾ついてないんだろうね?いいじゃんね、尻尾くらいあってもさ。
alumican_net:@tail_y テイルズみたいに飛べる尻尾がほしい
AtuyL:@tail_y 尻尾あったら「しっぽアート」とか「ゆるフワしっぽで激モテ」とかで経済効果が見込めますね
coppieee:@tail_y ちょっと尻尾ほしくなった。
tail_y:こんだけASerに尻尾好きがいるってことはwonderflに尻尾コンテンツ投下したら大人気じゃね!?
*/
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.DisplayObjectContainer;
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.InterpolationMethod;
import flash.display.SpreadMethod;
import flash.display.Sprite;
import flash.display.StageQuality;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.filters.BevelFilter;
import flash.filters.BitmapFilterQuality;
import flash.filters.BlurFilter;
import flash.filters.GlowFilter;
import flash.filters.GradientGlowFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
public class FoxTail extends Sprite
{
public function FoxTail()
{
addEventListener(Event.ADDED_TO_STAGE, init); // flexBuilderとの互換性。
//Wonderfl.capture_delay(1); // キャプチャを遅らせます。
}
public static const STAGE_W:uint = 465;
public static const STAGE_H:uint = 465;
private static const _PI:Number = Math.PI;
private static const _PI2:Number = 2.0 * _PI;
private static const _WALL_LEFT:Number = 0;
private static const _WALL_RIGHT:Number = 465;
private static const _GROUND_LINE:Number = 400;
private static const _DERIVATION:int = 4;
private static const _GRAVITY:Number = 0.4 / _DERIVATION;
private static const _ROTATION_RATE:Number = 0.05 / _DERIVATION; // 自身バネ(根元)
private static const _VERTICAL_RATE:Number = 0.5 / _DERIVATION; // ターゲットバネ(さきっぽ)
private static const _MOUSE_PULL_RATE:Number = 0.3 / _DERIVATION;
private static const _FRICTION:Number = 1 - 0.1 / _DERIVATION;
private static const _MOUSE_ROTATE_FRICTION:Number = 1 - 0.8 / _DERIVATION;
private static const _MOUSE_MOVE_FRICTION:Number = 1 - 0.5 / _DERIVATION;
private static const _COLOR:uint = 0xE8B453;
private var _boneList:Array = [];
private var _dragId:int = -1;
private var _boneLayer:Sprite;
private var _displayLayer:Sprite;
private var _displayWhiteLayer:Sprite;
private var _shadowLayer:Bitmap;
private var _shadow:BitmapData = new BitmapData(STAGE_W, STAGE_H, true, 0x00000000);
private var _clear:BitmapData = new BitmapData(STAGE_W, STAGE_H, false, 0x888888);
private var _cover:BitmapData = new BitmapData(STAGE_W, STAGE_H, true, 0x00000000);
private var _bevel:BevelFilter = new BevelFilter(25, 100, 0x000000, 0, 0xBD9243, 1, 35, 35, 1, 1);
private var _topLock:Boolean = true;
private static const _LOCK_Y:int = 160;
private function init(e:Event):void { // ここから開始
removeEventListener(Event.ADDED_TO_STAGE, init);
// SWF設定
stage.frameRate = 30;
stage.quality = StageQuality.MEDIUM;
var bg:Sprite = new Sprite(); // wonderflではキャプチャに背景色が反映されないので、背景色Spriteで覆う。
bg.graphics.beginFill(0xffffff, 1);
bg.graphics.drawRect(0, 0, STAGE_W, STAGE_H);
addChild(bg);
var foxsuke:DisplayObjectContainer = Base64ImageLoader.load("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")
// 色々準備
var coverGradient:Sprite = new Sprite();
var matrix:Matrix = new Matrix()
matrix.createGradientBox(STAGE_W, STAGE_H, Math.PI / 2, STAGE_W / 2, STAGE_H / 2)
coverGradient.graphics.beginGradientFill(GradientType.LINEAR, [0xffffff, 0xffffff], [1, 0], [0, 230], matrix);
coverGradient.graphics.drawRect(0, 0, STAGE_W, STAGE_H);
_cover.draw(coverGradient);
_shadowLayer = new Bitmap(_shadow);
_displayLayer = new Sprite();
//_displayWhiteLayer = new Sprite();
//_displayLayer.filters = [new BlurFilter(10, 10, 4)];
_boneLayer = new Sprite();
addChild(_shadowLayer);
foxsuke.x = 200;
foxsuke.y = -80;
addChild(foxsuke);
addChild(_displayLayer);
//addChild(_displayWhiteLayer);
addChild(_boneLayer);
_boneLayer.alpha = 0; // マウスを取ってもらうので、完全には消さない
_displayLayer.filters = [_bevel, new GlowFilter(0xFF0000, 0.3, 20, 20, 2, BitmapFilterQuality.MEDIUM, false, false)];
// 骨組みを用意する。
var i:int=0;
var tmpR:Number = 0;
addBone(tmpR+= 1, 15);
addBone(tmpR+= 7, 22);
addBone(tmpR+= 10, 30);
addBone(tmpR+= 10, 30);
addBone(tmpR+= 10, 30);
addBone(tmpR+= 6, 30);
addBone(tmpR+= 3, 30);
addBone(tmpR-= 4, 30);
addBone(tmpR-= 7, 30);
addBone(tmpR-= 12, 30);
addBone(tmpR-= 12, 20);
// ドラッグ解除
stage.addEventListener(MouseEvent.MOUSE_UP, bornMouseUpEvent());
// フレームの処理を登録
addEventListener(Event.ENTER_FRAME, frame);
// キーの処理を登録
stage.addEventListener(KeyboardEvent.KEY_DOWN, key);
}
private var _id:int = 0;
private var _lastX:Number = 50;
private function addBone(radius:Number, connectLength:Number):void{
var bone:BoneCircle = new BoneCircle(radius, connectLength);
bone.y = _LOCK_Y;
bone.x = _lastX;
_boneList.push(bone);
_boneLayer.addChild(bone);
// マウスイベント
bone.addEventListener(MouseEvent.MOUSE_DOWN, bornMouseDownEvent(_id++));
_lastX += connectLength;
}
// フレーム挙動
private function frame(event:Event):void{
for (var i:int=0; i<_DERIVATION; i++){
rotate();
foce();
move();
}
draw();
drawShadow();
debugDraw();
}
// ボーンの向きを決定する
private function rotate():void{
var l:int = _boneList.length;
for (var i:int=0; i < l; i++){
var baceBone:BoneCircle = _boneList[i];
var targetBone:BoneCircle = _boneList[i+1];
if (i + 1 < l){
calcConnectRForce(baceBone, targetBone, 0);
calcConnectRForce(targetBone, baceBone, _PI);
}
if (i == _dragId) baceBone.vr *= _MOUSE_ROTATE_FRICTION;
baceBone.vr *= _FRICTION; // 摩擦
}
}
// 接続されたパーツの回転方向を計算する
private function calcConnectRForce(baceBone:BoneCircle, targetBone:BoneCircle, connectAngle:Number):void{
var angle:Number = Math.atan2(targetBone.y - baceBone.y, targetBone.x - baceBone.x);
baceBone.vr += ajustRadian(angle - (connectAngle + baceBone.radian)) * _ROTATION_RATE;
}
// 力関係、加速度を整理する。
private function foce():void{
var i:int;
var l:int = _boneList.length;
var bone:BoneCircle;
for (i=0; i < l; i++){
bone = _boneList[i];
bone.vy += _GRAVITY;
if (_dragId == i){ // マウスで引っ張る
var vPoint:Point = pullForce(bone.x, bone.y, mouseX, mouseY, _MOUSE_PULL_RATE);
bone.vx += vPoint.x;
bone.vy += vPoint.y;
}
if (i + 1 < l){
calcConnectFoce(bone, _boneList[i+1], 0);
calcConnectFoce(_boneList[i+1], bone, _PI);
}
// 摩擦
bone = _boneList[i];
bone.vx *= _FRICTION;
bone.vy *= _FRICTION;
if (i == _dragId){
bone.vx *= _MOUSE_MOVE_FRICTION;
bone.vy *= _MOUSE_MOVE_FRICTION;
}
}
}
// 接続された2パーツの力を計算する
private function calcConnectFoce(baceBone:BoneCircle, targetBone:BoneCircle, connectAngle:Number):void{
var toAngle:Number = ajustRadian(connectAngle + baceBone.radian);
var toX:Number = baceBone.x + Math.cos(toAngle) * baceBone.connectLength;
var toY:Number = baceBone.y + Math.sin(toAngle) * baceBone.connectLength;
var vx:Number = (targetBone.x - toX) * _VERTICAL_RATE;
var vy:Number = (targetBone.y - toY) * _VERTICAL_RATE;
baceBone.vx += vx;
baceBone.vy += vy;
targetBone.vx -= vx;
targetBone.vy -= vy;
}
// ポイントx1 y1を、ポイントx2 y2へ、係数rateだけ移動させる場合の、XYの力を返す
private function pullForce(x1:Number, y1:Number, x2:Number, y2:Number, rate:Number):Point{
var point:Point = new Point();
var distance:Number = calcDistance(x1, y1, x2, y2);
var angle:Number = Math.atan2(y2 - y1, x2 - x1);
point.x = Math.cos(angle) * distance * rate;
point.y = Math.sin(angle) * distance * rate;
return point;
}
// ポイントx1 y1から、ポイントx2 y2までの距離
private function calcDistance(x1:Number, y1:Number, x2:Number, y2:Number):Number{
return Math.sqrt(Math.pow(x2-x1, 2) + Math.pow(y2-y1, 2));
}
// radian角度を、-π~πの範囲に修正する
private function ajustRadian(radian:Number):Number{
return radian - _PI2 * Math.floor( 0.5 + radian / _PI2);
}
// 移動を反映。
private function move():void {
for (var i:int=0; i < _boneList.length; i++){
var bone:BoneCircle = _boneList[i];
bone.x += bone.vx;
bone.y += bone.vy;
bone.radian += bone.vr;
// 壁チェック
if (0 < bone.vy && _GROUND_LINE - bone.radius < bone.y){
bone.y = _GROUND_LINE - bone.radius;
bone.vy = 0;
}
if (bone.vx < 0 && bone.x < _WALL_LEFT + bone.radius){
bone.x = _WALL_LEFT + bone.radius;
bone.vx = 0;
}else if (0 < bone.vx && _WALL_RIGHT - bone.radius < bone.x){
bone.x = _WALL_RIGHT - bone.radius;
bone.vx = 0;
}
// 回転方向を反映
bone.rotation = bone.radian * 180 / Math.PI;
}
if (_topLock){
bone = _boneList[_boneList.length - 1];
bone.vy = 0;
bone.y = _LOCK_Y;
bone.vx = 0;
bone.x = 320;
}
}
// 表示。
private function draw():void{
var pointListX:Array = [];
var pointListY:Array = [];
var i:int;
var l:int = _boneList.length;
for (i=0; i < l; i++){
var bone:BoneCircle = _boneList[i];
var cosR:Number = Math.cos(bone.radian + _PI/2)*bone.radius;
var sinR:Number = Math.sin(bone.radian + _PI/2)*bone.radius;
pointListX.push(bone.x + cosR);
pointListY.push(bone.y + sinR);
pointListX.unshift(bone.x - cosR);
pointListY.unshift(bone.y - sinR);
}
var g:Graphics = _displayLayer.graphics;
g.clear();
//g.beginLinearGradientFill
SmartGradient.beginLinearGradientFill(_displayLayer, [0xB8120D,0xFEFD01], [1, 1], [50,250],new Point(_boneList[0].x, 200), new Point(_boneList[0].x, 350));
l = pointListX.length - 1;
i = 0;
var baceX:Number = (pointListX[i] + pointListX[i+1])/2;
var baceY:Number = (pointListY[i] + pointListY[i + 1]) / 2;
g.moveTo(baceX, baceY);
for (i=1; i < l; i++){
g.curveTo(pointListX[i], pointListY[i], (pointListX[i] + pointListX[i+1])/2, (pointListY[i] + pointListY[i+1])/2);
}
g.lineTo(baceX, baceY);
/*g.beginFill(0xFFFFFF, 1);
l = pointListX.length - 5;
i = 0;
baceX = (pointListX[i+15] + pointListX[i+14])/2;
baceY = (pointListY[i+15] + pointListY[i+14])/2;
g.moveTo(baceX, baceY);
for (i=6; i < l; i++){
g.curveTo(pointListX[i], pointListY[i], (pointListX[i] + pointListX[i+1])/2, (pointListY[i] + pointListY[i+1])/2);
}*/
/*var gw:Graphics = _displayWhiteLayer.graphics;
gw.clear();
gw.beginFill(0xFFFFFF, 1);
l = pointListX.length - 5;
i = 0;
baceX = (pointListX[i+15] + pointListX[i+16])/2;
baceY = (pointListY[i+15] + pointListY[i+16])/2;
gw.moveTo(baceX, baceY);
for (i=5; i < l; i++){
gw.curveTo(pointListX[i], pointListY[i], (pointListX[i] + pointListX[i+1])/2, (pointListY[i] + pointListY[i+1])/2);
}*/
}
private var _rect:Rectangle = new Rectangle(0, 0, STAGE_W, STAGE_H);
private var _point:Point = new Point();
private var _shadowMatrix:Matrix = new Matrix(1, 0, 0, 0.5, 0, STAGE_H/2-30);
private var _shadowColor:ColorTransform = new ColorTransform(0,0,0,1, 0,0,0,0);
private var _shadowBlur:BlurFilter = new BlurFilter(30, 30, 1);
private function drawShadow():void{
_shadow.lock();
_shadow.copyPixels(_clear, _rect, _point);
_shadow.draw(_displayLayer, _shadowMatrix, _shadowColor);
_shadow.applyFilter(_shadow, _rect, _point, _shadowBlur);
_shadow.draw(_cover);
_shadow.unlock();
}
// デバッグ表示。
private function debugDraw():void{
}
// マウスイベント
private function bornMouseDownEvent(i:int):Function{
return function (event:Event):void{ startBornDrag(i);};
}
private function bornMouseUpEvent():Function{
return function (event:Event):void{ endBornDrag();};
}
// ドラッグ
private function startBornDrag(bornNum:int):void{
_dragId = bornNum;
}
private function endBornDrag():void{
_dragId = -1;
}
private function key(event:KeyboardEvent):void{
if (event.keyCode == 76){ // L
trace("changeLock");
_topLock = !_topLock;
}
if (event.keyCode == 68){ // D
trace("changeDisplay");
_boneLayer.alpha = _boneLayer.alpha ? 0 : 1;
}
}
}
}
import flash.display.Sprite;
class BoneCircle extends Sprite
{
public var radius:Number; // 半径
public var connectLength:Number; // 次パーツとのつながりの長さ
public var radian:Number = 0; // 一時的な回転量。
public var vx:Number = 0;
public var vy:Number = 0;
public var vr:Number = 0;
public function BoneCircle(radius:Number, connectLength:Number)
{
this.radius = radius;
this.connectLength = connectLength;
graphics.beginFill(0xff0000, 0.02);
graphics.lineStyle(0, 0, 0);
graphics.drawCircle(0, 0, radius + 20);
graphics.beginFill(0x0000ff, 0.3);
graphics.lineStyle(1, 0x000088, 1);
graphics.drawCircle(0, 0, radius);
graphics.moveTo(-radius + 10, 0);
graphics.lineTo(radius + 10, 0);
}
}
import flash.display.GradientType;
import flash.display.InterpolationMethod;
import flash.display.SpreadMethod;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
class SmartGradient
{
public static function beginRadialGradientFill(target:Sprite, colors:Array, alphas:Array, ratios:Array, centerPoint:Point, radius:Number, spreadMethod:String = null, interpolationMethod:String = null):void
{
spreadMethod ||= SpreadMethod.PAD;
interpolationMethod ||= InterpolationMethod.RGB;
var mat:Matrix = new Matrix();
mat.createGradientBox(radius * 2, radius * 2, 0, centerPoint.x - radius, centerPoint.y - radius);
target.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios, mat, spreadMethod, interpolationMethod);
}
public static function beginLinearGradientFill(target:Sprite, colors:Array, alphas:Array, ratios:Array, startPoint:Point, endPoint:Point, spreadMethod:String = null, interpolationMethod:String = null):void
{
spreadMethod ||= SpreadMethod.PAD;
interpolationMethod ||= InterpolationMethod.RGB;
var dx:Number = endPoint.x - startPoint.x;
var dy:Number = endPoint.y - startPoint.y;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
var rad:Number = Math.atan2(dy, dx);
var offsetX:Number = -(dist - Math.cos(rad) * dist) * 0.5 + startPoint.x;
var offsetY:Number = -(dist - Math.sin(rad) * dist) * 0.5 + startPoint.y;
var mat:Matrix = new Matrix();
mat.createGradientBox(dist, dist, rad, offsetX, offsetY);
target.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, mat, spreadMethod, interpolationMethod);
}
}
class Base64ImageLoader
{
import flash.display.DisplayObjectContainer;
import flash.display.Loader;
import flash.utils.ByteArray;
import mx.utils.Base64Decoder;
static public function load(data:String):DisplayObjectContainer
{
var byteArray:ByteArray;
var base64Decoder:Base64Decoder;
var loader:Loader;
base64Decoder = new Base64Decoder();
base64Decoder.decode(data);
try {
byteArray = base64Decoder.toByteArray();
byteArray.position = 0;
} catch (e:Error) {
return null;
}
loader = new Loader();
loader.loadBytes(byteArray);
return loader;
}
}