這裏我們從“喫雞”說起。
絕·地·求·生 遊戲的畫面效果超級強悍,像我這樣只玩摜蛋小遊戲的三不青年(不抽菸,不喝酒,不玩網遊)都被吸引到了
近年來掀起了一股“喫雞”熱潮,更衍生出了一種文化現象
(相關cosplay)
其手遊版本也是相當火爆,直播平臺上的觀看人數都超級多,當然,不確定這裏的數據是否有水分
一些周邊產品也被帶得風生水起
當然,也包括一些黑產,如外·掛,
(有些外·掛還是很有想象力的)
但是外·掛是“暴富寶典” ---- 《刑法》中掛了號的
(破壞計算機信息系統罪)
第二百八十六條 違反國家規定,對計算機信息系統功能進行刪除、修改、增加、干擾,造成計算機信息系統不能正常運行,後果嚴重的,處五年以下有期徒刑或者拘役;後果特別嚴重的,處五年以上有期徒刑。
違反國家規定,對計算機信息系統中存儲、處理或者傳輸的數據和應用程序進行刪除、修改、增加的操作,後果嚴重的,依照前款的規定處罰。
故意製作、傳播計算機病毒等破壞性程序,影響計算機系統正常運行,後果嚴重的,依照第一款的規定處罰。
作爲有道德與社會責任感的我們,自然是不能去製作外·掛程序。
同時,一些物理輔助工具也火了起來,可以用來協助使用者進行多指操作,就像觸控筆一樣,方便了手指的觸控操作,就加快了在遊戲中的反應速度,關鍵時刻剛得過
(主要操作有 水平移動,視線旋轉,射擊,跳躍等,所以多指操作相對於2個拇指的操作要有優勢)
作爲Android Developer, 我們完全可以在系統中通過注入點擊事件來實現類似的功能。
聲控設計
大吼一聲,射擊鍵就被點擊起來,2個拇指進行其他的操作,這就實現了3指操作的效果。
主要步驟:
1.使用 AudioRecord實時獲取外部聲音的音量大小,達到設定的閾值時觸發點擊
public RecordThread() {
super();
bs = AudioRecord.getMinBufferSize(SAMPLE_RATE_IN_HZ,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
ar = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_IN_HZ,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, bs);
}
public void run() {
super.run();
Log.d("getVoice", "run");
ar.startRecording();
// ..... buffer
byte[] buffer = new byte[bs];
isRun = true;
Log.d("getVoice", "buffer len=" + buffer.length);
while (isRun) {
int r = ar.read(buffer, 0, bs);
int v = 0;
// . buffer ............
for (int i = 0; i < buffer.length; i++) {
// ......................
v += buffer[i] * buffer[i];
}
// ................. sendMessage ...... Handler ......
float soundLevel = v / (float) r;
if (soundLevel > 3300){
sendLongPress(InputDevice.SOURCE_TOUCHSCREEN, 220, 330, 3000);
}
}
ar.stop();
}
public void pause() {
// ....... Activity . onPause ...... Activity ........
isRun = false;
}
public void start() {
// ....... Activity . onResume ...... Activity ..............
if (!isRun) {
super.start();
}
}
}
2.模擬點擊
//向inputManager發送一個touch事件,點擊x=220, y=330的座標3000ms
sendLongPress(InputDevice.SOURCE_TOUCHSCREEN, 220, 330, 3000);
這裏修改於 frameworks/base/cmds/input/src/com/android/commands/input/Input.java 裏的處理
實現如下:
private void injectMotionEvent(int inputSource, int action, long when, float x, float y, float pressure) {
final float DEFAULT_SIZE = 1.0f;
final int DEFAULT_META_STATE = 0;
final float DEFAULT_PRECISION_X = 1.0f;
final float DEFAULT_PRECISION_Y = 1.0f;
final int DEFAULT_EDGE_FLAGS = 0;
MotionEvent event = MotionEvent.obtain(when, when, action, x, y, pressure, DEFAULT_SIZE,
DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y,
getInputDeviceId(inputSource), DEFAULT_EDGE_FLAGS);
event.setSource(inputSource);
Log.i(TAG, "injectMotionEvent: " + event);
InputManager.getInstance().injectInputEvent(event,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
private int getInputDeviceId(int inputSource) {
final int DEFAULT_DEVICE_ID = 0;
int[] devIds = InputDevice.getDeviceIds();
for (int devId : devIds) {
InputDevice inputDev = InputDevice.getDevice(devId);
if (inputDev.supportsSource(inputSource)) {
return devId;
}
}
return DEFAULT_DEVICE_ID;
}
private void sendLongPress(int inputSource, float x, float y, int duration) {
if (duration < 0) {
duration = 300;
}
long now = SystemClock.uptimeMillis();
injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, x, y, 1.0f);
long startTime = now;
long endTime = startTime + duration;
while (now < endTime) {
// injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, now, x, y, 1.0f);
now = SystemClock.uptimeMillis();
}
injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, x, y, 0.0f);
}
代言人
這樣,戴上耳機,沉浸其中,大吼一聲,多有氣勢
(這個試驗場景是找了一個人機,瞄準好,咳嗽了一聲,左邊的射擊鍵被點擊)
好了,就到這裏,有什麼想法可以留言和我一起討論。