Clock (not so short coding)
not so short coding:)
pendulum clock : http://wonderfl.net/code/4617a99d63602525f710cde4de5473535293ed37
camera move: WASD
debug draw: click
/**
* Copyright yuuganisakase ( http://wonderfl.net/user/yuuganisakase )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/uxxn
*/
// not so short coding:)
// pendulum clock : http://wonderfl.net/code/4617a99d63602525f710cde4de5473535293ed37
// camera move: WASD
// debug draw: click
package
{
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.Joints.b2RevoluteJoint;
import com.actionsnippet.qbox.QuickBox2D;
import com.actionsnippet.qbox.QuickObject;
import com.bit101.components.Label;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.ui.Keyboard;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
import org.papervision3d.materials.shadematerials.PhongMaterial;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Cylinder;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.view.BasicView;
import flash.display.BitmapData;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.geom.Point;
[SWF(width=465, height=465, frameRate=20, backgroundColor=0x333333)]
public class Clock extends BasicView
{
private var boxMC:MovieClip = new MovieClip();
private var box:QuickBox2D;
private var light:PointLight3D;
private var colorMat:ColorMaterial = new ColorMaterial(0x5599dd);
private var shade:PhongMaterial;
private const Depth:int = 33;
private const CameraMove:int = 80;
private var jointArray:Array;
public function Clock():void
{
super(465, 465,false,false, "Target");
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
createPVWorld();
createBoxWorld();
removeChild(boxMC);
addEventListener(Event.ENTER_FRAME, onEnter);
stage.addEventListener(MouseEvent.CLICK, onClick);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
private function onKeyDown(e:KeyboardEvent):void
{
if (e.keyCode == 87) camera.moveForward(CameraMove);
if (e.keyCode == 83) camera.moveBackward(CameraMove);
if (e.keyCode == 65) camera.moveLeft(CameraMove);
if (e.keyCode == 68) camera.moveRight(CameraMove);
}
private function createPVWorld():void
{
camera.z = -760;
camera.y = -162;
camera.x = -110;
light = new PointLight3D();
light.copyPosition(camera);
shade = new PhongMaterial(light, 0xccbbaa, 0x776655,1);
var tar:DisplayObject3D = new DisplayObject3D();
tar.y = -70;
tar.x = 0;
tar.z = -100;
camera.target = tar;
createNumberPlate();
}
private function createNumberPlate(xx:Number =0, yy:Number=-140):void
{
var W:Number = 570;
var H:Number = 570;
var bd:BitmapData = new BitmapData(W, H, true,0x00ffffff);
var sp:flash.display.Sprite = new flash.display.Sprite();
var format:TextFormat = new TextFormat();
format.size = 64;
format.color = 0xffffff;
var i:int;
var tf:TextField;
var po:Point;
for (i = 0; i < 12; i++)
{
tf = new TextField();
tf.defaultTextFormat = format;
tf.text = (i+1).toString();
sp.graphics.beginFill(0xffffff,0.02);
sp.graphics.drawCircle(W / 2, H / 2, W / 2);
sp.addChild(tf);
po = new Point();
po = Point.polar((W*0.9) / 2, (Math.PI * 2 / 12) * i-Math.PI/2.9);
tf.x = W/2+po.x -tf.textWidth/2;
tf.y = H / 2 + po.y-tf.textHeight/2;
}
for (i = 0; i < 4; i++)
{
tf = new TextField();
tf.defaultTextFormat = format;
tf.text = ((i+1)*15).toString();
tf.scaleX = tf.scaleY = 0.3;
sp.addChild(tf);
po = new Point();
po = Point.polar((W*0.15) / 2, (Math.PI * 2 / 4) * i-Math.PI*0);
tf.x = W/2+po.x -tf.textWidth*0.3/2;
tf.y = H / 4.3 + po.y-tf.textHeight*0.3/2;
}
bd.draw(sp);
var bmMat:org.papervision3d.materials.BitmapMaterial = new org.papervision3d.materials.BitmapMaterial(bd);
bmMat.doubleSided = true;
var pl:Plane = new Plane(bmMat, W, H,2,2);
pl.z = -200;
scene.addChild(pl);
pl.x = xx;
pl.y = yy;
}
private function createBoxWorld():void
{
addChild(boxMC);
box = new QuickBox2D(boxMC,{ gravityX:0.0, gravityY:43,
iterations: 10, timeStep: 1 / 20,
bounds: [ -5, -5, 10, 10], debug:true,
simpleRender:false, renderJoints:true,
frim:true, customMouse:false } );
box.setDefault({friction:0, density:0.1});
boxMC.scaleX = boxMC.scaleY = 1.8;
boxMC.y = 88;
createClock();
box.start();
//box.mouseDrag();
}
private function createClock():void
{
var j0:QuickObject = createGear(4, 1, 10,0,-1,true, true);
var j1:QuickObject = createGearWithHand(4, 1.75, 6,-1,-2,true,"s");
var j2:QuickObject = createGear(3.55, 2.55, 7.5 ,-2,-3);
var j3:QuickObject = createGearWithHand(4, 3.4, 8,-3,-4,true,"m");
var j4:QuickObject = createGear(4.95, 3.4, 7.5 ,-4,-5);
var j5:QuickObject = createGearWithHand(4, 3.4, 8 , -5, -6,false,"h");
jointArray = [j0, j1, j2, j3, j4, j5];
var d:Date = new Date();
(j3.joint as b2RevoluteJoint).m_referenceAngle = -(d.getMinutes() * 2 * Math.PI / 60)+(Math.PI/2);
(j5.joint as b2RevoluteJoint).m_referenceAngle = -((d.getHours())*2*Math.PI/12)+(Math.PI/2);
jointGears(j0, j1, 6);
jointGears(j1, j2, 7.5);
jointGears(j2, j3, 8);
jointGears(j3, j4, 7.5);
jointGears(j4, j5, 8);
createAnchor();
}
private function jointGears(a:QuickObject, b:QuickObject, r:Number = 1):void
{
box.addJoint( {ratio:r,a:a.joint.GetBody2(), b:b.joint.GetBody2(), joint1:a.joint, joint2:b.joint, type:"gear" } );
}
private function createGear(xx:Number, yy:Number, sc:Number = 8,z1:int = 0, z2:int = -1,motor:Boolean = false, thorn:Boolean = false, addSmall:Boolean = true):QuickObject
{
var b:BoxGear = new BoxGear(box, xx, yy, sc, z1, z2, motor, thorn, addSmall);
var p:DisplayObject3D ;
if (thorn) {
p = new PVAnchor(shade,
(xx - 4) * Util.PhysScale,
( -yy + 2) * Util.PhysScale,
z1 * Depth,
Depth*0.5,
z2 * Depth,
Depth,
Util.WheelSize * Util.PhysScale,
sc);
}else {
p = new PVWheels(shade,
(xx - 4) * Util.PhysScale,
( -yy + 2) * Util.PhysScale,
z1 * Depth,
Depth*0.5,
z2 * Depth,
Depth,
Util.WheelSize * Util.PhysScale,
sc,
addSmall);
}
scene.addChild(p);
b.joint.userData = p;
return b.joint;
}
private function createGearWithHand(xx:Number, yy:Number, sc:Number = 8,z1:int = 0, z2:int = -1, addSmall:Boolean = true, hand:String = " "):QuickObject
{
var b:BoxGear = new BoxGear(box, xx, yy, sc, z1, z2, false, false, addSmall);
var p:DisplayObject3D ;
p = new PVWheels(shade,
(xx - 4) * Util.PhysScale,
( -yy + 2) * Util.PhysScale,
z1 * Depth,
Depth*0.5,
z2 * Depth,
Depth,
Util.WheelSize * Util.PhysScale,
sc,
addSmall,
hand);
scene.addChild(p);
b.joint.userData = p;
return b.joint;
}
private function createAnchor(xx:Number = 4, yy:Number = -0.9):void
{
var W:Number = 1.4;
var H:Number = 6;
var o1:QuickObject = box.addBox( { x:0, y:0, width:W, height:0.1 } );
var o2:QuickObject = box.addBox( { x:0, y:H/2, width:0.1, height:H ,maskBits:0x10} );
var o3:QuickObject = box.addBox( { x:0, y:H, width:1, height:1 , maskBits:0x10 } );
var aw:Number = Util.AnchorHandSize;
var o4:QuickObject = box.addBox( { x:-W/2, y:aw/2, width:0.2, height:aw, angle:-Util.AnchorAngle, isBullet:true} );
var o5:QuickObject = box.addBox( { x:W/2, y:aw/2, width:0.2, height:aw ,angle:Util.AnchorAngle, isBullet:true} );
var g:QuickObject = box.addGroup( { objects:[o1, o2, o3,o4,o5], x:xx, y:yy, categoryBits:0x01, maskBits:0x01 } );
var j1:QuickObject = box.addJoint( { type:"revolute", x1:xx, y1:yy, a:g.body, b:box.w.GetGroundBody() } );
var phy:Number = Util.PhysScale;
var p:PVPendulum = new PVPendulum(shade, (xx-4) * phy, (-yy+2) * phy, W * phy, H * phy, Depth);
scene.addChild(p);
j1.userData = p;
jointArray.push(j1);
g.body.ApplyImpulse(new b2Vec2(0.3, 0), new b2Vec2(xx, yy + H));
}
private function onClick(e:MouseEvent):void
{
if (boxMC.parent == this) {
removeChild(boxMC);
this.viewport.alpha = 1;
}
else {
addChild(boxMC);
this.viewport.alpha = 0;
}
}
private function onEnter(e:Event):void
{
if (boxMC.parent != this) {
singleRender();
light.copyPosition(camera);
}
for each(var jj:QuickObject in jointArray)
{
var rj:b2RevoluteJoint = (jj.joint as b2RevoluteJoint);
var angle:Number = 0;
if (rj is b2RevoluteJoint) angle = rj.GetJointAngle();
jj.userData.rotationZ = -angle * 180 / Math.PI;
if (jj.userData is PVPendulum) jj.userData.rotationZ = -jj.userData.rotationZ;
}
}
}
}
import flash.display.BitmapData;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFormat;
import org.papervision3d.core.proto.MaterialObject3D;
import org.papervision3d.materials.BitmapMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.objects.primitives.Cylinder;
import org.papervision3d.objects.DisplayObject3D;
import com.actionsnippet.qbox.QuickBox2D;
import com.actionsnippet.qbox.QuickObject;
import org.papervision3d.objects.primitives.Plane;
class BoxGear
{
public var joint:QuickObject;
public var thorn:Boolean;
private var box:QuickBox2D;
public function BoxGear(qb:QuickBox2D,
xx:Number,
yy:Number,
sc:Number = 8,
z1:int = 0,
z2:int = -1,
motor:Boolean = false,
th:Boolean = false,
addSmall:Boolean = true)
{
thorn = th;
box = qb;
var rr:Number = Util.WheelSize;
var a:QuickObject = box.addCircle( { x:xx, y:yy, radius:rr, maskBits:0x10 } );
var b:QuickObject = box.addCircle( { x:xx, y:yy, radius:rr*sc , maskBits:0x10} );
var p:QuickObject = box.addCircle( { x:xx, y:yy, radius:0.01, density:0 , maskBits:0x10} );
var j0:QuickObject = box.addJoint( { a:p.body, b:b.body, type:"revolute" , enableMotor:motor, maxMotorTorque:1, motorSpeed:-1.5 } );
var j1:QuickObject = box.addJoint( { a:p.body, b:a.body, type:"revolute" } );
jointGears(j0, j1,-1);
var PhysScale:Number = Util.PhysScale;
var w:DisplayObject3D;
if (thorn)
{
var rad:Number = rr * sc;
var hands:Array = new Array();
for (var i:int = 0; i < Util.ThornNum; i++)
{
var angle:Number = (360 / (Util.ThornNum)) * i * (Math.PI / 180) ;
var plusRadius:Number = rad + Util.ThornHeight / 4;
var o:QuickObject = box.addBox( {isBullet:true, x:plusRadius * Math.cos(angle), y:plusRadius * Math.sin(angle), angle:angle+Math.PI/2+Util.ThornAngle, width:Util.ThornWidth, height:Util.ThornHeight , categoryBits:0x01, maskBits:0x01} );
hands.push(o);
}
var g:QuickObject = box.addGroup( { objects:hands, x:xx, y:yy, categoryBits:0x01, maskBits:0x01 } );
var j2:QuickObject = box.addJoint( { a:p.body, b:g.body, type:"revolute" } );
jointGears(j0, j2, -1);
}
joint = j0;
}
private function jointGears(a:QuickObject, b:QuickObject, r:Number = 1):void
{
box.addJoint( {ratio:r,a:a.joint.GetBody2(), b:b.joint.GetBody2(), joint1:a.joint, joint2:b.joint, type:"gear" } );
}
}
class PVPendulum extends DisplayObject3D
{
private var mm:MaterialObject3D;
private var mList:MaterialsList;
public function PVPendulum(mat:MaterialObject3D, xx:Number, yy:Number, ww:Number, hh:Number,dd:Number)
{
mm = mat;
mList = new MaterialsList( { all:mm } );
this.x = xx;
this.y = yy;
var c1:Cube = new Cube(mList, ww, 60, 10);
c1.z = 20;
var c2:Cube = new Cube(mList, 10, 10, hh);
c2.y = -hh / 2;
c2.z = 40;
var c3:Cube = new Cube(mList, 70, 70, 70);
c3.y = -hh;
c3.z = 40;
var s:Number = Util.AnchorHandSize * Util.PhysScale;
var c4:Cube = new Cube(mList, 20, 20, s);
c4.x = ww / 2.1;
c4.y = -s / 2;
c4.z = 0;
var aa:Number = Util.AnchorAngle*180/Math.PI
c4.rotationZ = -aa;
var c5:Cube = new Cube(mList, 20, 20, s);
c5.x = -ww / 2.1;
c5.y = -s / 2;
c5.rotationZ = aa;
c5.z = 0;
var ar:Array = [c1, c2, c3, c4, c5];
for each(var c:Cube in ar)
{
this.addChild(c);
}
}
}
class PVAnchor extends DisplayObject3D
{
public function PVAnchor(mat:MaterialObject3D,
xx:Number,
yy:Number,
z1:Number,
depth1:Number,
z2:Number ,
depth2:Number,
rad1:Number,
sc:Number
)
{
this.x = xx;
this.y = yy;
var g1:PVGear = new PVGear(mat, 0, 0, z1, 0 , rad1 * sc, depth1);
this.addChild(g1);
var g2:PVGear = new PVGear(mat, 0, 0, z2, 10,rad1, depth2);
this.addChild(g2);
}
}
class PVWheels extends DisplayObject3D
{
public function PVWheels(mat:MaterialObject3D,
xx:Number,
yy:Number,
z1:Number,
depth1:Number,
z2:Number ,
depth2:Number,
rad1:Number,
sc:Number,
addSmall:Boolean = true,
addHand:String = " ")
{
this.x = xx;
this.y = yy;
var g1:PVGear = new PVGear(mat, 0, 0, z1, 10*sc,rad1*sc, depth1);
this.addChild(g1);
if (addSmall)
{
var g2:PVGear = new PVGear(mat, 0, 0, z2+10, 10,rad1, depth2);
this.addChild(g2);
}
var ww:Number;
var hh:Number;
var dd:Number;
var handW:Number;
if (addHand=="s")
{
ww = 6;
hh = 6;
dd = 170;
handW = 60;
}else if (addHand == "m") {
ww = 6;
hh = 10;
dd = 120;
handW = 260;
}else if (addHand == "h") {
ww = 6;
hh = 12;
dd = 80;
handW = 140;
}
if (addHand != " ") {
var c1:Cube = new Cube(new MaterialsList( { all:mat } ), ww, dd, hh);
c1.z = z1-dd/2;
var c2:Cube = new Cube(new MaterialsList( { all:mat } ), handW, ww, hh);
c2.x = handW / 2;
c2.z = z1-dd;
addChild(c1);
addChild(c2);
}
}
}
class PVGear extends DisplayObject3D
{
private var mm:MaterialObject3D;
public function PVGear(mat:MaterialObject3D,xx:Number, yy:Number, zz:Number,teeth:int, rad:Number, hei:Number)
{
mm = mat;
this.x = xx;
this.y = yy;
this.z = zz;
addCylinder(rad, hei);
addTeeth(teeth, rad, hei);
}
private function addTeeth(num:int, r:Number, dd:Number):void
{
var ww:Number=3;
var hh:Number = 6;
var i:int = 0;
var angle:Number;
var b:Cube;
var loc:Point;
if (num > 0)
{
for (i = 0; i < num; i++)
{
angle = (Math.PI * 2 / num) * i;
b = new Cube(new MaterialsList({all:mm}), ww, dd, hh);
loc = Point.polar(r+hh/3, angle);
b.x = loc.x;
b.y = loc.y;
b.rotationZ = (angle*180/Math.PI)+90;
this.addChild(b);
}
}else {
for (i = 0; i < Util.ThornNum; i++)
{
angle = (Math.PI * 2 / Util.ThornNum) * i;
b = new Cube(new MaterialsList({all:mm}), Util.ThornWidth*Util.PhysScale, dd, Util.ThornHeight*Util.PhysScale);
loc = Point.polar(r+Util.ThornHeight*Util.PhysScale/4, angle);
b.x = loc.x;
b.y = loc.y;
b.rotationZ = (angle*180/Math.PI)+90-(Util.ThornAngle*180/Math.PI);
this.addChild(b);
}
}
}
private function createThorn():void
{
}
private function addCylinder(rad:Number, hei:Number):void
{
var cy:Cylinder = new Cylinder(mm, rad, hei,16,2);
cy.rotationX = 90;
this.addChild(cy);
}
}
class Util
{
public static const ThornAngle:Number = Math.PI / 6;
public static const ThornNum:int = 5;
public static const WheelSize:Number = 0.1;
public static const ThornWidth:Number = WheelSize * 1.5;
public static const ThornHeight:Number = WheelSize * 5;
public static const PhysScale:Number = 100;
public static const AnchorHandSize:Number = 0.7;
public static const AnchorAngle:Number = 0.4;
}