flash on 2010-2-7
/**
* Copyright termat ( http://wonderfl.net/user/termat )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/QUgk
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.display.GradientType;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
import org.si.sion.*;
import org.si.sion.events.*;
import org.si.sion.utils.SiONPresetVoice;
import flash.geom.Point;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.filters.BlurFilter;
[SWF(framerate="30",width="480",height="480",backgroundColor="0xffffff")]
public class Practice18 extends Sprite{
private var nodes:Vector.<Node>;
private var edges:Vector.<Edge>;
private var rect:Rectangle = new Rectangle(0, 0, 480, 480);
private var baseLen:Number = 8;
private var limit:Number = 12;
private var pick:Node = null;
private var len:Number = 20;
private var count:int;
private var id:int;
public var driver:SiONDriver = new SiONDriver();
public var presetVoice:SiONPresetVoice = new SiONPresetVoice();
public var voices:Vector.<SiONVoice> = new Vector.<SiONVoice>(2);
private var bitmap:BitmapData;
private var blur:BlurFilter = new BlurFilter(20, 20, 8);
private var point:Point = new Point();
public function Practice18():void {
bitmap = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xffffff);
var img:Bitmap = new Bitmap(bitmap);
stage.addChild(img);
var percusVoices:Array = presetVoice["valsound.percus"];
voices[0] = percusVoices[0];
voices[1] = percusVoices[27];
driver.setBeatCallbackInterval(1);
driver.play();
nodes = new Vector.<Node>();
edges = new Vector.<Edge>();
stage.addEventListener(Event.ENTER_FRAME, onFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
Node.FORMAT.size = 28;
Node.FORMAT.color = 0x0000ff;
var str:String = "近畿2府4県は、大阪府、京都府、滋賀県、奈良県、和歌山県、兵庫県です。";
init(str);
}
private function init(str:String):void {
var pre:int = addNode(" ", 500 * Math.random(), 500 * Math.random());
for (var i:int = 0 ; i < str.length; i++) {
var id:int = addNode(str.charAt(i), 500 * Math.random(), 500 * Math.random());
var e:Edge = new Edge();
e.from = pre;
e.to = id;
e.len = baseLen;
nodes[e.from].neigh++;
nodes[e.to].neigh++;
edges.push(e);
pre = id;
}
e = new Edge();
e.from = pre;
e.to = 0;
e.len = baseLen * 10;
nodes[e.from].neigh++;
nodes[e.to].neigh++;
edges.push(e);
}
private function onFrame(evt:Event): void {
bitmap.lock()
bitmap.applyFilter(bitmap, bitmap.rect, point, blur)
bitmap.draw(this);
bitmap.unlock();
relax();
graphics.clear();
for each(var e:Edge in edges) {
var x1:Number = nodes[e.from].x;
var y1:Number = nodes[e.from].y;
var x2:Number = nodes[e.to].x;
var y2:Number = nodes[e.to].y;
var len:Number = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) - e.len;
if (len < 20) {
graphics.lineStyle(1, 0xaaaaaa);
}else {
graphics.lineStyle(1, 0xff0000);
}
graphics.moveTo(nodes[e.from].x, nodes[e.from].y);
graphics.lineTo(nodes[e.to].x, nodes[e.to].y);
}
for each(var n:Node in nodes) {
if (n.fixed) {
graphics.lineStyle(2, 0x0000ff);
graphics.drawCircle(n.x, n.y, n.radius + 2);
}
}
if (pick != null) {
graphics.lineStyle(2, 0xFF0000);
graphics.drawCircle(pick.x, pick.y, pick.radius + 2);
}
if (count++ == 120) {
count = 0;
id = (id + 1) % nodes.length;
driver.noteOn(36, voices[1], 4);
if (nodes[id] == pick || nodes[id].fixed) return;
nodes[id].x = (nodes[id].x * 0.5 + 0.5 * Math.random() * 500);
nodes[id].y = (nodes[id].y * 0.5 + 0.5 * Math.random() * 500);
}else if (count % 30 == 0) {
id = (id + 1) % nodes.length;
driver.noteOn(60, voices[0], 1);
if (nodes[id] == pick || nodes[id].fixed) return;
nodes[id].x = (nodes[id].x * 0.75 + 0.25 * Math.random() * 500);
nodes[id].y = (nodes[id].y * 0.75 + 0.25 * Math.random() * 500);
}else if (count % 20 == 0) {
id = (id + 1) % nodes.length;
driver.noteOn(36, voices[0], 1);
if (nodes[id] == pick || nodes[id].fixed) return;
nodes[id].x = (nodes[id].x * 0.75 + 0.25 * Math.random() * 500);
nodes[id].y = (nodes[id].y * 0.75 + 0.25 * Math.random() * 500);
}
}
private function onMouseDown(e:MouseEvent):void {
for each(var n:Node in nodes) {
if (n.isContain(e.stageX, e.stageY)) {
if (e.shiftKey) {
if (n.fixed) n.fixed = false;
}else {
pick = n;
pick.fixed = true;
}
return;
}
}
pick = null;
}
private function onMouseUp(e:MouseEvent):void {
if(!e.shiftKey)pick.fixed = false;
pick = null;
}
private function onMouseMove(e:MouseEvent):void {
if (pick == null) return;
pick.x = e.stageX;
pick.y = e.stageY;
}
private function relax():void {
for (var i:int = 0; i < edges.length; i++) {
var e:Edge = edges[i];
var vx:Number = nodes[e.to].x - nodes[e.from].x;
var vy:Number = nodes[e.to].y - nodes[e.from].y;
var len:Number = Math.sqrt(vx * vx + vy * vy);
len = Math.max(len, 0.001);
var f:Number = (edges[i].len - len) / (len * 3);
var dx:Number = f * vx;
var dy:Number = f * vy;
nodes[e.to].dx += dx;
nodes[e.to].dy += dy;
nodes[e.from].dx += -dx;
nodes[e.from].dy += -dy;
}
for (i = 0; i < nodes.length; i++) {
var n1:Node = nodes[i];
dx = 0;
dy = 0;
for (var j:int = 0; j < nodes.length; j++) {
if(i==j)continue;
var n2:Node = nodes[j];
vx = n1.x - n2.x;
vy = n1.y - n2.y;
len = vx * vx + vy * vy;
if (len == 0) {
dx += Math.random();
dy += Math.random();
} else if (len < 100*100) {
dx += vx / len;
dy += vy / len;
}
}
var dlen:Number = dx * dx + dy * dy;
if (dlen > 0) {
dlen = Math.sqrt(dlen) / 2;
n1.dx += dx / dlen;
n1.dy += dy / dlen;
}
}
for (i=0;i<nodes.length;i++){
var n:Node = nodes[i];
if (!n.fixed) {
var ll:Number = Math.max(1.5, limit / n.neigh);
n.x += Math.max(-ll, Math.min(ll, n.dx));
n.y += Math.max(-ll, Math.min(ll, n.dy));
}
if (n.x < 0) {
n.x = 0;
} else if (n.x > rect.width) {
n.x = rect.width;
}
if (n.y < 0) {
n.y = 0;
} else if (n.y > rect.height) {
n.y = rect.height;
}
n.dx /= 2;
n.dy /= 2;
}
}
private function addNode(name:String,nx:Number,ny:Number):int {
var n:Node = new Node(name, len);
n.name = name;
n.x = nx;
n.y = ny;
nodes.push(n);
addChild(n);
return nodes.length - 1;
}
}
}
import flash.display.GradientType;
import flash.display.InterpolationMethod;
import flash.display.MovieClip;
import flash.display.SpreadMethod;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.display.Bitmap;
import flash.display.BitmapData;
class Node extends MovieClip {
public static const FORMAT:TextFormat = new TextFormat();
private var text:TextField;
private var backGround:uint = 0xffffff;
public var dx:Number=0;
public var dy:Number=0;
public var neigh:int = 0;
public var fixed:Boolean = false;
public var radius:Number;
public function Node(str:String, r:Number):void {
radius = r;
text = new TextField();
text.defaultTextFormat = FORMAT;
text.text = str;
text.width = text.textWidth;
text.height = text.textHeight;
var mc_tmp:MovieClip = new MovieClip();
mc_tmp.addChild(text);
var bd:BitmapData = new BitmapData(text.textWidth, text.textHeight);
bd.fillRect(bd.rect,backGround);
bd.lock();
bd.draw(mc_tmp);
bd.unlock();
var mc:MovieClip = new MovieClip();
mc.addChild(new Bitmap(bd, "auto", true));
mc.x = -text.textWidth / 2;
mc.y = -text.textHeight / 2;
addChild(mc);
}
public function isContain(px:Number, py:Number):Boolean {
var vx:Number = px - x;
var vy:Number = py - y;
return ((Math.pow(radius+2,2) - (vx * vx + vy * vy)) > 0);
}
}
class Edge extends MovieClip{
public var from:int = 0;
public var to:int = 0;
public var len:Number = 0;
}