/**
* Copyright rxr01676 ( http://wonderfl.net/user/rxr01676 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/6xpu
*/
// forked from rxr01676's forked from: バネの動きの練習
// forked from yuugurenote's バネの動きの練習
// クラス化 - isRunning - toText
// バネの根元を表現するクラス - springRootSprite
// マウスボタンを押している間、バネの束縛を受けない - xPres - xReles - isPulled
// ( ボタンが効かない時がある )
// 直近300フレーム分のspringRootSpriteの位置を保存し、6フレーム分をピックアップして表示
// 形式は nフレーム前:x位置,y位置 - _storeState
// FPSを表示 - xTimer - FPS_REFRESH_RATIO FPSの数値を更新する頻度(回/秒)
// 初期化部分の修正 画面内のどこかをクリックするとバネの運動を開始する - xActivateRoot
// sprintfにパッチ - floatのゼロ埋めフラグ(flagZeroPad)が無効だった仕様を修正
package {
import flash.display.Sprite;
import flash.display.Graphics;
import flash.display.Bitmap;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.display.BitmapData;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.filters.BlurFilter;
import flash.geom.Point;
import flash.utils.Timer;
import flash.utils.getTimer;
import flash.display.StageScaleMode;
[SWF(width=465,height=465,backgroundColor=0x000000,frameRate=60)]
public class AS111113_01 extends Sprite {
public var fps:Number = 0.0;
public var sw:Number=stage.stageWidth;
public var sh:Number=stage.stageHeight;
public var myColor:ColorTransform = new ColorTransform();
public var viewBmd:BitmapData=new BitmapData(sw,sh,false,0x000000);
public var viewBmp:Bitmap=new Bitmap(viewBmd);
public var confTF:ConfigTextField = new ConfigTextField();
public var strCon:StrContainer = new StrContainer('stage');
public var _mySprite:mySprite;
private var _springRoot:SpringRootSprite;
private var activatedRoot:Boolean = false;
private const FPS_REFRESH_RATIO:int = 5;
private var _timer:Timer = new Timer(1000 / FPS_REFRESH_RATIO);
private var _preTimes:Vector.<int> = new Vector.<int>;
private var _totalTime:int = 0;
private var _drawCounts:Vector.<int> = new Vector.<int>;
private var _drawCount:int = 0;
private var _totalDrawCount:int = 0;
public function AS111113_01() {
addChild(viewBmp);
stage.scaleMode = StageScaleMode.NO_SCALE; // import flash.display.StageScaleMode;
myColor.redMultiplier=0.9;
myColor.greenMultiplier=0.9;
myColor.blueMultiplier=0.9;
_springRoot = new SpringRootSprite(this);
addChild(_springRoot);
_mySprite = new mySprite(this);
addChild(_mySprite);
confTF.watch(this.strCon);
confTF.watch(_springRoot.strCon);
confTF.watch(_mySprite.strCon);
confTF.textColor = 0xFFFFFF;
confTF.autoSize = TextFieldAutoSize.LEFT; // import flash.text.TextFieldAutoSize;
addChild(confTF);
_timer.addEventListener(TimerEvent.TIMER, xTimer);
var _now:int = getTimer();
for (var i:int = 0; i < FPS_REFRESH_RATIO; i++) {
_drawCounts.unshift(0);
_preTimes.unshift(_now); }
_timer.start();
addEventListener(Event.ENTER_FRAME, xEnter);
addEventListener(Event.ENTER_FRAME, xDraw);
stage.addEventListener(MouseEvent.CLICK, xActivateRoot);
}
public function xActivateRoot(e:Event):void {
if (!activatedRoot) {
_springRoot.bind(_mySprite);
_springRoot.isTracing = true;
activatedRoot = true;
stage.removeEventListener(MouseEvent.CLICK, xActivateRoot);
}
}
public function xTimer(te:TimerEvent):void {
var _now:int = getTimer();
_totalTime = _now - _preTimes.pop();
_preTimes.unshift(_now);
_totalDrawCount += _drawCount;
_totalDrawCount -= _drawCounts.pop();
_drawCounts.unshift(_drawCount);
_drawCount = 0;
if ( _totalTime > 0 ) {
fps = Number(_totalDrawCount)*1000.0 / Number(_totalTime);
}
}
public function xDraw(e:Event):void {
viewBmd.draw(stage,null,myColor);
viewBmd.applyFilter(viewBmd, viewBmd.rect, new Point(), new BlurFilter(8, 8, 3));
_drawCount++;
}
private function _setText():void {
strCon.text = sprintf( ' FPS: %06.2f\n', fps);
if (activatedRoot) { strCon.text += ' Activated\n'; } else { strCon.text += '\n'; }
}
private function xEnter(e:Event):void {
_springRoot.updateState();
_mySprite.updateState();
_setText();
confTF.updateContents();
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.geom.Point;
import flash.text.TextField;
class StrContainer extends Object {
public var header:String = '';
public var text:String = '';
public var isExpanded:Boolean = true;
public function StrContainer( hd:String ) { this.header = hd; }
public function getHeader():String { return header; };
public function getText():String {
if (this.isExpanded) { return text; } else { return ''; }
}
}
class ConfigTextField extends TextField {
public var watchList:Vector.<StrContainer> = new Vector.<StrContainer>;
public function watch( tc:StrContainer ):void {
watchList.push( tc );
}
public function updateContents(): void {
var s:String = '';
for (var i:int = 0; i < watchList.length; i++ ) {
s += watchList[i].getHeader()+'\n';
s += watchList[i].getText(); }
this.text = s;
}
}
class SpriteEx extends Sprite {
public var _stageWidth:int = 0;
public var _stageHeight:int = 0;
public var bottomSprite:Sprite;
public var posX:Number = 0;
public var posY:Number = 0;
public function SpriteEx(bs:Sprite) {
bottomSprite = bs;
_stageWidth = this.bottomSprite.stage.stageWidth;
_stageHeight = this.bottomSprite.stage.stageHeight;
this.addEventListener(Event.ADDED, this.xAdded);
}
public function xAdded(e:Event):void {}
}
class SpringRootSprite extends SpriteEx {
private const TOTAL_POINTS:int = 300;
private const TOP_POINTS:int = 30;
private var _memPts:Vector.<Point> = new Vector.<Point>(TOTAL_POINTS);
private var _topInd:Vector.<int> = new Vector.<int>;//(TOP_POINTS);
public var isPulling:Boolean=false;
public var isTracing:Boolean=false;
public var hasChild:Boolean=false;
public var childSprite:mySprite;
public var strCon:StrContainer = new StrContainer('root');
public function SpringRootSprite(bs:Sprite) {
super(bs);
this.graphics.beginFill(0x7F7FFF,1);
this.graphics.drawCircle(0,0,5);
this.graphics.endFill();
for ( var i:int = 0; i < TOTAL_POINTS; i++ ) { _memPts[i] = new Point(0,0); }
for ( i = 0; i < TOP_POINTS; i++ ) { _topInd.unshift(i); }
}
public override function xAdded(e:Event):void {
super.xAdded(e);
stage.addEventListener(MouseEvent.MOUSE_DOWN, xPulling);
stage.addEventListener(MouseEvent.MOUSE_UP, xPulling);
stage.addEventListener(MouseEvent.MOUSE_OVER, xPulling);
// this.isTracing = true;
this.posX = _stageWidth * 2/ 3 - this.width / 2;
this.posY = _stageHeight / 2 - this.height / 2;
this.x = this.posX;
this.y = this.posY;
}
public function xPulling(me:MouseEvent):void {
this.isPulling = !me.buttonDown;
}
private function _storeState():void {
var tc:int = _topInd[0];
tc++;
if(tc==TOTAL_POINTS){tc=0;}
_topInd.unshift(tc);
_topInd.pop();
_memPts[tc].x = this.posX;
_memPts[tc].y = this.posY;
}
public function updateState():void {
if(this.isTracing) {
this.posX = bottomSprite.mouseX;
this.posY = bottomSprite.mouseY;
}
this.x=this.posX;
this.y=this.posY;
if( this.hasChild ){
childSprite.oriX=this.posX;
childSprite.oriY=this.posY;
childSprite.isPulled = this.isPulling;
}
_storeState();
this._setText();
}
private function _setText():void {
strCon.text = '';
strCon.text += sprintf(' %03d : x=%+010.3f \t y=%+010.3f \t', 0, _memPts[_topInd[0]].x, _memPts[_topInd[0]].y);
strCon.text += sprintf(' %03d : x=%+010.3f \t y=%+010.3f \n', 5, _memPts[_topInd[5]].x, _memPts[_topInd[5]].y);
strCon.text += sprintf(' %03d : x=%+010.3f \t y=%+010.3f \t', 10, _memPts[_topInd[10]].x, _memPts[_topInd[10]].y);
strCon.text += sprintf(' %03d : x=%+010.3f \t y=%+010.3f \n', 15, _memPts[_topInd[15]].x, _memPts[_topInd[15]].y);
strCon.text += sprintf(' %03d : x=%+010.3f \t y=%+010.3f \t', 20, _memPts[_topInd[20]].x, _memPts[_topInd[20]].y);
strCon.text += sprintf(' %03d : x=%+010.3f \t y=%+010.3f \n', 25, _memPts[_topInd[25]].x, _memPts[_topInd[25]].y);
}
public function bind(ms:mySprite):void {
childSprite = ms;
this.hasChild = true;
this.isPulling = true;
}
}
class mySprite extends SpriteEx {
private var _preX:Number=0;
private var _preY:Number=0;
public var oriX:Number=0;
public var oriY:Number=0;
public var speedX:Number=0;
public var speedY:Number=0;
public var minRunningSpeed:Number=0.01;
public var isRunning:Boolean=false;
public var isPulled:Boolean=false;
public var spring:Number=0.1;
public var friction:Number=0.89;
public var strCon:StrContainer = new StrContainer('node');
private function _updateRunningState():void {
if (this.isRunning) {
if (Math.abs(this.speedX)<this.minRunningSpeed && Math.abs(this.speedY)<this.minRunningSpeed) {
this.isRunning=false;
this._preX=Math.round(this.x);
this._preY=Math.round(this.y);
}
}
else {
if (this._preX != Math.round(this.x) || this._preY != Math.round(this.y)) {
this.isRunning=true;
}
}
}
private function _updateSpeed():void {
var myIntX:Number=this.oriX-this.posX;
var myIntY:Number=this.oriY-this.posY;
this.speedX+=myIntX*this.spring;
this.speedY+=myIntY*this.spring;
this.speedX*=this.friction;
this.speedY*=this.friction;
}
private function _setText():void {
strCon.text = '';
strCon.text+=sprintf(' x=%+010.3f \ty=%+010.3f \tox=%+010.3f \toy=%+010.3f\n', x, y, oriX, oriY);
strCon.text+=sprintf(' vx=%+010.5f \tvy=%+010.5f\n', speedX, speedY);
if (isRunning) { strCon.text += ' Running'; }
if (isPulled) { strCon.text += ' Pulled\n'; } else { strCon.text += '\n'; }
}
public function mySprite(bs:Sprite) {
super(bs);
this.graphics.beginFill(0x00FF7F,1);
this.graphics.drawCircle(0,0,5);
this.graphics.endFill();
}
public override function xAdded(e:Event):void {
super.xAdded(e);
this.posX = _stageWidth / 3 - this.width / 2;
this.posY = _stageHeight / 2 - this.height / 2;
this.x = this.posX;
this.y = this.posY;
this._preX = this.posX;
this._preY = this.posY;
this.oriX = this.posX;
this.oriY = this.posY;
}
public function updateState():void {
if(this.isPulled){ this._updateSpeed(); }
this.posX+=this.speedX;
this.posY+=this.speedY;
this.x=this.posX;
this.y=this.posY;
this._updateRunningState();
this._setText();
}
}
/**
* Copyright (c) 2008. Adobe Systems Incorporated.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Adobe Systems Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* sprintf(3) implementation in ActionScript 3.0.
*
* Author: Manish Jethani (manish.jethani@gmail.com)
* Date: April 3, 2006
* Version: 0.1
*
* Copyright (c) 2006 Manish Jethani
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/* sprintf(3) implementation in ActionScript 3.0.
*
* http://www.die.net/doc/linux/man/man3/sprintf.3.html
*
* The following flags are supported: '#', '0', '-', '+'
*
* Field widths are fully supported. '*' is not supported.
*
* Precision is supported except one difference from the standard: for an
* explicit precision of 0 and a result string of "0", the output is "0"
* instead of an empty string.
*
* Length modifiers are not supported.
*
* The following conversion specifiers are supported: 'd', 'i', 'o', 'u', 'x',
* 'X', 'f', 'F', 'c', 's', '%'
*
* Report bugs to manish.jethani@gmail.com
*/
function sprintf(format:String, ... args):String
{
var result:String = "";
var length:int = format.length;
var next:*;
var str:String;
for (var i:int = 0; i < length; i++)
{
var c:String = format.charAt(i);
if (c == "%")
{
var pastFieldWidth:Boolean = false;
var pastFlags:Boolean = false;
var flagAlternateForm:Boolean = false;
var flagZeroPad:Boolean = false;
var flagLeftJustify:Boolean = false;
var flagSpace:Boolean = false;
var flagSign:Boolean = false;
var fieldWidth:String = "";
var precision:String = "";
c = format.charAt(++i);
while (c != "d"
&& c != "i"
&& c != "o"
&& c != "u"
&& c != "x"
&& c != "X"
&& c != "f"
&& c != "F"
&& c != "c"
&& c != "s"
&& c != "%")
{
if (!pastFlags)
{
if (!flagAlternateForm && c == "#")
flagAlternateForm = true;
else if (!flagZeroPad && c == "0")
flagZeroPad = true;
else if (!flagLeftJustify && c == "-")
flagLeftJustify = true;
else if (!flagSpace && c == " ")
flagSpace = true;
else if (!flagSign && c == "+")
flagSign = true;
else
pastFlags = true;
}
if (!pastFieldWidth && c == ".")
{
pastFlags = true;
pastFieldWidth = true;
c = format.charAt(++i);
continue;
}
if (pastFlags)
{
if (!pastFieldWidth)
fieldWidth += c;
else
precision += c;
}
c = format.charAt(++i);
}
switch (c)
{
case "d":
case "i":
next = args.shift();
str = String(Math.abs(int(next)));
if (precision != "")
str = leftPad(str, int(precision), "0");
if (int(next) < 0)
str = "-" + str;
else if (flagSign && int(next) >= 0)
str = "+" + str;
if (fieldWidth != "")
{
if (flagLeftJustify)
str = rightPad(str, int(fieldWidth));
else if (flagZeroPad && precision == "")
str = leftPad(str, int(fieldWidth), "0");
else
str = leftPad(str, int(fieldWidth));
}
result += str;
break;
case "o":
next = args.shift();
str = uint(next).toString(8);
if (flagAlternateForm && str != "0")
str = "0" + str;
if (precision != "")
str = leftPad(str, int(precision), "0");
if (fieldWidth != "")
{
if (flagLeftJustify)
str = rightPad(str, int(fieldWidth));
else if (flagZeroPad && precision == "")
str = leftPad(str, int(fieldWidth), "0");
else
str = leftPad(str, int(fieldWidth));
}
result += str;
break;
case "u":
next = args.shift();
str = uint(next).toString(10);
if (precision != "")
str = leftPad(str, int(precision), "0");
if (fieldWidth != "")
{
if (flagLeftJustify)
str = rightPad(str, int(fieldWidth));
else if (flagZeroPad && precision == "")
str = leftPad(str, int(fieldWidth), "0");
else
str = leftPad(str, int(fieldWidth));
}
result += str;
break;
case "X":
var capitalise:Boolean = true;
case "x":
next = args.shift();
str = uint(next).toString(16);
if (precision != "")
str = leftPad(str, int(precision), "0");
var prepend:Boolean = flagAlternateForm && uint(next) != 0;
if (fieldWidth != "" && !flagLeftJustify
&& flagZeroPad && precision == "")
str = leftPad(str, prepend
? int(fieldWidth) - 2 : int(fieldWidth), "0");
if (prepend)
str = "0x" + str;
if (fieldWidth != "")
{
if (flagLeftJustify)
str = rightPad(str, int(fieldWidth));
else
str = leftPad(str, int(fieldWidth));
}
if (capitalise)
str = str.toUpperCase();
result += str;
break;
case "f":
case "F":
next = args.shift();
str = Math.abs(Number(next)).toFixed(
precision != "" ? int(precision) : 6);
/* original
if (int(next) < 0)
str = "-" + str;
else if (flagSign && int(next) >= 0)
str = "+" + str;
*/
// patch
if(!flagZeroPad){
if (int(next) < 0)
str = "-" + str;
else if (flagSign && int(next) >= 0)
str = "+" + str;
}
// end of patch
if (flagAlternateForm && str.indexOf(".") == -1)
str += ".";
if (fieldWidth != "")
{
/* original
if (flagLeftJustify)
str = rightPad(str, int(fieldWidth));
else if (flagZeroPad && precision == "")
str = leftPad(str, int(fieldWidth), "0");
else
str = leftPad(str, int(fieldWidth));
*/
// patch
if (flagLeftJustify)
str = rightPad(str, int(fieldWidth));
else if (flagZeroPad)
if( (int(next) < 0) || (flagSign && int(next) >= 0) )
str = leftPad(str, int(fieldWidth) - 1, "0"); // add Sign after ZeroPad
else
str = leftPad(str, int(fieldWidth) , "0");
else
str = leftPad(str, int(fieldWidth));
// end of patch
}
// patch
if(flagZeroPad){
if (int(next) < 0)
str = "-" + str;
else if (flagSign && int(next) >= 0)
str = "+" + str;
}
// end of patch
result += str;
break;
case "c":
next = args.shift();
str = String.fromCharCode(int(next));
if (fieldWidth != "")
{
if (flagLeftJustify)
str = rightPad(str, int(fieldWidth));
else
str = leftPad(str, int(fieldWidth));
}
result += str;
break;
case "s":
next = args.shift();
str = String(next);
if (precision != "")
str = str.substring(0, int(precision));
if (fieldWidth != "")
{
if (flagLeftJustify)
str = rightPad(str, int(fieldWidth));
else
str = leftPad(str, int(fieldWidth));
}
result += str;
break;
case "%":
result += "%";
}
}
else
{
result += c;
}
}
return result;
}
// Private functions
function leftPad(source:String, targetLength:int, padChar:String = " "):String
{
if (source.length < targetLength)
{
var padding:String = "";
while (padding.length + source.length < targetLength)
padding += padChar;
return padding + source;
}
return source;
}
function rightPad(source:String, targetLength:int, padChar:String = " "):String
{
while (source.length < targetLength)
source += padChar;
return source;
}