pv3d物体在stage上的坐标投射

thumb_screenprojection

pv3d提供了方便的接口。将物体的autoCalcScreenCoords设为true,可以直接从screen属性取到坐标值。进入看源代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
package {
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.geom.Point;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.utils.Timer;
    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.view.BasicView;
   
    [SWF(width="700",height="400")]
    /**
     * @author Ryan Liu | www.ryan-liu.com
     * @since  2009-4-10 8:32
     */

    public class ScreeLocation extends BasicView {
       
        private var mat:FlatShadeMaterial
        private var matList:MaterialsList
        private var light:PointLight3D
        private var cross:Shape;
        private var ang:Number = 90
        private var camTarget:DisplayObject3D;
        private var sw:int = stage.stageWidth;
        private var sh:int = stage.stageHeight;
        private var enemyNum:int = 5;
        private var enemyArr:Array = [];
        private var uiColor:int = 0x009922;
        private var logColor:int = 0x00cc44;
        private var targetEnemyID:int = 0;
        private var targetPos:Point = new Point();
        private var crossPos:Point = new Point(sw / 2, sh / 2);
        private var logField:TextField
        private var defaultLog:String = "Press 1-5 to switch target"
        private var warningLog:String = "Target out of sight"
        private var logFormat:TextFormat = new TextFormat('arial', 14, logColor, false, false, false,null, null, 'center');
        private var logTimer:Timer
        private var logTimerOn:Boolean = false;
        private var logTimerDelay:int = 300;
        private var logTimerBuffer:String = "";
       
        public function ScreeLocation() {
            init3D();
            initUI();          
            startRendering();          
            addEventListener(Event.ENTER_FRAME, loop)
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPress);
        }
        private function initUI():void {
            var screenui:Shape = new Shape();
            var g:Graphics = screenui.graphics;
            g.lineStyle(1, uiColor);
            var gap:int = 15
            g.drawRect(gap, gap, sw - gap * 2, sh - gap * 2);
            g.drawRect(0, 0, sw - 1 , sh - 1 );
            addChild(screenui);
           
            cross = new Shape();
            addChild(cross);
           
            logField = new TextField();
            logField.width = 300;
            logField.height = 30;
            logField.x = (sw - 300) * .5;
            logField.y = sh - 40;
            logField.selectable = false;
            logField.text = defaultLog;
            logField.setTextFormat(logFormat);
            addChild(logField);
           
            setLogInfo(defaultLog);
           
            logTimer = new Timer(logTimerDelay);
            logTimer.addEventListener(TimerEvent.TIMER, onTimer);
        }
        private function init3D():void {
            camera.focus = 10;
            camera.zoom = 35;
            light = new PointLight3D()
            light.x = 8000;
            light.y = 12000
            light.z = -8000
            scene.addChild(light)
            //build cubes
            for (var i:int = 0; i < enemyNum; i++) {
                mat = new FlatShadeMaterial(light, 0xffffff, Math.random() * 0xffffff);
                matList = new MaterialsList({all:mat});
                var enemy:Cube = new Cube(matList, 60, 60, 60, 2, 2, 2);
                enemy.rotationX = Math.random() * 360;
                enemy.rotationY = Math.random() * 360;
                enemy.rotationZ = Math.random() * 360;
                enemy.x = (Math.random() - Math.random()) * sw * 1.5;
                enemy.y = (Math.random() - Math.random()) * sh * 1.2;
                enemy.z = (Math.random() - Math.random()) * 300;
                //auto calculate screen coordinate
                enemy.autoCalcScreenCoords = true;
                scene.addChild(enemy);
                enemyArr.push(enemy);
            }
            //set camera's target          
            camTarget = new DisplayObject3D();
            scene.addChild(camTarget);         
            camera.target = camTarget;
        }
        private function setLogInfo(info:String):void {
            logField.text = info;
            logField.setTextFormat(logFormat);
        }
        private function drawCross():void {
            var curTarget:Cube = enemyArr[targetEnemyID] as Cube;
            var targetX:Number = curTarget.screen.x + sw * .5;
            var targetY:Number = curTarget.screen.y + sh * .5;
            var g:Graphics = cross.graphics;
            g.clear();
           
            if (targetX < 0 || targetX > sw || targetY < 0 || targetY > sh) {
                switchWarning(true);
            } else {
                switchWarning(false);
                crossPos.x += (targetX  - crossPos.x) * .4;
                crossPos.y += (targetY  - crossPos.y) * .4;
                g.lineStyle(1, uiColor);
                g.moveTo(crossPos.x, 0);
                g.lineTo(crossPos.x, sh);
                g.moveTo(0, crossPos.y);
                g.lineTo(sw, crossPos.y);              
                g.drawRect(crossPos.x - 30, crossPos.y - 30, 60, 60);
            }
        }
       
        private function loop(e:Event):void {
            for (var i:int = 0; i < enemyNum; i++) {
                var enemy:Cube = enemyArr[i] as Cube;
                enemy.yaw(i+1);
            }
           
            camTarget.x += (targetPos.x - camTarget.x) * .2;   
            camTarget.y += (targetPos.y - camTarget.y) * .2;
           
            drawCross();
        }
       
        private function onMouseMove(e:MouseEvent):void {
            var tx:Number = 300*(e.stageX - sw * .5) / (sw * .5);
            var ty:Number = -300*(e.stageY - sh * .5) / (sh * .5);
            targetPos.x = tx;
            targetPos.y = ty;
        }
       
        private function onKeyPress(e:KeyboardEvent):void {
            var keycode:uint = e.keyCode
            if (keycode >= 49 && keycode <= 53) {
                targetEnemyID = keycode - 49;
            }
        }
       
        private function switchWarning(isOn:Boolean):void {
            if (logTimerOn == isOn) {
                return;
            } else {
                logTimerOn = isOn;
            }
            if (isOn) {
                setLogInfo(warningLog);
                logTimerBuffer = warningLog;
                logTimer.start();
            } else {
                setLogInfo(defaultLog);
                logTimer.stop();
            }
        }
        private function onTimer(e:TimerEvent):void {
            if (logField.text == "") {
                setLogInfo(logTimerBuffer);
            } else {
                setLogInfo("");
            }
        }

    }
   
}
Comments:
  1. Weekly Digest for December 16th | Fework Says:

    [...] Shared pv3d物体在stage上的坐标投射. [...]

Leave a comment


Verify Code   If you cannot see the CheckCode image,please refresh the page again!