forked from: Clock (not so short coding)

by chez_sugi forked from Clock (not so short coding) (diff: 1)
not so short coding:)
pendulum clock : http://wonderfl.net/code/4617a99d63602525f710cde4de5473535293ed37
camera move: WASD
debug draw: click
♥0 | Line 493 | Modified 2013-03-11 20:52:18 | MIT License
play

ActionScript3 source code

/**
 * Copyright chez_sugi ( http://wonderfl.net/user/chez_sugi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/c4h4
 */

// forked from yuuganisakase's Clock (not so short coding)
// 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;
}