puyo line 3d
PuyoDot3 -> 3D
press any key to start/stop dropping lines
drag to rotate
/**
* Copyright zob ( http://wonderfl.net/user/zob )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/jsyP
*/
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import flash.events.MouseEvent;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.events.KeyboardEvent;
import flash.utils.*;
[SWF(width=465,height=465,backgroundColor=0xFFFFFF,frameRate=60)]
public class barebone extends Sprite {
private var matrix:Matrix3D = new Matrix3D();
private var drag:Boolean = false;
private var start_m:Vector3D = new Vector3D();
private var old_mouse:Vector3D = new Vector3D();
private var new_mouse:Vector3D = new Vector3D();
private var joints:Vector.<Joint> = new Vector.<Joint>();
private var bmpd:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xFFFFFF);
private var center:Point = new Point(stage.stageWidth/2, stage.stageHeight/2);
private var ground:Vector.<Vector3D> = new Vector.<Vector3D>();
private var start:Boolean = false;
public function barebone() {
ground.push(new Vector3D(-200, 100, -200));
ground.push(new Vector3D(-200, 100, 200));
ground.push(new Vector3D(200, 100, 200));
ground.push(new Vector3D(200, 100, -200));
stage.addEventListener(MouseEvent.MOUSE_DOWN, onmouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onmouseUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onmouseMove);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onkeyDown);
addEventListener(Event.ENTER_FRAME, processing);
}
private function processing(e:Event):void
{
interaction();
update();
paint();
}
private function interaction():void
{
if(start)
{
var vlen:Number = 0;
if(joints.length>0)
{
var vx:Number = (mouseX-center.x) - joints[joints.length-1].x;
var vy:Number = (-450) - joints[joints.length-1].y;
var vz:Number = -(mouseY-center.y) - joints[joints.length-1].z;
vlen = Math.sqrt(vx*vx+vy*vy+vz*vz);
}
if(vlen > 10 || joints.length == 0)
{
joints.push(new Joint((mouseX-center.x), -450, -(mouseY-center.y)));
var currentMaxLength:int = joints.length;
if(currentMaxLength>1)
{
joints[currentMaxLength-2].addConstraint(joints[currentMaxLength-1]);
}
if(joints.length>300)
{
joints.splice(0,1);
}
}
}
}
private function update():void
{
var j:Joint;
for each(j in joints) j.updateRForce();
for each(j in joints) j.updateForce();
for each(j in joints) j.move();
}
private function paint():void
{
graphics.clear();
var i:int = 0;
var j:int = 0;
var tv1:Vector3D = new Vector3D();
var tv2:Vector3D = new Vector3D();
var tp1:Point = new Point();
var tp2:Point = new Point();
var ratio:Number = 0;
var focalLength:Number = 500;
for(i = 0; i < ground.length; i++)
{
graphics.lineStyle(0.1, 0xFF << i * 8);
j = (i+1) % ground.length;
tv1 = matrix.transformVector(ground[i]);
ratio = focalLength/(focalLength + tv1.z);
tp1.x = tv1.x * ratio + center.x;
tp1.y = tv1.y * ratio + center.y;
tv2 = matrix.transformVector(ground[j]);
ratio = focalLength/(focalLength + tv2.z);
tp2.x = tv2.x * ratio + center.x;
tp2.y = tv2.y * ratio + center.y;
graphics.moveTo(tp1.x, tp1.y);
graphics.lineTo(tp2.x, tp2.y);
}
var k:int = 0;
var c:Constraint;
for(i = 0; i < joints.length; i++)
{
graphics.lineStyle(0.1, 0xFF << i * 8);
j = (i+1);
tv1 = matrix.transformVector(joints[i]);
ratio = focalLength/(focalLength + tv1.z);
tp1.x = tv1.x * ratio + center.x;
tp1.y = tv1.y * ratio + center.y;
if(joints[i].constraints.length > 0)
for(k = 0; k < joints[i].constraints.length; k++)
{
c = joints[i].constraints[k];
tv2 = matrix.transformVector(c.to);
ratio = focalLength/(focalLength + tv2.z);
tp2.x = tv2.x * ratio + center.x;
tp2.y = tv2.y * ratio + center.y;
graphics.moveTo(tp1.x, tp1.y);
graphics.lineTo(tp2.x, tp2.y);
}
}
}
private function onkeyDown(e:KeyboardEvent):void
{
start = !start;
if(start)
{
joints.splice(0, joints.length);
}
}
private function onmouseDown(e:MouseEvent):void
{
drag = true;
old_mouse.x = mouseX;
old_mouse.y = mouseY;
}
private function onmouseUp(e:MouseEvent):void
{
drag = false;
}
private function onmouseMove(e:MouseEvent):void
{
new_mouse.x = mouseX;
new_mouse.y = mouseY;
if(drag)
{
var difference:Vector3D = new Vector3D(new_mouse.x - old_mouse.x, new_mouse.y - old_mouse.y);
var vector:Vector3D = new Vector3D(difference.x, difference.y, 0);
var rotationAxis:Vector3D = vector.crossProduct(new Vector3D(0,0,1));
rotationAxis.normalize();
var distance:Number = Math.sqrt(difference.x * difference.x + difference.y * difference.y);
var rotationMatrix:Matrix3D = new Matrix3D();
rotationMatrix.appendRotation(distance/150*180/Math.PI, rotationAxis);
matrix.append(rotationMatrix);
}
old_mouse.x = mouseX;
old_mouse.y = mouseY;
}
}
}
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
class Joint extends Vector3D
{
private var vertices:Vector.<int> = new Vector.<int>();
private var angles:Matrix3D = new Matrix3D();
private var vr:Matrix3D = new Matrix3D();
public var constraints:Vector.<Constraint> = new Vector.<Constraint>();
public var fixed:Boolean = false;
public var locked:Boolean = false;
public var a:Vector3D = new Vector3D();
public var vt:Vector3D = new Vector3D();
public function Joint(px:Number = 0, py:Number = 0, pz:Number = 0)
{
super(px, py, pz);
}
public function checkConnection(v:Joint):void
{
if(!locked && v.locked && Vector3D.distance(Vector3D(this), v) < GB._DISTANCE)
{
addConstraint(v, GB._DISTANCE);
locked = true;
}
}
public function addConstraint(v:Joint, d:Number = -1):void
{
constraints.push(new Constraint(this, v, d));
}
public function has(v:Joint):Boolean
{
for each(var c:Constraint in constraints) if(c.to == v) return true;
return false;
}
public function updateConnectRForce(c:Constraint):void
{
connectRForce(this, c.to, c.vTo);
connectRForce(c.to, this, c.vFrom);
}
public function connectRForce(aj:Joint, bj:Joint, cv:Vector3D):void
{
var CURR_VECTOR:Vector3D = bj.subtract(Vector3D(aj));
var NEW_VECTOR:Vector3D = aj.angles.transformVector(cv);
var degree:Number = Vector3D.angleBetween(NEW_VECTOR, CURR_VECTOR);
if(isNaN(degree)) degree = 0;
var right:Vector3D = NEW_VECTOR.crossProduct(CURR_VECTOR);
right.normalize();
var matrix:Matrix3D = new Matrix3D();
matrix.identity();
matrix.appendRotation(degree/Math.PI*180, right);
aj.vr.append(Matrix3D.interpolate(GB._originMATRIX, matrix, GB._ROTATION_RATE));
}
public function updateConnectForce(c:Constraint):void
{
connectForce(this, c.to, c.vTo);
connectForce(c.to, this, c.vFrom);
}
public function connectForce(aj:Joint, bj:Joint, cv:Vector3D):void
{
var v:Vector3D = aj.angles.transformVector(cv);
var toVector:Vector3D = aj.add(v);
var ax:Number = (bj.x - toVector.x) * GB._VERTICAL_RATE;
var ay:Number = (bj.y - toVector.y) * GB._VERTICAL_RATE;
var az:Number = (bj.z - toVector.z) * GB._VERTICAL_RATE;
aj.a.x += ax;
aj.a.y += ay;
aj.a.z += az;
bj.a.x -= ax;
bj.a.y -= ay;
bj.a.z -= az;
}
public function move():void
{
a.x += -GB._FRICTION * vt.x;
a.y += -GB._FRICTION * vt.y;
a.z += -GB._FRICTION * vt.z;
vt.x += a.x;
vt.y += a.y;
vt.z += a.z;
x += vt.x;
y += vt.y;
z += vt.z;
a.x = 0;
a.y = 0;
a.z = 0;
if (GB._GROUND_LINE < y){
y = GB._GROUND_LINE;
vt.y *= -0.8;
if (vt.y < -50) vt.y = -50;
vt.x *= GB._GROUND_FRICTION;
vt.z *= GB._GROUND_FRICTION;
}
}
public function updateRForce():void
{
for each(var cR:Constraint in constraints)
{
updateConnectRForce(cR);
}
vr = Matrix3D.interpolate(GB._originMATRIX, vr, GB._ROTATE_FRICTION);
angles.append(vr);
}
public function updateForce():void
{
for each(var c:Constraint in constraints)
{
updateConnectForce(c);
}
a.y += GB._GRAVITY;
}
}
class Constraint
{
public var to:Joint;
public var vTo:Vector3D;
public var vFrom:Vector3D;
public function Constraint(J:Joint, v:Joint, d:Number = -1)
{
to = v;
vTo = to.subtract(Vector3D(J));
vFrom = J.subtract(Vector3D(to));
if(d>=0)
{
vTo.normalize();
vTo.scaleBy(d);
vFrom.normalize();
vFrom.scaleBy(d);
}
}
}
class GB
{
public static const _DISTANCE :Number = 30;
public static const _LIMIT_DISTANCE :Number = 50;
public static const _WALL_LEFT :Number = 0;
public static const _WALL_RIGHT :Number = 465;
public static const _GROUND_LINE :Number = 100;
public static const _DOT_CONNECT_MAX :int = 4;
public static const _DERIVATION :int = 3;
public static const _MAP_SIZE :Number = 400;
public static const _PI :Number = Math.PI;
public static const _PI2 :Number = 2.0 * _PI;
public static const _RADIAN90 :Number = _PI * 0.5;
public static const _RADIAN180 :Number = _PI * 1.0;
public static const _RADIAN270 :Number = _PI * -0.5;
public static const _RADIAN360 :Number = _PI * 2;
public static const _TO_DEGREE :Number = 180 / _PI;
public static const _COMP :Number = 0.0133; //0.1
public static const _GRAVITY :Number = 0.6 / _DERIVATION;
public static const _ROTATION_RATE :Number = 0.05 / _DERIVATION;
public static const _VERTICAL_RATE :Number = 0.2 / _DERIVATION;
public static const _MOUSE_PULL_RATE :Number = 2.0 / _DERIVATION;
public static const _FRICTION :Number = 0.1 / _DERIVATION;
public static const _ROTATE_FRICTION :Number = 1 - 0.2 / _DERIVATION;
public static const _MOUSE_ROTATE_FRICTION :Number = 1 - 0.8 / _DERIVATION;
public static const _MOUSE_MOVE_FRICTION :Number = 1 - 0.5 / _DERIVATION;
public static const _GROUND_FRICTION :Number = 1 - 0.5 / _DERIVATION;
public static const _originMATRIX :Matrix3D = new Matrix3D();
public function GB()
{
}
}