您可以使用下列函式,透過遊戲控制器程式庫將遊戲控制器支援加入遊戲。
初始化並刪除遊戲控制器程式庫
使用 Paddleboat_init
函式初始化遊戲控制器程式庫。
Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)
Paddleboat_init
會使用兩個參數:
- 指向目前執行緒附加的
JNIEnv
的指標 Context
衍生類別的jobject
JNI 物件參照。任何Context
衍生類別的物件均有效,包括但不限於:Activity
、NativeActivity
、或GameActivity
。
如果初始化成功,Paddleboat_init
會傳回 PADDLEBOAT_NO_ERROR
,否則會傳回適當的錯誤代碼。
您可以使用 Paddleboat_isInitialized
檢查遊戲控制器程式庫是否已成功初始化。它會傳回布林值。如為 true,則可使用 API。
bool Paddleboat_isInitialized()
終止應用程式之前,請先使用 Paddleboat_destroy
函式關閉遊戲控制器程式庫。函式會使用單一參數,並指向目前執行緒附加的 JNIEnv
指標。Paddleboat_init
可能會在 Paddleboat_destroy
後再次呼叫。
void Paddleboat_destroy(JNIEnv *env)
通知生命週期事件資料庫
遊戲控制器程式庫必須隨時掌握活動生命週期onStop
和onStart
事件。在您的停止位置呼叫 Paddleboat_onStop
和 Paddleboat_onStart
函式,然後啟動事件處理程式碼。兩個函式都使用單一參數:指向目前執行緒附加的 JNIEnv
的指標。
void Paddleboat_onStop(JNIEnv *env)
void Paddleboat_onStart(JNIEnv *env)
註冊或移除控制器狀態回呼
遊戲控制器程式庫會在控制器連線或中斷連線時,使用控制器狀態回呼通知遊戲。一次僅支援一個控制器狀態回呼。
- 如要註冊控制器狀態回呼,或以新的回呼函式取代任何先前註冊的回呼,請呼叫
Paddleboat_setControllerStatusCallback
函式。 - 如要移除目前註冊的回呼,請傳遞
NULL
或nullptr
。 userData
參數是使用者定義資料的選用指標。userData
參數會傳遞到回呼函式。這個指標會在內部保留,直到後續呼叫Paddleboat_setControllerStatusCallback
為止。
void Paddleboat_setControllerStatusCallback(Paddleboat_ControllerStatusCallback
statusCallback, void *userData)
回呼函式的函式簽名如下:
typedef void (*Paddleboat_ControllerStatusCallback)(
const int32_t controllerIndex,
const Paddleboat_ControllerStatus controllerStatus,
void *userData)
參數 | 說明 |
---|---|
controllerIndex
|
啟動回呼的控制器索引。這個值必須介於 0 至 PADDLEBOAT_MAX_CONTROLLERS - 1 之間 |
controllerStatus
|
PADDLEBOAT_CONTROLLER_JUST_CONNECTED 或 PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED 的列舉值。 |
userData
|
選用指標 (可能為 NULL),指向上次呼叫 Paddleboat_setControllerStatusCallback 的使用者定義資料。 |
呼叫遊戲控制器程式庫更新函式
遊戲控制器程式庫的更新函式 Paddleboat_update
應在每個遊戲影格中呼叫一次,最好在接近影格開頭處。這個函式會使用單一參數,指向目前執行緒附加的 JNIEnv
指標。
void Paddleboat_update(JNIEnv *env)
處理事件
收到輸入事件時,您的遊戲必須將輸入事件轉送至遊戲控制器程式庫進行檢查。遊戲控制器程式庫會評估輸入事件是否與其管理的任何裝置相關聯。系統會處理受管理裝置的事件,並消耗這類事件。
遊戲控制器程式庫支援兩種輸入事件:AInputEvents
和 GameActivity
輸入事件。
AInputEvent 處理
您的遊戲應透過事件控制代碼呼叫 Paddleboat_processInputEvent
,以轉送 AInputEvents
。
int32_t Paddleboat_processInputEvent(const AInputEvent *event)
如果事件遭到忽略,Paddleboat_processInputEvent
會傳回 0
;如果遊戲控制器程式庫已處理及使用該事件,則會傳回 1
。
GameActivity 事件處理
如果遊戲使用 GameActivity
,請轉寄
GameActivityKeyEvent
和
呼叫 GameActivityMotionEvent
事件
Paddleboat_processGameActivityKeyInputEvent
或
Paddleboat_processGameActivityMotionInputEvent
使用事件處理程式碼呼叫
int32_t Paddleboat_processGameActivityKeyInputEvent(const void *event,
const size_t eventSize)
int32_t Paddleboat_processGameActivityMotionInputEvent(const void *event,
const size_t eventSize)
參數 | 說明 |
---|---|
event
|
指向 GameActivityKeyEvent 或 GameActivityMotionEvent 結構的指標,視呼叫的函式而定。 |
eventSize
|
透過 event 參數傳遞的事件結構大小 (以位元組為單位)。 |
如果事件遭到忽略,則兩個函式都會傳回 0
;如果遊戲控制器程式庫已處理及使用該事件,則會傳回 1
。
GameActivity
要求使用 GameActivityPointerAxes_enableAxis
函式指定使用中的動作軸。而 Paddleboat_getActiveAxisMask
呼叫會傳回已連結控制器目前使用中的動作軸的位元遮罩。
uint64_t Paddleboat_getActiveAxisMask()
如需如何處理此問題的相關範例,請參閱使用 GameActivity
的遊戲控制器程式庫範例。該範例會輪詢使用中的軸遮罩,並在使用新軸時通知 GameActivity
。這可透過 NativeEngine::CheckForNewAxis()
函式實作。
void NativeEngine::CheckForNewAxis() {
// Tell GameActivity about any new axis ids so it reports
// their events
const uint64_t activeAxisIds = Paddleboat_getActiveAxisMask();
uint64_t newAxisIds = activeAxisIds ^ mActiveAxisIds;
if (newAxisIds != 0) {
mActiveAxisIds = activeAxisIds;
int32_t currentAxisId = 0;
while(newAxisIds != 0) {
if ((newAxisIds & 1) != 0) {
LOGD("Enable Axis: %d", currentAxisId);
GameActivityPointerAxes_enableAxis(currentAxisId);
}
++currentAxisId;
newAxisIds >>= 1;
}
}
}
讀取控制器
遊戲控制器程式庫會使用索引值參照特定控制器。有效索引值的範圍從 0
到 PADDLEBOAT_MAX_CONTROLLERS - 1
。
Paddleboat_getControllerStatus
敬上
函式會決定指定控制器索引的狀態。
Paddleboat_ControllerStatus Paddleboat_getControllerStatus(
const int32_t controllerIndex)
您可透過三個函式讀取已連結控制器的資訊。
Paddleboat_getControllerName
函式會擷取控制器裝置的名稱。Paddleboat_getControllerInfo
函式會擷取控制器裝置本身的資料。Paddleboat_getControllerData
函式會擷取控制器輸入的目前狀態。
控制器名稱
Paddleboat_getControllerName function
會接受兩個輸入參數:控制器索引、緩衝區大小,以及用來儲存控制器名稱字串的緩衝區指標。名稱字串的格式為 C 字串,使用 UTF-8 編碼。使用 InputDevice.getName()
會在內部取得裝置名稱。
如果 Paddleboat_getControllerName
成功擷取名稱,則會傳回 PADDLEBOAT_NO_ERROR
,否則會傳回適當的錯誤代碼。
Paddleboat_ErrorCode Paddleboat_getControllerName(const int32_t controllerIndex,
const size_t bufferSize,
char *controllerName);
參數 | 說明 |
---|---|
controllerIndex
|
啟動回呼的控制器索引。這個值必須介於 0 至 PADDLEBOAT_MAX_CONTROLLERS - 1 之間 |
bufferSize
|
由 controllerName 傳送的緩衝區大小 (以位元組為單位),如果需要,名稱字串將被截斷以適合緩衝區大小。 |
controllerName
|
指向 bufferSize 位元組緩衝區的指標,用於儲存控制器名稱。系統會將名稱儲存為 C 字串,並使用 UTF-8 編碼。 |
控制器裝置資訊
Paddleboat_getControllerInfo function
會接受兩個輸入參數:控制器索引和指向 Paddleboat_Controller_Info
結構的指標。
如果 Paddleboat_Controller_Info
已順利填入資料,Paddleboat_getControllerInfo
會傳回 PADDLEBOAT_NO_ERROR
,否則會傳回適當的錯誤代碼。
Paddleboat_ErrorCode Paddleboat_getControllerInfo(const int32_t controllerIndex,
Paddleboat_Controller_Info *controllerInfo)
Paddleboat_Controller_Info
結構包含與該控制器相關的裝置專屬資訊。
typedef struct Paddleboat_Controller_Info {
uint32_t controllerFlags;
int32_t controllerNumber;
int32_t vendorId;
int32_t productId;
int32_t deviceId;
Paddleboat_Controller_Thumbstick_Precision leftStickPrecision;
Paddleboat_Controller_Thumbstick_Precision rightStickPrecision;
} Paddleboat_Controller_Info;
typedef struct Paddleboat_Controller_Thumbstick_Precision {
float stickFlatX;
float stickFlatY;
float stickFuzzX;
float stickFuzzY;
} Paddleboat_Controller_Thumbstick_Precision;
一些結構成員會填入從控制器關聯 InputDevice
中擷取的值:
controllerNumber - InputDevice.getControllerNumber()
vendorId - InputDevice.getVendorId()
productId - InputDevice.getProductId()
deviceId - InputDevice.getId()
stickFlat
值代表中心平坦位置的範圍。這個值主要用於計算自攜式裝置的預設中心「死區」。stickFuzz
值代表錯誤容許值,或是目前值可能會因噪音和裝置敏感度限製而與實際值差距的程度。
兩個值都會按照任一維度正規化為最大軸值 1.0
。
controllerFlags
成員包含個別位元遮罩旗標和多位元組合值的組合。
使用 PADDLEBOAT_CONTROLLER_LAYOUT_MASK
執行 controllerFlags
的邏輯 AND
,會產生一個可投放至 Paddleboat_ControllerButtonLayout
列舉的值。這個列舉值會指定控制器使用的按鈕圖形和版面配置。
enum Paddleboat_ControllerButtonLayout {
// Y
// X B
// A
PADDLEBOAT_CONTROLLER_LAYOUT_STANDARD = 0,
// △
// □ ○
// x
PADDLEBOAT_CONTROLLER_LAYOUT_SHAPES = 1,
// X
// Y A
// B
PADDLEBOAT_CONTROLLER_LAYOUT_REVERSE = 2,
// X Y R1 L1
// A B R2 L2
PADDLEBOAT_CONTROLLER_LAYOUT_ARCADE_STICK = 3,
PADDLEBOAT_CONTROLLER_LAYOUT_MASK = 3
};
下列常數可定義功能位元。如要確定控制器是否支援特定功能,請針對 controllerFlags
執行對應常數的邏輯 AND
。非零的結果表示控制器支援這項功能。
PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD
如果設定了此旗標位元,控制器就會有整合的觸控板。如果按下觸控板,控制器會在 Paddleboat_Controller_Data.buttonsDown
欄位中設定 PADDLEBOAT_BUTTON_TOUCHPAD
位元。
PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE
如果設定了此旗標位元,控制器會模擬指標裝置。Paddleboat_Controller_Data
結構的 virtualPointer
成員會填入虛擬指標目前的座標。
控管器資料
Paddleboat_getControllerData
函式會接受兩個輸入參數:控制器索引和指向 Paddleboat_Controller_Data
結構的指標。如果 Paddleboat_Controller_Data
順利填入資料,Paddleboat_getControllerInfo
會傳回 PADDLEBOAT_NO_ERROR
,否則會傳回適當的錯誤代碼。
Paddleboat_ErrorCode Paddleboat_getControllerData(const int32_t controllerIndex,
Paddleboat_Controller_Data *controllerData)
Paddleboat_Controller_Data
結構包含控制器目前的控制輸入值。
typedef struct Paddleboat_Controller_Data {
uint64_t timestamp;
uint32_t buttonsDown;
Paddleboat_Controller_Thumbstick leftStick;
Paddleboat_Controller_Thumbstick rightStick;
float triggerL1;
float triggerL2;
float triggerR1;
float triggerR2;
Paddleboat_Controller_Pointer virtualPointer;
} Paddleboat_Controller_Data;
typedef struct Paddleboat_Controller_Pointer {
float pointerX;
float pointerY;
} Paddleboat_Controller_Pointer;
typedef struct Paddleboat_Controller_Thumbstick {
float stickX;
float stickY;
} Paddleboat_Controller_Thumbstick;
值範圍
輸入類型 | 值範圍 |
---|---|
指軸 | -1.0 至 1.0 |
觸發事件 | 0.0 至 1.0 |
虛擬指標 | 0.0 至視窗寬度/高度 (單位為像素) |
結構詳細資料
結構成員 | 說明 |
---|---|
buttonsDown
|
Bit-per-button 位元欄位陣列。按鈕位元遮罩常數是在 paddleboat.h 標頭檔案中定義,且開頭為 PADDLEBOAT_BUTTON_ 。 |
timestamp.
|
最近一次控制器輸入事件的時間戳記。時間戳記是自時鐘 Epoch 時間起算的微秒時間。 |
virtualPointer
|
虛擬指標位置。只有在 controllerFlags 中設定 PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE 旗標時,才有效,否則為 0.0, 0.0 。 |