Aby dodać do gry obsługę kontrolera za pomocą biblioteki Game Controller, użyj tych funkcji.
Inicjowanie i niszczenie biblioteki Game Controller
Użyj funkcji Paddleboat_init
, aby zainicjować bibliotekę Game Controller.
Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)
Paddleboat_init
przyjmuje 2 parametry:
- Wskaźnik do
JNIEnv
dołączonego do bieżącego wątku - Odwołanie do obiektu JNI
jobject
do klasy pochodnejContext
. Każdy obiekt klasy pochodnejContext
jest prawidłowy, w tym m.in.Activity
,NativeActivity
iGameActivity
.
Paddleboat_init
zwraca
PADDLEBOAT_NO_ERROR
, jeśli inicjowanie się powiodło, w przeciwnym razie zwracany jest odpowiedni kod błędu.
Możesz użyć Paddleboat_isInitialized
, aby sprawdzić, czy biblioteka GameController została prawidłowo zainicjowana. Zwraca wartość logiczną. Jeśli ma wartość Prawda, interfejs API jest dostępny.
bool Paddleboat_isInitialized()
Przed zakończeniem działania aplikacji użyj funkcji
Paddleboat_destroy
do zamknięcia biblioteki Game Controller. Funkcja przyjmuje jeden parametr, wskaźnik do JNIEnv
dołączonego do bieżącego wątku.
Paddleboat_init
może ponownie zadzwonić po Paddleboat_destroy
.
void Paddleboat_destroy(JNIEnv *env)
Informowanie biblioteki o zdarzeniach cyklu życia
Biblioteka Game Controller musi być informowana o cyklu życia aktywności
onStop
i onStart
zdarzeniach.
Wywołaj funkcje Paddleboat_onStop
i Paddleboat_onStart
w kodzie obsługi zdarzeń zatrzymania i rozpoczęcia. Obie funkcje przyjmują jeden parametr: wskaźnik do obiektu JNIEnv
dołączonego do bieżącego wątku.
void Paddleboat_onStop(JNIEnv *env)
void Paddleboat_onStart(JNIEnv *env)
Rejestrowanie lub usuwanie wywołania zwrotnego stanu kontrolera
Biblioteka Game Controller używa wywołania zwrotnego stanu kontrolera, aby powiadamiać grę o podłączeniu lub odłączeniu kontrolera. Obsługuje tylko 1 wywołanie zwrotne stanu kontrolera naraz.
- Aby zarejestrować wywołanie zwrotne stanu kontrolera lub zastąpić wcześniej zarejestrowane wywołanie zwrotne nową funkcją wywołania zwrotnego, wywołaj funkcję
Paddleboat_setControllerStatusCallback
. - Aby usunąć zarejestrowane wywołanie zwrotne, przekaż wartość
NULL
lubnullptr
. - Parametr
userData
jest opcjonalnym wskaźnikiem danych zdefiniowanych przez użytkownika. ParametruserData
zostanie przekazany do funkcji wywołania zwrotnego. Ten wskaźnik jest przechowywany wewnętrznie do czasu zmiany przez kolejne wywołanie funkcjiPaddleboat_setControllerStatusCallback
.
void Paddleboat_setControllerStatusCallback(Paddleboat_ControllerStatusCallback
statusCallback, void *userData)
Podpis funkcji wywołania zwrotnego jest następujący:
typedef void (*Paddleboat_ControllerStatusCallback)(
const int32_t controllerIndex,
const Paddleboat_ControllerStatus controllerStatus,
void *userData)
Parametr | Opis |
---|---|
controllerIndex
|
Indeks kontrolera, który zainicjował wywołanie zwrotne. Wartość z zakresu od 0 do . PADDLEBOAT_MAX_CONTROLLERS - 1 |
controllerStatus
|
Wartość typu wyliczeniowego PADDLEBOAT_CONTROLLER_JUST_CONNECTED lub PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED . |
userData
|
Opcjonalny wskaźnik (może mieć wartość NULL) do danych zdefiniowanych przez użytkownika, określonych w ostatnim wywołaniu funkcji Paddleboat_setControllerStatusCallback . |
Wywołanie funkcji aktualizacji biblioteki Game Controller
Funkcję aktualizacji biblioteki Game Controller,Paddleboat_update
należy wywoływać raz na klatkę gry, najlepiej na początku klatki.
Funkcja przyjmuje jeden parametr, wskaźnik do JNIEnv
dołączonego do bieżącego wątku.
void Paddleboat_update(JNIEnv *env)
Przetwarzanie zdarzeń
Gdy gra otrzymuje zdarzenia wejściowe, musi przekazywać je do biblioteki Game Controller w celu sprawdzenia. Biblioteka Game Controller sprawdza, czy zdarzenie wejściowe jest powiązane z jednym z zarządzanych urządzeń. Zdarzenia z urządzeń zarządzanych są przetwarzane i wykorzystywane.
Biblioteka Game Controller obsługuje 2 rodzaje zdarzeń wejściowych: AInputEvents
i GameActivity
.
Przetwarzanie AInputEvent
Gra powinna przekazywać wartość AInputEvents
, wywołując funkcję Paddleboat_processInputEvent
w kodzie obsługi zdarzeń.
int32_t Paddleboat_processInputEvent(const AInputEvent *event)
Paddleboat_processInputEvent
zwróci wartość 0
, jeśli zdarzenie zostało zignorowane, i 1
, jeśli zostało przetworzone i wykorzystane przez bibliotekę Game Controller.
Przetwarzanie zdarzeń GameActivity
Jeśli Twoja gra korzysta z GameActivity
, przekazuj zdarzenia
GameActivityKeyEvent
i
GameActivityMotionEvent
, wywołując
Paddleboat_processGameActivityKeyInputEvent
lub
Paddleboat_processGameActivityMotionInputEvent
z kodu obsługi zdarzeń.
int32_t Paddleboat_processGameActivityKeyInputEvent(const void *event,
const size_t eventSize)
int32_t Paddleboat_processGameActivityMotionInputEvent(const void *event,
const size_t eventSize)
Parametr | Opis |
---|---|
event
|
Wskaźnik do struktury GameActivityKeyEvent lub GameActivityMotionEvent , w zależności od wywoływanej funkcji. |
eventSize
|
Rozmiar w bajtach struktury zdarzenia przekazanej w parametrze event . |
Obie funkcje zwracają wartość 0
, jeśli zdarzenie zostało zignorowane, i 1
, jeśli zostało przetworzone i wykorzystane przez bibliotekę Game Controller.
GameActivity
wymaga określenia aktywnej osi ruchu za pomocą funkcji GameActivityPointerAxes_enableAxis
. Wywołanie
Paddleboat_getActiveAxisMask
zwraca maskę bitową obecnie aktywnych osi ruchu używanych przez podłączone kontrolery.
uint64_t Paddleboat_getActiveAxisMask()
Przykład obsługi tego problemu znajdziesz w przykładzie biblioteki Game Controller, która korzysta z GameActivity
. Przykładowy kod odpytuje maskę aktywnej osi i informuje,GameActivity
kiedy używane są nowe osie. Jest to zaimplementowane w funkcji 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;
}
}
}
Odczytywanie kontrolerów
Biblioteka Game Controller używa wartości indeksu do odwoływania się do konkretnego kontrolera. Prawidłowe wartości indeksu mieszczą się w zakresie od 0
do PADDLEBOAT_MAX_CONTROLLERS - 1
. Funkcja
Paddleboat_getControllerStatus
określa stan określonego indeksu kontrolera.
Paddleboat_ControllerStatus Paddleboat_getControllerStatus(
const int32_t controllerIndex)
Istnieją 3 funkcje odczytywania informacji z podłączonego kontrolera.
- Funkcja
Paddleboat_getControllerName
pobiera nazwę urządzenia sterującego. - Funkcja
Paddleboat_getControllerInfo
pobiera dane o samym urządzeniu sterującym. - Funkcja
Paddleboat_getControllerData
pobiera bieżący stan danych wejściowych kontrolera.
Nazwa kontrolera
Funkcja Paddleboat_getControllerName function
przyjmuje 2 parametry wejściowe: indeks kontrolera, rozmiar bufora i wskaźnik do bufora, w którym ma być przechowywany ciąg znaków z nazwą kontrolera. Ciąg znaków nazwy jest sformatowany jako ciąg znaków C z użyciem kodowania UTF-8. Nazwa urządzenia jest uzyskiwana wewnętrznie za pomocą funkcji InputDevice.getName()
.
Jeśli funkcja Paddleboat_getControllerName
prawidłowo pobierze nazwę, zwróci wartość PADDLEBOAT_NO_ERROR
. W przeciwnym razie zwróci odpowiedni kod błędu.
Paddleboat_ErrorCode Paddleboat_getControllerName(const int32_t controllerIndex,
const size_t bufferSize,
char *controllerName);
Parametr | Opis |
---|---|
controllerIndex
|
Indeks kontrolera, który zainicjował wywołanie zwrotne. Wartość z zakresu od 0 do . PADDLEBOAT_MAX_CONTROLLERS - 1 |
bufferSize
|
Rozmiar w bajtach bufora przekazanego przez
controllerName . W razie potrzeby ciąg nazwy zostanie obcięty, aby zmieścił się w buforze. |
controllerName
|
Wskaźnik do bufora o rozmiarze bufferSize bajtów, w którym będzie przechowywana nazwa kontrolera. Nazwa będzie przechowywana jako ciąg znaków C z kodowaniem UTF-8. |
Informacje o urządzeniu sterującym
Funkcja Paddleboat_getControllerInfo function
przyjmuje 2 parametry wejściowe: indeks kontrolera i wskaźnik struktury Paddleboat_Controller_Info
.
Jeśli funkcja Paddleboat_Controller_Info
została wypełniona danymi,
Paddleboat_getControllerInfo
zwraca PADDLEBOAT_NO_ERROR
, w przeciwnym razie zwracany jest odpowiedni kod błędu.
Paddleboat_ErrorCode Paddleboat_getControllerInfo(const int32_t controllerIndex,
Paddleboat_Controller_Info *controllerInfo)
Struktura Paddleboat_Controller_Info
zawiera informacje o kontrolerze dotyczące konkretnego urządzenia.
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;
Kilka elementów struktury jest wypełnianych wartościami pobranymi z InputDevice
powiązanego z kontrolerem:
controllerNumber - InputDevice.getControllerNumber()
vendorId - InputDevice.getVendorId()
productId - InputDevice.getProductId()
deviceId - InputDevice.getId()
- Wartość
stickFlat
reprezentuje zakres pozycji środkowej. Ta wartość jest przydatna głównie do obliczania domyślnej strefy martwej na środku urządzeń samocentrujących. - Wartość
stickFuzz
reprezentuje tolerancję błędu, czyli jak bardzo bieżąca wartość może odbiegać od rzeczywistej wartości z powodu szumu i ograniczeń czułości urządzenia.
Obie wartości są normalizowane do maksymalnej wartości osi 1.0
w każdym wymiarze.
Element controllerFlags
zawiera kombinację poszczególnych flag z maską bitową i wartości kombinacji wielobitowych.
Wykonanie logicznej operacji AND
na wartości controllerFlags
z wartością PADDLEBOAT_CONTROLLER_LAYOUT_MASK
daje w rezultacie wartość, którą można przekształcić w wyliczenie Paddleboat_ControllerButtonLayout
. Ten wyliczenie określa ikonografię i układ przycisków używane przez kontroler.
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
};
Stałe poniżej definiują bity możliwości. Aby sprawdzić, czy kontroler obsługuje daną funkcję, wykonaj logiczną operację AND
na odpowiedniej stałej i wartości controllerFlags
. Wynik różny od zera oznacza, że kontroler obsługuje tę funkcję.
PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD
Jeśli ten bit flagi jest ustawiony, kontroler ma zintegrowany touchpad. Jeśli naciśniesz panel dotykowy, kontroler ustawi bit PADDLEBOAT_BUTTON_TOUCHPAD
w polu Paddleboat_Controller_Data.buttonsDown
.
PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE
Jeśli ten bit flagi jest ustawiony, kontroler emuluje urządzenie wskazujące. Element virtualPointer
struktury Paddleboat_Controller_Data
jest wypełniany bieżącymi współrzędnymi wskaźnika wirtualnego.
Dane kontrolera
Funkcja Paddleboat_getControllerData
przyjmuje 2 parametry wejściowe: indeks kontrolera i wskaźnik struktury Paddleboat_Controller_Data
. Jeśli zmienna Paddleboat_Controller_Data
zostanie wypełniona danymi, funkcja Paddleboat_getControllerInfo
zwróci wartość PADDLEBOAT_NO_ERROR
. W przeciwnym razie zwrócony zostanie odpowiedni kod błędu.
Paddleboat_ErrorCode Paddleboat_getControllerData(const int32_t controllerIndex,
Paddleboat_Controller_Data *controllerData)
Struktura Paddleboat_Controller_Data
zawiera aktualne wartości wejściowe kontrolera.
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;
Zakresy wartości
Typ danych wejściowych | Zakres wartości |
---|---|
Oś drążka | Od -1.0 do 1.0 |
Aktywatory | Od 0.0 do 1.0 |
Wskaźniki wirtualne | 0.0 do szerokości/wysokości okna (w pikselach) |
Szczegóły struktury
Członek struktury | Opis |
---|---|
buttonsDown
|
Tablica pól bitowych typu „bit na przycisk”. Stałe maski bitowe przycisków są zdefiniowane w pliku nagłówkowym paddleboat.h i zaczynają się od znaku PADDLEBOAT_BUTTON_ . |
timestamp.
|
Sygnatura czasowa ostatniego zdarzenia wejścia kontrolera. Sygnatura czasowa jest wyrażona w mikrosekundach od początku epoki zegara. |
virtualPointer
|
Lokalizacja wskaźnika wirtualnego. Obowiązuje tylko wtedy, gdy w parametrze controllerFlags ustawiona jest flaga PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE . W przeciwnym razie będzie to 0.0, 0.0 . |