In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

jiglibflashでバントの練習 Ver 0.2

2011-01-14
バットの質量をガッツり重くしたら、上手く跳ね返るようになりました。
ただ、力学的にはおかしいので(バットを振っている力を考慮していない)、まだまだ調査します。
---------------------------------------------------------------
2011-01-13
jiglibFlashの習作です。
サンプルコードを元に、jiglibFlashを理解するため、ちょちょいと変更を加えています。

マウス操作でバットを振り、飛んでくるボールに当てるというものです。
跳ね返るようにするためはどのようにすればよいか調査中なため
バットにあたったとき、上手く跳ね返らないのでバントみたいになってしまっています。
/**
 * Copyright sasa ( http://wonderfl.net/user/sasa )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/icd1
 */

package
{
    import flash.ui.Keyboard;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.geom.Matrix3D;
    import flash.geom.Vector3D;
    
    import jiglib.cof.JConfig;
    import jiglib.geometry.*;
    import jiglib.math.*;
    import jiglib.physics.*;
    import jiglib.physics.constraint.*;
    import jiglib.plugin.papervision3d.*;
    
    import org.papervision3d.cameras.CameraType;
    import org.papervision3d.core.geom.renderables.Vertex3D;
    import org.papervision3d.core.math.Number3D;
    import org.papervision3d.core.math.Plane3D;
    import org.papervision3d.core.utils.Mouse3D;
    import org.papervision3d.events.*;
    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.materials.shadematerials.*;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.view.BasicView;
    import org.papervision3d.view.layer.ViewportLayer;
    import org.papervision3d.view.layer.util.ViewportLayerSortMode;
    import org.papervision3d.view.stats.StatsView;

    
    [SWF(width="800", height="600", backgroundColor="#ffffff", frameRate="60")]
    public class Main extends BasicView
    {
        private var mylight:PointLight3D;
        private var mouse3D:Mouse3D;
        private var shadeMateria:FlatShadeMaterial;
        
        private var ground:RigidBody;
        private var ballBody:Vector.<RigidBody>;//ボールの剛体
        private var batBody:RigidBody;//バットの剛体
        
        private var onDraging:Boolean = false;
        
        private var currDragBody:RigidBody;
        private var dragConstraint:JConstraintWorldPoint;
        private var startMousePos:Vector3D;
        private var planeToDragOn:Plane3D;
        
        private var keyRight   :Boolean = false;
        private var keyLeft    :Boolean = false;
        private var keyForward :Boolean = false;
        private var keyReverse :Boolean = false;
        private var keyUp:Boolean = false;
        
        private var physics:Papervision3DPhysics;
         
        public function Main():void
        {
            super(800, 600, true, true, CameraType.TARGET);
            
            init3D();
        }

        private function init3D():void
        {
            JConfig.numContactIterations = 12;
            physics = new Papervision3DPhysics(scene, 8);
            
            Mouse3D.enabled = true;
            mouse3D = viewport.interactiveSceneManager.mouse3D;
            viewport.containerSprite.sortMode = ViewportLayerSortMode.INDEX_SORT;
            
            mylight = new PointLight3D(true, true);
            mylight.y = 300;
            mylight.z = -400;
             
            shadeMateria = new FlatShadeMaterial(mylight, 0x77ee77);
            var materiaList :MaterialsList = new MaterialsList();
            materiaList.addMaterial(shadeMateria, "all");
            
            ground = physics.createCube(materiaList, 500, 500, 10);
            ground.movable = false;
            ground.friction = 0.9;
            ground.restitution = 8;
            viewport.getChildLayer(physics.getMesh(ground)).layerIndex = 1;

            var vplObjects:ViewportLayer = new ViewportLayer(viewport,null);
            vplObjects.layerIndex = 2;
            vplObjects.sortMode = ViewportLayerSortMode.Z_SORT;
            viewport.containerSprite.addLayer(vplObjects);

            //バットの生成
            var batHeight:Number = 200;
            shadeMateria = new FlatShadeMaterial(mylight, 0xFFFF00);
            var capsuleSkin:Cylinder;
            capsuleSkin = new Cylinder(shadeMateria, 20, batHeight);
            //バットの原点を長さの半分だけずらす
            for each (var v:Vertex3D in capsuleSkin.geometry.vertices) {
                v.y += batHeight/2;
            }
            scene.addChild(capsuleSkin);
            vplObjects.addDisplayObject3D(capsuleSkin);
            //本当は剛体の中心位置もバット同様にずらす必要がありますが、方法がわからないのでとりあえず長さを二倍にして、バットの先端でも衝突が起きるようにしています。
            //但し、本当はモノが何も無いバットの(持っている原点を中心とした)反対側でも衝突が検知されてしまいます。
            batBody = new JCapsule(new Pv3dMesh(capsuleSkin), 20, batHeight * 2);
            //バットの質量をガッツり重くする。質量0では上手く動かないため(地面のような静的剛体にならない?)、5000程度の値を与えてかなり重くしています。
            batBody.mass = 5000;
            //摩擦、反発の仕様は調査中のため、適当な値を設定
            batBody.friction = 0.8;
            batBody.restitution = 0.8;
            batBody.moveTo(new Vector3D(50, 100, 0));
            PhysicsSystem.getInstance().addBody(batBody);
            
            //ボールの生成
            //本当は1個つくればいいのですが、めんどくさかったのでサンプルのコードそのまま使っています。
            ballBody = new Vector.<RigidBody>();
            var color:uint;
            for (var i:int = 0; i < 1; i++)
            {
                color = (i == 0)?0xff8888:0xeeee00;
                shadeMateria = new FlatShadeMaterial(mylight, color);
                shadeMateria.interactive = true;
                ballBody[i] = physics.createSphere(shadeMateria, 22);
                ballBody[i].mass = 2;
                ballBody[i].friction = 0.8;
                ballBody[i].restitution = 0.8;
                ballBody[i].moveTo(new Vector3D( -100, 200, -500));
                //ボールに対してZ軸方向に4000の力を加えます。
                //一瞬のうちに大きな力を加えることで、ボールが投げられているような動きをします。
                ballBody[i].addWorldForce(new Vector3D(0, 0, 4000), ballBody[i].currentState.position);
                vplObjects.addDisplayObject3D(physics.getMesh(ballBody[i]));
            }
            
            camera.y = mylight.y;
            camera.z = mylight.z;
                         
            //var stats:StatsView = new StatsView(renderer);
            //addChild(stats);
             
            startRendering();
        }
        
        private function findSkinBody(skin:DisplayObject3D):int
        {
            for (var i:String in PhysicsSystem.getInstance().bodies)
            {
                if (skin == physics.getMesh(PhysicsSystem.getInstance().bodies[i]))
                {
                    return int(i);
                }
            }
            return -1;
        }
        
        private function resetBox():void
        {
            for (var i:int = 0; i < ballBody.length;i++ )
            {
                if (ballBody[i].currentState.position.y < -200)
                {
                    ballBody[i].moveTo(new Vector3D( -100, 200, -500));
                    ballBody[i].addWorldForce(new Vector3D(0, 0, 4000), ballBody[i].currentState.position);
                }
            }
        }
        
        private function testFreezeObject():void {
            var _body:RigidBody;
            for (var i:int = 0; i < ballBody.length; i++ )
            {
                _body = ballBody[i];
                if (_body.isActive)
                {
                    shadeMateria = (i == 0)? new FlatShadeMaterial(mylight, 0xff8888):new FlatShadeMaterial(mylight, 0xeeee00);
                    shadeMateria.interactive = true;
                    physics.getMesh(_body).material = shadeMateria;
                }
                else
                {
                    shadeMateria = new FlatShadeMaterial(mylight, 0xff7777);
                    shadeMateria.interactive = true;
                    physics.getMesh(_body).material = shadeMateria;
                }
            }
        }


        protected override function onRenderTick(event:Event = null):void {
            
            //剛体の回転はrotationX, rotationY, rotationZと
            //pitch, roll, yawがあるみたいです。
            //どのように動くかは調査中
            batBody.rotationZ = (stage.mouseY / stage.stageHeight) * 180;
            batBody.yaw(((stage.stageWidth / 2) - stage.mouseX) / 2);
            
            //バットの位置は初期位置から変えたくないため、毎度初期位置に位置させるコードを追加しています。
            batBody.moveTo(new Vector3D(50, 100, 0));
            
            //physics.step();//dynamic timeStep
            physics.engine.integrate(0.1);//static timeStep
            resetBox();
            //testFreezeObject();
            super.onRenderTick(event);
        }
    }
}