码迷,mamicode.com
首页 > 其他好文 > 详细

Flex:3D Introduction

时间:2015-08-04 10:45:31      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:

PS:此篇为转文,原文链接:http://www.cnblogs.com/yjmyzz/archive/2010/05/08/1730697.html

三维坐标系:右手法则坐标系

三维透视基本规则:
物体坐标在Z轴上越大(越远),则看起来越小,如果距离足够远,则物体消失于屏幕上的某个特定点(“消失点”)
技术分享技术分享

技术上的主要处理:动态调整物体的scaleX与scaleY(同时因物体大小改变后,相应的x,y坐标值通常也会改变,所以x,y坐标也要做相应调整以符合透视规则),基本公式如下:
scale = fl/(fl+z)

技术分享
package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.ui.Keyboard;
    
    public class Base3D extends Sprite
    {
        public function Base3D()
        {
            var ball:Ball = new Ball();
            addChild(ball);
            
            //观察点 相对于 消失点的坐标
            var xPos:Number    = 0;
            var yPos:Number    = 0;
            var zPos:Number    = 0;
            var fl:Number    = 250;//焦距
            //消失点
            var vpX:Number    = stage.stageWidth/2;
            var vpY:Number    = stage.stageHeight/2;

            addEventListener(Event.ENTER_FRAME, EnterFrameHandler);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDownHandler);
            stage.addEventListener(MouseEvent.MOUSE_WHEEL,MouseWheelHandler);
            
            //鼠标滚轮事件(注:必须让stage获取焦点时-即用鼠标在动画上点击一下,该事件才会触发,另外还要注意:嵌入网页时,浏览器也会响应鼠标滚轮)
            function MouseWheelHandler(e:MouseEvent):void
            {
                zPos += (e.delta*5);
            }
            
            function EnterFrameHandler(event:Event):void
            {
                if (zPos > -fl) 
                {
                    ball.visible    = true;
                    xPos    = mouseX-vpX;
                    yPos    = mouseY-vpY;
                    var scale:Number    = fl / (fl + zPos);
                    ball.scaleX    = ball.scaleY    = scale;
                    ball.x    = vpX+xPos*scale;
                    ball.y    = vpY+yPos*scale;
                } 
                else    ball.visible    = false;
                
                //辅助线
                graphics.clear();
                graphics.lineStyle(1,    0XCCCCCC);
                graphics.moveTo(vpX,    vpY);   
                graphics.lineTo(vpX,    ball.y);
                graphics.moveTo(vpX,    vpY);
                graphics.lineTo(ball.x,    vpY);
                
                graphics.lineStyle(1,0X000FF,    0.5);
                graphics.moveTo(vpX,    vpY);
                graphics.lineTo(ball.x,    ball.y);
                
                graphics.lineStyle(1,0XFF0000,    0.5);
                graphics.moveTo(ball.x,    ball.y);
                graphics.lineTo(mouseX,    mouseY); 
            }
            
            function KeyDownHandler(e:KeyboardEvent):void
            {
                if (e.keyCode == Keyboard.UP) 
                    zPos    += 50;
                else if (e.keyCode == Keyboard.DOWN)
                    zPos    -= 50;
            }
        }
    }
}
3D View

此例中,"鼠标位置"充当"观察点"(即"人眼"位置),键盘↑↓键可调整小球在Z轴上的位置。移动鼠标,通过辅助线观察变化。

技术分享
package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.ui.Keyboard;
    
    public class Base3D extends Sprite
    {
        private var ball:Ball;
        
        //相当于消失点的坐标
        private var xpos:Number=0;
        private var ypos:Number=0;
        private var zpos:Number=0;
        
        //x,y,z三轴上的速度分量
        private var vx:Number=0;
        private var vy:Number=0;
        private var vz:Number=0;
        
        private var friction:Number    = 0.98;
        private var fl:Number=250;
        
        //消失点
        private var vpX:Number    = stage.stageWidth/2;
        private var vpY:Number    = stage.stageHeight/2;
        
        public function Base3D()
        {
            init();
        }
        
        private function init():void 
        {
            stage.align        = StageAlign.TOP_LEFT;  
            stage.scaleMode    = StageScaleMode.NO_SCALE;
            ball = new Ball(20);
            addChild(ball);
            addEventListener(Event.ENTER_FRAME, EnterFrameHandler);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDownHandler);
        }
        
        private function EnterFrameHandler(event:Event):void 
        {
            vpX = stage.stageWidth/2;
            vpY = stage.stageHeight/2;
            
            xpos    += vx;
            ypos    += vy;
            zpos    += vz;
            vx        *= friction;
            vy        *= friction;
            vz        *= friction;
            
            if (zpos>-fl) {
                var scale:Number = fl / (fl + zpos);
                ball.scaleX=ball.scaleY=scale;
                ball.x=vpX+xpos*scale;
                ball.y=vpY+ypos*scale;
                ball.visible=true;
            } else {
                ball.visible=false;
            }
            
            //辅助线
            graphics.clear();
            graphics.lineStyle(1,0xefefef);
            graphics.moveTo(0,stage.stageHeight/2);
            graphics.lineTo(stage.stageWidth,stage.stageHeight/2);
            graphics.lineTo(stage.stageWidth-15,stage.stageHeight/2-8);
            graphics.moveTo(stage.stageWidth,stage.stageHeight/2);
            graphics.lineTo(stage.stageWidth-15,stage.stageHeight/2+8);
            
            graphics.moveTo(stage.stageWidth/2,0);
            graphics.lineTo(stage.stageWidth/2,stage.stageHeight);
            graphics.lineTo(stage.stageWidth/2-8,stage.stageHeight-15);
            graphics.moveTo(stage.stageWidth/2,stage.stageHeight);
            graphics.lineTo(stage.stageWidth/2+8,stage.stageHeight-15);
            graphics.lineStyle(1,0xdadada);
            graphics.moveTo(vpX,vpY);
            graphics.lineTo(ball.x,ball.y);
            
            
        }
        private function KeyDownHandler(e:KeyboardEvent):void
        {
            switch (e.keyCode)
            {
                case Keyboard.UP :
                    vy    -= 10;
                    break;
                case Keyboard.DOWN :
                    vy    += 10;
                    break;
                case Keyboard.LEFT :
                    vx    -= 10;
                    break;
                case Keyboard.RIGHT :
                    vx    += 10;
                    break;
                case Keyboard.SHIFT :
                    vz    += 5;
                    break;
                case Keyboard.CONTROL :
                    vz    -= 5;
                    break;
                default :
                    break;
            }
        }
    }
}
3D Motion

此例中,↑↓←→控制x,y轴方向速度,shift/ctrl控制z轴速度

技术分享
package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.ui.Keyboard;
    
    public class Base3D extends Sprite
    {
        private var ball:Ball;
        private var xpos:Number=0;
        private var ypos:Number=0;
        private var zpos:Number=0;
        private var vx:Number    = Math.random()*12-6;
        private var vy:Number    = Math.random()*12-6;
        private var vz:Number    = Math.random()*12-6;
        private var fl:Number    = 250;
        
        //消失点
        private var vpX:Number    = stage.stageWidth/2;
        private var vpY:Number    = stage.stageHeight/2;
        
        //相对于消失点的六个边界面(上,下,左,右,前,后)
        private var top:Number        = -100;
        private var bottom:Number    = 100;
        private var left:Number        = -100;
        private var right:Number    = 100;
        private var front:Number    = 100;
        private var back:Number        = -100;
        
        public function Base3D()
        {
            init();
        }
        
        private function init():void 
        {
            stage.align     = StageAlign.TOP_LEFT;  
            stage.scaleMode = StageScaleMode.NO_SCALE;
            ball    = new Ball(15);
            addChild(ball);
            addEventListener(Event.ENTER_FRAME, EnterFrameHandler);
        }
        
        private function EnterFrameHandler(event:Event):void {
            vpX = stage.stageWidth/2;
            vpY = stage.stageHeight/2; 
            
            xpos    += vx;
            ypos    += vy;
            zpos    += vz;
            var radius:Number    = ball.getRadius();
            
            //左右边界
            if (xpos+radius    > right)
            {
                xpos    =     right-radius;
                vx        *=     -1;
            } 
            else if (xpos - radius < left)
            {
                xpos    =     left+radius;
                vx        *=    -1;
            }
            
            //上下边界
            if (ypos+radius > bottom) 
            {                
                ypos    =     bottom-radius;
                vy        *=    -1;
            } 
            else if (ypos - radius < top) 
            {
                ypos    =     top+radius;
                vy        *=     -1;
            }
            
            //前后边界
            if (zpos+radius > front) 
            {
                zpos    =     front-radius;
                vz        *=    -1;
            } 
            else if (zpos - radius < back) 
            {
                zpos    =    back+radius;
                vz        *=    -1;
            }
            
            //换算成平面二维坐标及缩放比率
            if (zpos > -fl) 
            {
                var scale:Number = fl / (fl + zpos);
                ball.scaleX=ball.scaleY=scale;
                ball.x=vpX+xpos*scale;
                ball.y=vpY+ypos*scale;
                ball.visible    = true;
            } 
            else 
                ball.visible=false;
            
            //辅助线
            graphics.clear();
            graphics.lineStyle(1,0xccccff);
            graphics.moveTo(0,stage.stageHeight/2);
            graphics.lineTo(stage.stageWidth,stage.stageHeight/2);
            graphics.lineTo(stage.stageWidth-15,stage.stageHeight/2-8);
            graphics.moveTo(stage.stageWidth,stage.stageHeight/2);
            graphics.lineTo(stage.stageWidth-15,stage.stageHeight/2+8);
            
            graphics.moveTo(0,stage.stageHeight);
            graphics.lineTo(stage.stageWidth,0);
            graphics.lineTo(stage.stageWidth-15,2);
            graphics.moveTo(stage.stageWidth,0);
            graphics.lineTo(stage.stageWidth-6,13);
            
            graphics.moveTo(stage.stageWidth/2,0);
            graphics.lineTo(stage.stageWidth/2,stage.stageHeight);
            graphics.lineTo(stage.stageWidth/2-8,stage.stageHeight-15);
            graphics.moveTo(stage.stageWidth/2,stage.stageHeight);
            graphics.lineTo(stage.stageWidth/2+8,stage.stageHeight-15);
            graphics.lineStyle(1,0xffccff);
            graphics.moveTo(vpX,vpY);
            graphics.lineTo(ball.x,ball.y);
        }
    }
}
3D Motion Rebound

 

 

 

 

 

Flex:3D Introduction

标签:

原文地址:http://www.cnblogs.com/cangyu/p/4701131.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!