/**
* Copyright shohei909 ( http://wonderfl.net/user/shohei909 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/mmtJ
*/
package {
//柔らかい物体を作る
import com.bit101.components.*;
import flash.display.*;
import flash.events.Event;
public class SoftTest extends Sprite {
//重力[x方向の加速度, y方向の加速度]
static public var GRAVITY:Array = [0.0, 0.8];
public var objectList:Vector.<SoftObject> = new Vector.<SoftObject>();
public var box:HBox;
public var button:PushButton;
public var label:Label;
public function SoftTest(){
box = new HBox(this,2,2);
button = new PushButton(box,0,0,"create",create);
label = new Label(box,0,0,"Nothing happen...");
addEventListener("enterFrame",move);
//壁を描く
var wall:SoftObject = new SoftObject();
addChild(wall);
objectList.push(wall);
wall.dotFrictionX = 10000;
wall.dotFrictionY = 10000;
wall.dotMass= 10000;
wall.add([ [0,400],[0,465],[465,465],[465,400] ]);
}
//物体の生成
public function create(e:Event):void{
var object:SoftObject = new SoftObject();
addChild(object);
objectList.push(object);
//正多角形を描く(中心のx座標,中心のy座標,角の数,半径)
object.circle(5,20);
object.x=235;
object.y=35;
object.resize(2);
}
public function move(e:Event):void{
label.text="ok";
for(var i:int=0; i<objectList.length; i++){
objectList[i].accel(GRAVITY);
objectList[i].move();
for(var j:int=0; j<objectList.length; j++){
//if(i!=j){objectList[i].collide();}
}
}
}
}
}
import flash.display.Shape;
import flash.display.Graphics;
class SoftObject extends Shape{
public var pointList:Vector.<MaterialPoint> = new Vector.<MaterialPoint>();
public var springList:Vector.<Vector.<Spring>> = new Vector.<Vector.<Spring>>();
public var dotMass:Number = 0.1;
public var dotFrictionX:Number = 0.01;
public var dotFrictionY:Number = 0.01;
public var closeIndex:Number = 0;
public var springIndex:Number = 0;
public function SoftObject(){
springList[0] = new Vector.<Spring>();
}
public function add(map:Array):void{
for(var i:int=0; i<map.length; i++){
var point:MaterialPoint = new MaterialPoint(map[i][0],map[i][1],dotMass,dotFrictionX,dotFrictionY);
pointList.push( point );
}
for(i=1; i<pointList.length; i++){
var spring:Spring = new Spring(pointList[i-1], pointList[i]);
springList[springIndex].push( spring );
}
close();
draw();
}
public function draw():void{
with(this.graphics){
lineStyle(2,0x000000,1.0);
beginFill(0xCCFFBB,1.0);
}
for(var i:int=0; i<springList.length-1; i++){
this.graphics.moveTo(springList[i][0].point1.x,springList[i][0].point1.y);
for(var j:int =1; j<springList[i].length; j++){
this.graphics.lineTo(springList[i][j].point1.x,springList[i][j].point1.y);
}
this.graphics.endFill();
}
}
public function circle(c:int = 16,r:Number=1):void{
var a:Array = [];
for(var i:int=0; i<c; i++){
a.push([ r*Math.sin(Math.PI*2*i/c) , r*Math.cos(Math.PI*2*i/c)]);
}
add(a);
}
public function close():void{
var spring:Spring = new Spring(pointList[pointList.length-1], pointList[closeIndex]);
spring.draw(this.graphics);
springList[springIndex].push( spring );
closeIndex = pointList.length;
springIndex++;
springList[springIndex] = new Vector.<Spring>();
}
public function accel(a:Array):void{
for(var i:int=0; i<pointList.length; i++){
pointList[i].vx += a[0];
pointList[i].vy += a[1];
}
}
public function move():void{
for(var i:int=0; i<pointList.length; i++){
pointList[i].vx /= 1.0+pointList[i].fx;
pointList[i].vy /= 1.0+pointList[i].fy;
pointList[i].x += pointList[i].vx;
pointList[i].y += pointList[i].vy;
}
for(i=0; i<springList[i].length-1; i++){
for(var j:int=0; j<springList[i].length; j++){
springList[i][j].move();
}
}
this.graphics.clear();
draw();
}
public function resize(late:Number):void{
for(var i:int=0; i<springList[i].length-1; i++){
for(var j:int=0; j<springList[i].length; j++){
springList[i][j].length *= late;
}
}
}
}
class Spring{
public var point1:MaterialPoint;
public var point2:MaterialPoint;
public var length:Number;
public var k:Number = 0.01;
public function Spring(p1:MaterialPoint,p2:MaterialPoint){
point1 = p1;
point2 = p2;
length = Math.sqrt( (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) )
}
public function move():void{
var xl:Number = (point2.x - point1.x);
var yl:Number = (point2.y - point1.y);
var nl:Number = Math.sqrt( xl*xl + yl*yl );
var tx:Number = xl*(nl-length)*k / nl;
var ty:Number = yl*(nl-length)*k / nl;
point1.push(tx,ty);
point2.push(-tx,-ty);
}
public function draw(g:Graphics):void{
g.lineStyle(2,0x000000,1.0);
g.moveTo(point1.x,point1.y);
g.lineTo(point2.x,point2.y);
}
}
class MaterialPoint{
public var m:Number = 1;
public var x:Number = 0;
public var y:Number = 0;
public var vx:Number = 0;
public var vy:Number = 0;
public var fx:Number = 0.1;
public var fy:Number = 0.1;
public function MaterialPoint(x1:Number,y1:Number,mass:Number = 1,friY:Number = 1,friX:Number = 1):void{
x = x1; y = y1; m = mass;
fx = friX; fy = friY;
}
public function draw(g:Graphics):void{
g.lineStyle(2,0xFF0000,1.0);
g.beginFill(0xFFFFFF,1.0);
g.drawCircle(x,y,4);
}
public function push(fx:Number,fy:Number):void{
vx += fx/m;
vy += fy/m;
}
}