flash on 2010-4-11

by shohei909
柔らかい物体を作る
♥0 | Line 172 | Modified 2010-04-12 23:18:05 | MIT License
play

ActionScript3 source code

/**
 * 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;
	}
}