幾年前項目中想做一個手機模擬手柄的功能,在手機上繪制並通過觸摸反饋獲取操控信息,當時記錄的博客只有貼圖,很多人留言想借鑒思路,今天抽點時間把項目轉成了AndroidStudio版本,稍微寫詳細一點。
現在手機比幾年前快了N倍,非常流暢毫無卡頓
首先上圖:
這是我用到的素材(每個鍵的常態和按下狀態,就是按下時要換圖)
實現的效果:
然后寫一下思路吧:
1、手柄按鍵分兩類:
按鍵(A、B、X、Y,DPAD等,反饋的值是一個確定的值)
模擬量(左右搖桿,左右扳機(triggerL triggerR),反饋的值是一個偏移量(0到1之間的浮點值))
2、所有按鍵需要在SurfaceView上進行繪制,drawCanvas()方法進行實時狀態繪制
3、相關技術:
- SurfaceView
- 觸屏和多點觸控處理
- Bitmap處理
- 震動
4、實現步驟:(按難度逐漸增加)
- 實現SurfaceView繪制
- 普通按鈕
- 方向鍵
- 扳機鍵
- 搖桿
按鍵信息:--1 // A按下 按鍵信息:--0 // A抬起 按鍵信息:--2 // B按下 按鍵信息:--0 // B抬起 按鍵信息:--8 // X按下 按鍵信息:--0 // X抬起 按鍵信息:--16 // Y按下 按鍵信息:--0 // Y抬起
//每個按鈕都獨立封裝,自己處理自己的貼圖和觸屏事件 //觸屏事件處理,每個按鍵View自識別點擊事件是否在自己的范圍內: //手柄對象視圖繼承SurfaceView實現,加載所有按鈕,統一對外輸出按鈕事件 @Override public boolean onTouchEvent(MotionEvent event) { if(gameButtonA != null) { gameButtonA.checkTouch(event); } if(gameButtonB != null) { gameButtonB.checkTouch(event); } if(gameButtonC != null) { gameButtonC.checkTouch(event); } if(gameButtonX != null) { gameButtonX.checkTouch(event); } if(gameButtonY != null) { gameButtonY.checkTouch(event); } if(gameButtonZ != null) { gameButtonZ.checkTouch(event); } if(gameButtonL1 != null) { gameButtonL1.checkTouch(event); } if(gameButtonR1 != null) { gameButtonR1.checkTouch(event); } if(gameButtonSelect != null) { gameButtonSelect.checkTouch(event); } if(gameButtonStart != null) { gameButtonStart.checkTouch(event); } if(gameButtonDpad != null) { gameButtonDpad.checkTouch(event); } if(mGameJoyL != null) { mGameJoyL.onTouchEvent(event); } if(mGameJoyR != null) { mGameJoyR.onTouchEvent(event); } if(mGameTriggerL != null) { mGameTriggerL.onTouchEvent(event); } if(mGameTriggerR != null) { mGameTriggerR.onTouchEvent(event); } return true; }
// 最后直接加載手柄視圖 public class MainActivity extends Activity { private GamePadSurfaceView mouseSurfaceView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); mouseSurfaceView = new GamePadSurfaceView(this); mouseSurfaceView.setOnGamePadKeyActionListener(padKeyActionListener); mouseSurfaceView.setOnGamePadMotionActionListener(padMotionActionListener); setContentView(mouseSurfaceView); } private GamePadSurfaceView.OnGamePadKeyActionListener padKeyActionListener = new GamePadSurfaceView.OnGamePadKeyActionListener() { @Override public void onKeyActionListener(long keyInfo) { } }; private GamePadSurfaceView.OnGamePadMotionActionListener padMotionActionListener = new GamePadSurfaceView.OnGamePadMotionActionListener() { @Override public void onMotionActionListener(float[] motionValues) { } }; }
代碼剛找回編譯,需要源碼參考,可以發郵件到:syliu.11@163.com
碼字不易,請作者喝杯咖啡吧!