563
技術社區[雲棲]
Android 遊戲開發中 OnTouchEvent() 觸屏事件的性能優化
關於Android 遊戲開發中 OnTouchEvent() 觸屏事件的性能優化筆記!
原文地址:https://blog.csdn.net/xiaominghimi/archive/2011/01/10/6127578.aspx
先上一段代碼大家來看一下:
view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
package com.himi;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
/**
* @author Himi
*/
public class MainActivity extends Activity {
private Object object;
private final int TIME = 50;//備注1
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
object = new Object();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.v("Himi", "ACTION_DOWN");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
Log.v("Himi", "ACTION_UP");
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
Log.v("Himi", "ACTION_MOVE");
}
synchronized (object) {//備注2
try {
object.wait(TIME);} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return true;//這裏一定要返回true!原因請看【Android2D遊戲開發之九】
}
}
代碼很清晰嗬嗬,主要就是備注2的地方:
一: 前言:
各位童鞋肯定都知道在模擬器中,我們的鼠標當點擊一次模擬器屏幕然後釋放,先觸發 ACTION_DOWN 然後 ACTION_UP ;如果是在屏幕上移動那麼才會觸發 ACTION_MOVE 的動作;OK,很對。但是你要知道,這隻是模擬器!!!!!
二:真機與模擬器的區別:
當我們的小用戶(說到用戶我就想起“我叫MT”中的暗夜男那句經典台詞:親愛的客戶,我是嫩爹!)咳咳,回到話題;當我們的用戶在玩我們的遊戲的時候,尤其是RPG這種類型的,用戶肯定需要會長時間的去觸屏按我們的虛擬按鍵,比如我們會在屏幕上畫上一個虛擬方向盤類似這樣子~那麼其實 ACTION_MOVE 這個事件會被Android一直在響應!!
三: 為什麼會一直響應 ACTION_MOVE 這個動作呢? 如果用戶沒有移動手指而是靜止不動也會一直響應?
原因有兩點:低一點是因為,Android 對於觸屏事件很敏感!第二點:雖然我們的手指感覺是靜止沒有移動,其實事實不是如此!當我們的手指觸摸到手機屏幕上之後,感覺靜止沒動,其實手指在不停的微顫抖震動。不信你試試靜止下手指,是不是微微動?嘿嘿~
so~ 我們就要分析了,如果ACTION_MOVE此時間一直被Android os 一直不停的響應並處理,無疑對我們遊戲的性能增加了不少的負擔!
比如我們遊戲線程繪圖時間每次用了50ms,那麼在這50ms裏Android接收到的觸屏事件其實已經響應了N遍了- -、那麼我們其實根本用不著按鍵響應這麼多次,而是需要在我們每次繪圖後,或者繪圖前接受一次用戶按鍵就OK了,不是麼?!so~我們要控製這個時間,讓他慢下來,隨著我們的繪圖時間一起來合作~這樣就能減不少係統線程的負擔。
備注2:
可能有的童鞋會問為什麼不用sleep()的方法,其實如果我們隻是想讓線程休眠指定時間的話可以用sleep()函數,但是這個沒有資源鎖的限製。而Object的wait,notify方法通常用在時間不定的條件限製等待,並且必須寫在同步代碼塊中。so~
還有童鞋會問,為什麼不用當前類的object來使用:this.wait(),而是new 一個object來:synchronized 中的Object 表示Object 調用wait必須擁有該對象的監視鎖,當前我們有了object的鎖,就要用object調用wait~
備注1:
這裏的變量大家都知道其實是我們設置的休眠的時間,那麼這裏我想拿出來跟大家說下關於這個時間的定值,在上文我也有說過我們的遊戲中隻要按鍵跟我們的繪圖線程的時間一樣即可,當然這裏是個我們的理想時間!如果我們遊戲中有人物的幀,那麼我們可以來根據人物幀數來當成設定這個睡眠時間也是相當合適的,畢竟人物一幀說明邏輯執行了一遍了嗬嗬~這個還是根據大家遊戲的情況而定吧~
注意:Object.wait(long timeout)這個方法也需要慎用!
原因是因為測試發現:這個睡眠的時間其實比你規定的時間要略微的長一些,不過我們合理控製好時間還是沒問題的。
最後更新:2017-04-02 06:52:04