すらいむの実装

今回はすらいむ作ってみました。かわいいです。

とりあえず構造

これは周りに40個の円を配置させてそれをjointで結んでいます。
そしてこのままでは潰れてしまうので対角線上に伸縮性のあるjointを引いています。

こんな感じ http://about-hiroppy.com/flash/work/slime/

そーす

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	import Box2D.Collision.Shapes.b2PolygonShape;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2DebugDraw;
	import Box2D.Dynamics.b2World;
	import Box2D.Dynamics.Joints.b2DistanceJointDef;
	import Box2D.Dynamics.Joints.b2RevoluteJoint;
	import Box2D.Dynamics.Joints.b2RevoluteJointDef;
	
	[SWF(width="500",height="500",backgroundColor="0xfffacd")]
//	[SWF(width="500",height="500",backgroundColor="0")] //debug
	
	public class slime extends Sprite
	{
		private var world:b2World;
		private const gravity:b2Vec2 = new b2Vec2(0,9.8);
		private var wall:b2PolygonShape= new b2PolygonShape();
		private var wallDf:b2BodyDef = new b2BodyDef();
		private var wallB:b2Body;
		private var circles:Vector.<b2Body> = new Vector.<b2Body>;
		private var N:int = 40;
		private var slime:Sprite = new Sprite();
		private var slime_eye_left:Sprite = new Sprite();
		private var slime_eye_right:Sprite = new Sprite();
		private var slime_eye_left_white:Sprite = new Sprite();
		private var slime_eye_right_white:Sprite = new Sprite();
		private var canvas:Sprite = new Sprite();
		
		public function slime()
		{
			
			//background mater
			var meter_line:Sprite = new Sprite();
			meter_line.graphics.lineStyle(3,0);
			meter_line.graphics.moveTo(50,500);
			meter_line.graphics.lineTo(50,0);
			stage.addChild(meter_line);
			//separated 100
			for(var i:int=400;i >0;i-=100){
				var meter_stop:Sprite = new Sprite();
				meter_stop.graphics.lineStyle(2,0);
				meter_stop.graphics.moveTo(50,i);
				meter_stop.graphics.lineTo(80,i);
				stage.addChild(meter_stop);
			}
			var meter_string:Array = new Array("100","200","300","400");
			for(i=0;i<meter_string.length;i++){
				var tf:TextField = new TextField();
				tf.autoSize = TextFieldAutoSize.LEFT;
				tf.defaultTextFormat = new TextFormat("ahahahahahaha.warota",20);
				tf.text = meter_string[i];
				tf.x = 85;
				tf.y = 400 - i*100;
				stage.addChild(tf);
			}
			
			//描画Layer
			stage.addChild(canvas);
			
			// The physical world
			world = new b2World(gravity,true);
			
			//walls
			// Left
			wallDf.position.Set( -95 / 30, stage.stageHeight / 30 /2.5);
			wall.SetAsBox(100/30, stage.stageHeight/30);
			wallB = world.CreateBody(wallDf);
			wallB.CreateFixture2(wall);
			// Right
			wallDf.position.Set((stage.stageWidth + 95) / 30, stage.stageHeight / 30 / 2);
			wallB = world.CreateBody(wallDf);
			wallB.CreateFixture2(wall);

			// Bottom
			wallDf.position.Set(stage.stageWidth / 30 / 2, (stage.stageHeight + 101) / 30);
			wall.SetAsBox(stage.stageWidth/30, 100/30);
			wallB = world.CreateBody(wallDf);
			wallB.CreateFixture2(wall);
			
			//angle
			var rot:int = 0;
			
			//circles and joints
			for(i=0;i<N;i++){
				var c:Circle = new Circle(world,1,0.7,0.8);
				var c_2:b2Body = c.Circle_2((100*Math.cos(rot*Math.PI/180)+220),(100*Math.sin(rot*Math.PI/180)+220));
				circles.push(c_2);
				if(i == 39) joint(circles[0],circles[i]);
				if(i != 0) joint(circles[i-1],circles[i]);
				rot += 9;
			}
			for(i=0;i<20;i++){
				joint_center(circles[i],circles[i+20]);
			}
			
//			//bebug mode
//			var debug:b2DebugDraw = new b2DebugDraw();
//			debug.SetSprite(this);
//			debug.SetDrawScale(30.0);
//			debug.SetFillAlpha(0.3);
//			debug.SetLineThickness(1.0);
//			debug.SetLineThickness(2);
//			debug.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
//			world.SetDebugDraw(debug);
//			world.DrawDebugData();
			
			addEventListener(Event.ENTER_FRAME,onEnterFrame);
		}
		
		private function joint(from:b2Body,to:b2Body):void{
			var jointDef:b2DistanceJointDef = new b2DistanceJointDef();
			jointDef.Initialize(from,to,from.GetWorldCenter(),to.GetWorldCenter());
			jointDef.collideConnected = false;    
			jointDef.frequencyHz  = 0;            
			jointDef.dampingRatio = 1;            
//			jointDef.length = 2.0;                
			jointDef.collideConnected = false;
			world.CreateJoint(jointDef);
			//			var frontJoint:b2RevoluteJoint = b2RevoluteJoint(world.CreateJoint(jointDef));
		}
		private function joint_center(from:b2Body,to:b2Body):void{
			var jointDef:b2DistanceJointDef = new b2DistanceJointDef();
			jointDef.Initialize(from,to,from.GetWorldCenter(),to.GetWorldCenter());
			jointDef.collideConnected = false; 
			jointDef.frequencyHz  = 1000;            
			jointDef.dampingRatio = 1;           
//			jointDef.length = 5.0;               
			jointDef.collideConnected = false;
			world.CreateJoint(jointDef);
		}
		
		private function onEnterFrame(e:Event):void{
			var top_position:Number=501; //y軸の最小値(描画では最大値)
			var bottom_position:Number = 0; //y軸の最大値
			var right_position:Number = 0; //x軸の最大値
			var left_position:Number = 501; //x軸の最小値
			
			//all check
			for(i=0;i<circles.length;i++){
				top_position = Math.min(top_position,circles[i].GetPosition().y*30);
				bottom_position = Math.max(bottom_position,circles[i].GetPosition().y*30);
				right_position = Math.max(right_position,circles[i].GetPosition().x*30);
				left_position = Math.min(left_position,circles[i].GetPosition().x*30);
			}
			
			//右目の座標
			var r_yy:Number = Math.abs(bottom_position-top_position)/2.5+top_position;
			var r_xx:Number = Math.abs(right_position-left_position)/1.5+left_position;
			//左目の座標
			var l_yy:Number = Math.abs(bottom_position-top_position)/2.5+top_position;
			var l_xx:Number = Math.abs(right_position-left_position)/2.5+left_position;
			
			//drawing
			slime.graphics.clear();
			slime_eye_left.graphics.clear();
			slime_eye_right.graphics.clear();
			slime_eye_left_white.graphics.clear();
			slime_eye_right_white.graphics.clear();
			
			//body
//			slime.graphics.lineStyle(3,0x22ff22);
			slime.graphics.beginFill(0x00ffff,0.5);
			
			slime.graphics.moveTo(circles[0].GetPosition().x*30,circles[0].GetPosition().y*30);
			for(var i:int = 1;i<40;i++){
				slime.graphics.lineTo(circles[i].GetPosition().x*30,circles[i].GetPosition().y*30);
			}
			slime.graphics.lineTo(circles[0].GetPosition().x*30,circles[0].GetPosition().y*30);
			
			graphics.endFill();
			canvas.addChild(slime);
			
			//right_eye
			slime_eye_right.graphics.beginFill(0,0.7);
			slime_eye_right.graphics.drawCircle(r_xx,r_yy,15); 
			slime_eye_right.graphics.endFill();
			canvas.addChild(slime_eye_right);
			
			//left_eye
			slime_eye_left.graphics.beginFill(0,0.7);
			slime_eye_left.graphics.drawCircle(l_xx,l_yy,15); 
			slime_eye_left.graphics.endFill();
			canvas.addChild(slime_eye_left);
			
			//white eyes
			//right
			slime_eye_right_white.graphics.beginFill(0xffffff,0.8);
			slime_eye_right_white.graphics.drawCircle(r_xx,r_yy,4);
			slime_eye_right_white.graphics.endFill();
			slime_eye_right.addChild(slime_eye_right_white);
			
			//left
			slime_eye_left_white.graphics.beginFill(0xffffff,0.8);
			slime_eye_left_white.graphics.drawCircle(l_xx,l_yy,4);
			slime_eye_left_white.graphics.endFill();
			slime_eye_left.addChild(slime_eye_left_white);
			
			world.Step(1/30, 10 ,20);
			world.ClearForces();
			world.DrawDebugData();
		}
	}
}


import flash.display.BlendMode;
import flash.display.Sprite;
import flash.filters.GlowFilter;


import Box2D.Collision.Shapes.b2CircleShape;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2FixtureDef;
import Box2D.Dynamics.b2World;


class Circle extends Sprite{
	
	private var bodyDef:b2BodyDef = new b2BodyDef();
	private var body:b2Body;
	private var fixtureDef:b2FixtureDef = new b2FixtureDef();
	private var circleDef:b2CircleShape = new b2CircleShape();
	private var world:b2World;
	
	public function Circle(W:b2World,den:Number,fri:Number,res:Number):void{
		this.world = W;
		fixtureDef.shape = circleDef;
		fixtureDef.density = den; 
		fixtureDef.friction = fri; 
		fixtureDef.restitution = res; 
	}
	
	public function Circle_2(position_x:Number,position_y:Number):b2Body{
		var r:Number = 1; 
		var color:uint = 0x00ffff; 
		bodyDef.type = b2Body.b2_dynamicBody;  
		add(r,position_x,position_y);
		return body;
	}
	
	
	public function Circle_5(position_x:Number,position_y:Number,r:Number,color:uint,type:Boolean):b2Body{
		if(type) bodyDef.type = b2Body.b2_dynamicBody;
		else bodyDef.type = b2Body.b2_staticBody;
		draw(r,color);
		add(r,position_x,position_y);
		return body;
	}
	
	private function draw(r:Number,color:uint):void{
		bodyDef.userData = new Sprite();
		bodyDef.userData.graphics.lineStyle(3,0xffffff);
		bodyDef.userData.graphics.drawCircle(0,0,r);
		filters = [new GlowFilter(color,1,18,18,6,2)];
		blendMode = BlendMode.ADD; 
		addChild(bodyDef.userData);
	}
	private function add(r:Number,position_x:Number,position_y:Number):void{
		circleDef.SetRadius(r/30);
		bodyDef.position.Set(position_x/30,position_y/30);
		body = world.CreateBody(bodyDef);
		body.CreateFixture(fixtureDef);
	}
}