如何高效的學習,這才是我們最值得去學習的。
andengine中繪製虛擬遊戲搖杆非常簡單,只需要實現AnalogOnScreenControl類比搖杆類,在設定一些屬性即可。先看:
左邊的搖杆是控制精靈上下左右移動,右邊的搖杆空值精靈的旋轉。代碼結構跟andengine學習系列二一樣,其中很多注釋在系列二中有說明,在該章內便不多複述。
onLoadEngine()方法:
@Overridepublic Engine onLoadEngine() {this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);final Engine engine = new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));try {//因為有兩個搖杆,需要兩個手指同時進行,所以這裡要註冊多點觸控if(MultiTouch.isSupported(this)) {engine.setTouchController(new MultiTouchController());if(MultiTouch.isSupportedDistinct(this)) {Toast.makeText(this, "MultiTouch detected --> Both controls will work properly!", Toast.LENGTH_LONG).show();} else {this.mPlaceOnScreenControlsAtDifferentVerticalLocations = true;Toast.makeText(this, "MultiTouch detected, but your device has problems distinguishing between fingers.\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG).show();}} else {Toast.makeText(this, "Sorry your device does NOT support MultiTouch!\n\n(Falling back to SingleTouch.)\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG).show();}} catch (final MultiTouchException e) {Toast.makeText(this, "Sorry your Android Version does NOT support MultiTouch!\n\n(Falling back to SingleTouch.)\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG).show();}return engine;}
onLoadResources()方法:
public void onLoadResources() {this.mTexture = new Texture(32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);this.mFaceTextureRegion = TextureRegionFactory.createFromAsset(this.mTexture, this, "face_box.png", 0, 0);this.mOnScreenControlTexture = new Texture(256, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);this.mOnScreenControlBaseTextureRegion = TextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_base.png", 0, 0);//這裡是載入搖杆的地盤的紋理圖片 this.mOnScreenControlKnobTextureRegion = TextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_knob.png", 128, 0);//這裡是載入搖杆的紋理圖片this.mEngine.getTextureManager().loadTextures(this.mTexture, this.mOnScreenControlTexture);}
onLoadScene()方法,關鍵的商務邏輯便在該方法中:
public Scene onLoadScene() {this.mEngine.registerUpdateHandler(new FPSLogger());final Scene scene = new Scene(1);scene.setBackground(new ColorBackground(0.09804f, 0.6274f, 0.8784f));final int centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;final int centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;final Sprite face = new Sprite(centerX, centerY, this.mFaceTextureRegion);scene.getTopLayer().addEntity(face);//-------------------------------------------以下為左搖桿的實現----------------------------------------------------------------------final int x1 = 0;//y座標為螢幕的高度減去搖杆底盤的高度,注意螢幕在前面已經被強制橫屏final int y1 = CAMERA_HEIGHT - this.mOnScreenControlBaseTextureRegion.getHeight();//AnalogOnScreenControl構造方法中:第一第二參數是該搖杆的座標,第三個參數為上面定義camera,第四第五個參數為搖杆底盤和搖杆的紋理地區,第六個參數為pTimeBetweenUpdates介面的更新final AnalogOnScreenControl velocityOnScreenControl = new AnalogOnScreenControl(x1, y1, this.mCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, new IAnalogOnScreenControlListener() {//備忘1@Overridepublic void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {Log.i("test","x1:"+x1+",y1:"+y1+",pValueX:"+pValueX+",pValueY:"+pValueY);face.setVelocity(pValueX * 100, pValueY * 100);//備忘2}@Overridepublic void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {//備忘3/* Nothing. */}});velocityOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);//備忘4velocityOnScreenControl.getControlBase().setAlpha(0.5f);scene.setChildScene(velocityOnScreenControl);//-------------------------------------------------------end 坐搖杆的實現------------------------------------------------------------//-------------------------------------------------------以下為右搖桿的實現----------------------------------------------------------final int y2 = (this.mPlaceOnScreenControlsAtDifferentVerticalLocations) ? 0 : y1;final int x2 = CAMERA_WIDTH - this.mOnScreenControlBaseTextureRegion.getWidth();final AnalogOnScreenControl rotationOnScreenControl = new AnalogOnScreenControl(x2, y2, this.mCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, new IAnalogOnScreenControlListener() {@Overridepublic void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {Log.i("test","x2:"+x2+",y2:"+y2+",pValueX:"+pValueX+",pValueY:"+pValueY);if(pValueX == x1 && pValueY == x1) {face.setRotation(x1);} else {face.setRotation(MathUtils.radToDeg((float)Math.atan2(pValueX, -pValueY)));//備忘5}}@Overridepublic void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {/* Nothing. */}});rotationOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);rotationOnScreenControl.getControlBase().setAlpha(0.5f);velocityOnScreenControl.setChildScene(rotationOnScreenControl);//備忘6return scene;}//---------------------------------------------end 右搖桿的實現------------------------------------------------------------
備忘1:關於AnalogOnScreenControl 類的第六個參數pTimeBetweenUpdates,我在這裡把他理解成介面的延時程度,值設的越高,則精靈跟隨搖杆變換的越緩慢;但是如果設成0,則兩個搖杆失靈,於是我們在這裡把他設定成0.1f,便可以看到精靈跟隨搖杆很靈活的變換而沒有卡殼和延時的現象
備忘2:face.setVelocity,整個精靈移動的核心代碼便是這一句,怎麼樣?比起用SurfaceView實現的搖杆簡單方便的多吧!
備忘3:onControlClick(),這個方法是當我們點擊搖杆的時候會觸發的方法,比如我們在這裡可以把搖杆設定放大1.5倍,當沒有點擊的時候又恢複原來的狀態,給人一種真實的感覺。
備忘4:關於這裡顏色的混合可以參考http://www.cnblogs.com/yujunyong/archive/2011/04/13/2015467.html,比較全面。
備忘5:face.setRotation(),精靈的轉動也是這一句代碼便可實現,MathUtils.radToDeg方法返回的是:(180/PI)*方法中的參數; Math.atan2()函數返回點(x,y)和原點(0,0)之間直線的傾斜角。具體可以參考http://apps.hi.baidu.com/share/detail/50270911。
備忘6:這裡可能會有疑問,為什麼是velocityOnScreenControl.setChildScene,而不是scene.setChildScene,事實上,經過測試發現,scene.setChildScene這種情況會把前面定義好的左邊的搖杆覆掉,也就沒有了,scene只會顯示最後一個定義的搖杆,於是我們在這裡寫好的右邊的搖杆需要setChildScene左邊的搖杆中,然後一起setChildScene整個情境中,這樣兩個搖杆都會顯示了。