這次想研究Flash ActionScript 3鍵盤事件與PV3D的互動,算是成功,也不算成功。詭異。
與前幾次同樣使用Cube來實驗,有材質貼圖的Cube預設自體X軸緩慢旋轉,鍵盤按下左鍵或右鍵之後,camera會以Cube為中心向左或向右旋轉。

原本想要以類第一人稱遊戲的操作方式(WASD),不過讀入的keyCode都是229,只有特殊鍵(上下左右鍵、Ctrl、Shift…)才能正確讀出,查了document,在KeyboardEvent.keyCode的部分有一行這麼寫著『注意:當您執行輸入法編輯器 (IME) 時,keyCode 將無法報告正確的按鍵碼。』,所以嘗試關掉IME(輸入法),先以Capabilities.hasIME查出是否有安裝輸入法,再判斷IME.enabled是否為true,若是的話,設為false。測試的結果有trace出已安裝輸入法,也試圖關閉,依舊無法正確讀出keyCode,這部分還要再查查如何修正,現在先以上下左右鍵來控制。
下面是演示效果,以上下左右鍵控制camera的移動。
以下是原始碼:
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 | package { import flash.display.Sprite; import flash.events.Event; import flash.events.KeyboardEvent; import flash.system.Capabilities; import flash.system.IME; import org.papervision3d.cameras.Camera3D; import org.papervision3d.objects.*; import org.papervision3d.materials.*; import org.papervision3d.scenes.MovieScene3D; public class CubeRotate extends Sprite{ private var textContainer : Sprite; private var container :Sprite; private var scene :MovieScene3D; private var camera :Camera3D; private var myCube :DisplayObject3D; private var objKeyboard :Object; // 建立一個物件紀錄鍵盤事件 private var hoverx :Number; private var hovery :Number; public function CubeRotate(){ objKeyboard = {pressed:false, keyCode:null}; hoverx = 0; hovery = 0; // 建立主要容器 container = new Sprite; container.x = stage.stageWidth/2; container.y = stage.stageHeight/2; addChild(container); // 將這個容器指定為3D場景 scene = new MovieScene3D( container ); // 建立像機物件 camera = new Camera3D(); camera.z = -300; camera.zoom = 3; camera.focus = 100; // 定義貼圖材質 var bmamWoodboard:BitmapAssetMaterial = new BitmapAssetMaterial("woodboard.jpg"); // 指定立方體各面的著色方式 var materiallist:MaterialsList = new MaterialsList(); materiallist.addMaterial(bmamWoodboard,"top"); materiallist.addMaterial(bmamWoodboard,"bottom"); materiallist.addMaterial(bmamWoodboard,"front"); materiallist.addMaterial(bmamWoodboard,"back"); materiallist.addMaterial(bmamWoodboard,"left"); materiallist.addMaterial(bmamWoodboard,"right"); // 建立立方體 myCube = new Cube(materiallist, 200, 200, 200, 1, 1, 1); // 在場景中加入剛剛建立的立方體 scene.addChild(myCube); // 將相機的目標指定到立方體 camera.target = myCube; // 註冊enterFrame的事件,每次觸發皆重繪制3D畫面 stage.addEventListener(Event.ENTER_FRAME, loop3d); if (Capabilities.hasIME){ if (IME.enabled){ trace("IME 已安裝且啟用。"); IME.enabled = false; trace("IME 已Disable。"); } } // 註冊鍵盤事件 // 鍵盤按下 stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler); // 放開鍵盤 stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler); } private function loop3d(evt: Event): void{ if(objKeyboard.pressed){ switch(objKeyboard.keyCode){ case 37: hoverx -= 0.1; break; case 39: hoverx += 0.1; break; case 38: hovery -= 0.1; break; case 40: hovery += 0.1; break; } camera.hover(0, hoverx, hovery); /* objKeyboard.keyCode: 37 = 向左鍵 38 = 向上鍵 39 = 向右鍵 40 = 向下鍵 */ }else{ // 旋轉立方體 myCube.rotationX += 0.35; } // 繪制場景 scene.renderCamera(camera); } private function keyDownHandler(evt:KeyboardEvent): void{ objKeyboard.pressed = true; objKeyboard.keyCode = evt.keyCode; } private function keyUpHandler(evt:KeyboardEvent): void{ objKeyboard.pressed = false; objKeyboard.keyCode = null; } } } |
結論:
1. keyCode、IME部分需再詳查。
2. camera.hover的部份,還是不太能精確了解參數的意義。
hover(type:Number, mouseX:Number, mouseY:Number)
Parameters
type:Number — Type of movement.mouseX:Number — Indicates the x coordinate of the mouse position in relation to the canvas MovieClip.
mouseY:Number — Indicates the y coordinate of the mouse position in relation to the canvas MovieClip.
type是什麼?沒有詳細寫清楚,開原始碼來研究,裡面也是寫這樣。
mouseX和mouseY,大概知道,但為什麼一使用hover,target馬上遠離鏡頭,我並沒另外設定距離啊。

6 Responses