pv3d物体在stage上的坐标投射
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(""); } } } } |
12月 16th, 2009 at 08:26
[...] Shared pv3d物体在stage上的坐标投射. [...]