TheoJansen's mad monster
UP: regenerate monster
DOWN: walk on/off
LEFT: add legs
RIGHT: change color
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/oPek
*/
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.*;
import flash.ui.*;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.trace.Trace;
[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;
private var level:int = 3;
private var drawMode:int = 0;
private var console:TextField = new TextField();
public function barebone() {
var tf:TextFormat = new TextFormat("Arial", 10, 0x666666);
console.defaultTextFormat = tf;
addChild(console);
console.text = "leg = 6; color = 0; walk = off;";
console.x = console.y = 5; console.autoSize = "left";
spawnMonster();
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 spawnMonster():void
{
joints.splice(0, joints.length);
var i:int = 0;
var k:int = 0;
var stack:int = 0;
var ajustmentX:Number = 0;
var ajustmentY:Number = 500;
for(i = 0; i < level; i++)
{
for(k = 0; k < 2; k++)
{
stack = k*50;
///////////////////////////////////////////
joints.push(new Joint( -60+ajustmentX, -620+ajustmentY, (i*50)-stack)); // 0
joints.push(new Joint(-110+ajustmentX, -570+ajustmentY, (i*50)-stack)); // 1
joints.push(new Joint( -60+ajustmentX, -570+ajustmentY, (i*50)-stack)); // 2
joints.push(new Joint(-110+ajustmentX, -520+ajustmentY, (i*50)-stack)); // 3
joints.push(new Joint( -60+ajustmentX, -520+ajustmentY, (i*50)-stack)); // 4
joints.push(new Joint( -60+ajustmentX, -440+ajustmentY, (i*50)-stack)); // 5
///////////////////////////////////////////
joints.push(new Joint( 60+ajustmentX, -620+ajustmentY, (i*50)-stack)); // 6
joints.push(new Joint( 60+ajustmentX, -570+ajustmentY, (i*50)-stack)); // 7
joints.push(new Joint( 110+ajustmentX, -570+ajustmentY, (i*50)-stack)); // 8
joints.push(new Joint( 60+ajustmentX, -520+ajustmentY, (i*50)-stack)); // 9
joints.push(new Joint( 110+ajustmentX, -520+ajustmentY, (i*50)-stack)); //10
joints.push(new Joint( 60+ajustmentX, -440+ajustmentY, (i*50)-stack)); //11
///////////////////////////////////////////
joints.push(new Joint( 0+ajustmentX, -580+ajustmentY, (i*50)-stack)); //12
}
}
for(i = 0; i < level-1; i++)
{
joints[15+(i+1)*26] = joints[2+i*26];
joints[20+(i+1)*26] = joints[7+i*26];
}
for(i = 0; i < level*2; i++)
{
stack = i*13;
joints[ 0+stack].addConstraint(joints[ 1+stack]);
joints[ 0+stack].addConstraint(joints[ 2+stack]);
joints[ 0+stack].addConstraint(joints[12+stack], 90);
joints[ 1+stack].addConstraint(joints[ 2+stack]);
joints[ 1+stack].addConstraint(joints[ 3+stack]);
joints[ 2+stack].addConstraint(joints[ 7+stack]);
joints[ 3+stack].addConstraint(joints[ 4+stack]);
joints[ 3+stack].addConstraint(joints[ 5+stack]);
joints[ 4+stack].addConstraint(joints[ 2+stack]);
joints[ 4+stack].addConstraint(joints[ 5+stack]);
joints[ 4+stack].addConstraint(joints[12+stack], 90);
joints[ 6+stack].addConstraint(joints[ 7+stack]);
joints[ 6+stack].addConstraint(joints[ 8+stack]);
joints[ 6+stack].addConstraint(joints[12+stack], 90);
joints[ 8+stack].addConstraint(joints[ 7+stack]);
joints[ 8+stack].addConstraint(joints[10+stack]);
joints[ 9+stack].addConstraint(joints[ 7+stack]);
joints[ 9+stack].addConstraint(joints[10+stack]);
joints[ 9+stack].addConstraint(joints[11+stack]);
joints[ 9+stack].addConstraint(joints[12+stack], 90);
joints[10+stack].addConstraint(joints[11+stack]);
}
for(i = 0; i < level; i++)
{
for(k = 0; k < 13; k++)
{
joints[i*26+k].addConstraint(joints[i*26+k+13]);
}
}
}
private function processing(e:Event):void
{
update();
monsterwalk();
paint();
}
private function monsterwalk():void
{
if(start)
{
var i:int = 0;
var centraAxis:Vector3D;
for(i = 0; i < level; i++)
{
var centraA:Vector3D = joints[ 7+i*26].subtract(joints[ 2+i*26]);
centraA.scaleBy(0.5);
centraA = centraA.add(joints[ 2+i*26]);
var centraB:Vector3D = joints[20+i*26].subtract(joints[15+i*26]);
centraB.scaleBy(0.5);
centraB = centraB.add(joints[15+i*26]);
if(i == 0)
{
centraAxis = centraB.subtract(centraA);
centraAxis.normalize();
}
var rotateMatrix:Matrix3D = new Matrix3D();
rotateMatrix.appendRotation(-(getTimer()/4+i*120), centraAxis);
var vector:Vector3D = rotateMatrix.transformVector(new Vector3D(0, 35,0));
joints[12+i*26].copy(centraA);
joints[25+i*26].copy(centraB);
joints[12+i*26].copy(joints[12+i*26].add(vector));
joints[25+i*26].copy(joints[25+i*26].add(vector));
}
}
}
private function interaction():void
{
}
private function update():void
{
var i:int = 0;
var j:Joint;
var k:int = 0;
for(k = 0; k < 10; k++)
{
for each(j in joints) j.updateRForce();
for each(j in joints) j.updateForce();
for(i = 0; i < joints.length; i++)
{
//if(start || i != Math.floor(i/13)*13+7 )// && i != 2 && i != 7 && i != 15 && i != 20)
joints[i].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++)
{
//
switch(drawMode)
{
case 0:
graphics.lineStyle(0.1, (int(i/26)%level==0)? 0x666666: 0xDDDDDD);
break;
case 1:
graphics.lineStyle(0.1, 0xFF << int(i/26) * 8);
break;
case 2:
graphics.lineStyle(0.1, (int(i/26)%2==0)? 0x666666: 0xDDDDDD);
break;
case 3:
graphics.lineStyle(0.1, (int(i/26)%2==0)? 0xDDDDDD: 0x666666);
break;
}
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
{
switch(e.keyCode)
{
case Keyboard.UP:
spawnMonster();
break;
case Keyboard.LEFT:
if(++level>5) level = 3;
spawnMonster();
start = false;
break;
case Keyboard.RIGHT:
if(++drawMode>3) drawMode = 0;
break;
case Keyboard.DOWN:
start = !start;
break;
}
console.text = "";
console.appendText("leg = "+(level*2)+"; ");
console.appendText("color = "+(drawMode)+"; ");
console.appendText("walk = "+((start)?"on":"off")+"; ");
}
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();
//temp
public var verts:Vector.<Vector3D> = new Vector.<Vector3D>();
public var vert:Vector3D = new Vector3D();
public function Joint(px:Number = 0, py:Number = 0, pz:Number = 0)
{
super(px, py, pz);
}
public function copy(v:Vector3D):void
{
x = v.x; y = v.y; z = v.z;
}
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
{
if(!has(v))
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, c.distance);
connectForce(c.to, this, c.vFrom, c.distance);
}
public function connectForce(aj:Joint, bj:Joint, cv:Vector3D, d:Number):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.x = 0;
vt.z = 0;
/**/
vt.y *= -0.1;
if (vt.y < -50) vt.y = -50;
/*
vt.x *= -GB._GROUND_FRICTION;
vt.z *= -GB._GROUND_FRICTION;
/**/
}
/**/
vert = angles.transformVector(new Vector3D(1,0,0));
vert.scaleBy(20);
}
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 var distance:Number = 0;
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)
{
distance = d;
vTo.normalize();
vTo.scaleBy(d);
vFrom.normalize();
vFrom.scaleBy(d);
} else distance = Vector3D.distance(to, J);
}
}
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 = 4; // 計算の分割数。 //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;
////v0.2
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.3 / _DERIVATION; //0.3 //0.6
public static const _ROTATION_RATE :Number = 0.05 / _DERIVATION; // 自身バネ(根元) //0.05
public static const _VERTICAL_RATE :Number = 0.2 / _DERIVATION; // ターゲットバネ(さきっぽ) //0.2 //0.133
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.99 / _DERIVATION; // 1 - 0.2
public static const _originMATRIX :Matrix3D = new Matrix3D();
public function GB()
{
}
}