Mit den folgenden Funktionen können Sie Ihrem Spiel mithilfe der Game Controller-Bibliothek Unterstützung für Gamecontroller hinzufügen.
Game Controller-Bibliothek initialisieren und zerstören
Verwenden Sie die Funktion Paddleboat_init
, um die Game Controller-Bibliothek zu initialisieren.
Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)
Paddleboat_init
hat zwei Parameter:
- Ein Zeiger auf ein
JNIEnv
, das an den aktuellen Thread angehängt ist - Eine
jobject
-JNI-Objektreferenz zu einer abgeleiteten Klasse vom TypContext
. Ein beliebigesContext
-abgeleitetes Klassenobjekt ist gültig, einschließlich, aber nicht beschränkt aufActivity
,NativeActivity
oderGameActivity
.
Paddleboat_init
gibt PADDLEBOAT_NO_ERROR
zurück, wenn die Initialisierung erfolgreich war. Andernfalls wird ein entsprechender Fehlercode zurückgegeben.
Mit Paddleboat_isInitialized
kannst du prüfen, ob die Game Controller-Bibliothek erfolgreich initialisiert wurde. Sie gibt einen booleschen Wert zurück. Bei „true“ ist die API verfügbar.
bool Paddleboat_isInitialized()
Verwenden Sie vor dem Beenden der Anwendung die Funktion Paddleboat_destroy
, um die Game Controller-Bibliothek zu schließen. Die Funktion verwendet einen einzelnen Parameter, einen Zeiger auf ein JNIEnv
, das an den aktuellen Thread angehängt ist.
Paddleboat_init
kann nach Paddleboat_destroy
noch einmal aufgerufen werden.
void Paddleboat_destroy(JNIEnv *env)
Bibliothek über Lebenszyklusereignisse informieren
Die Game Controller-Bibliothek muss über Aktivitätslebenszyklus-onStop
- und onStart
-Ereignisse informiert werden.
Rufen Sie die Funktionen Paddleboat_onStop
und Paddleboat_onStart
aus dem Code für die Verarbeitung von Stopp- und Startereignissen auf. Beide Funktionen verwenden einen einzelnen Parameter: einen Zeiger auf ein JNIEnv
, das an den aktuellen Thread angehängt ist.
void Paddleboat_onStop(JNIEnv *env)
void Paddleboat_onStart(JNIEnv *env)
Controller-Status-Callback registrieren oder entfernen
Die Game Controller-Bibliothek verwendet einen Controller-Status-Callback, um ein Spiel zu benachrichtigen, wenn ein Controller verbunden oder getrennt wird. Es wird jeweils nur ein Controller-Status-Callback unterstützt.
- Wenn Sie einen Callback für den Controllerstatus registrieren oder einen zuvor registrierten Callback durch eine neue Callback-Funktion ersetzen möchten, rufen Sie die Funktion
Paddleboat_setControllerStatusCallback
auf. - Wenn Sie einen aktuell registrierten Callback entfernen möchten, übergeben Sie
NULL
odernullptr
. - Der Parameter
userData
ist ein optionaler Zeiger auf benutzerdefinierte Daten. Der ParameteruserData
wird an die Callback-Funktion übergeben. Dieser Zeiger wird intern beibehalten, bis er durch einen nachfolgenden Aufruf vonPaddleboat_setControllerStatusCallback
geändert wird.
void Paddleboat_setControllerStatusCallback(Paddleboat_ControllerStatusCallback
statusCallback, void *userData)
Die Funktionssignatur der Callback-Funktion lautet:
typedef void (*Paddleboat_ControllerStatusCallback)(
const int32_t controllerIndex,
const Paddleboat_ControllerStatus controllerStatus,
void *userData)
Parameter | Beschreibung |
---|---|
controllerIndex
|
Index des Controllers, der den Callback initiiert hat. Muss ein Wert zwischen 0 und sein. PADDLEBOAT_MAX_CONTROLLERS - 1 |
controllerStatus
|
Enum-Wert von
PADDLEBOAT_CONTROLLER_JUST_CONNECTED oder PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED . |
userData
|
Ein optionaler Zeiger (kann NULL sein) auf benutzerdefinierte Daten, die beim letzten Aufruf von Paddleboat_setControllerStatusCallback angegeben wurden. |
Funktion zum Aktualisieren der Gamecontroller-Bibliothek aufrufen
Die Update-Funktion der Game Controller-Bibliothek, Paddleboat_update
, sollte einmal pro Frame aufgerufen werden, vorzugsweise am Anfang des Frames.
Die Funktion verwendet einen einzelnen Parameter, einen Zeiger auf ein JNIEnv
, das an den aktuellen Thread angehängt ist.
void Paddleboat_update(JNIEnv *env)
Ereignisse verarbeiten
Wenn Ihr Spiel Eingabeereignisse empfängt, muss es diese zur Überprüfung an die Game Controller-Bibliothek weiterleiten. Die Game Controller-Bibliothek prüft, ob ein Eingabeereignis mit einem der verwalteten Geräte verknüpft ist. Ereignisse von verwalteten Geräten werden verarbeitet und genutzt.
Die Game Controller-Bibliothek unterstützt zwei Arten von Eingabeereignissen: AInputEvents
- und GameActivity
-Eingabeereignisse.
AInputEvent-Verarbeitung
Dein Spiel sollte AInputEvents
weiterleiten, indem es Paddleboat_processInputEvent
aus deinem Event-Handling-Code aufruft.
int32_t Paddleboat_processInputEvent(const AInputEvent *event)
Paddleboat_processInputEvent
gibt 0
zurück, wenn das Ereignis ignoriert wurde, und 1
, wenn das Ereignis von der Game Controller-Bibliothek verarbeitet und genutzt wurde.
GameActivity-Ereignisverarbeitung
Wenn in Ihrem Spiel GameActivity
verwendet wird, leiten Sie GameActivityKeyEvent
- und GameActivityMotionEvent
-Ereignisse weiter, indem Sie Paddleboat_processGameActivityKeyInputEvent
oder Paddleboat_processGameActivityMotionInputEvent
aus Ihrem Ereignisbehandlungscode aufrufen.
int32_t Paddleboat_processGameActivityKeyInputEvent(const void *event,
const size_t eventSize)
int32_t Paddleboat_processGameActivityMotionInputEvent(const void *event,
const size_t eventSize)
Parameter | Beschreibung |
---|---|
event
|
Ein Zeiger auf eine GameActivityKeyEvent - oder GameActivityMotionEvent -Struktur, je nachdem, welche Funktion aufgerufen wird. |
eventSize
|
Die Größe der Ereignisstruktur in Byte, die im Parameter event übergeben wird. |
Beide Funktionen geben 0
zurück, wenn das Ereignis ignoriert wurde, und 1
, wenn das Ereignis von der Game Controller-Bibliothek verarbeitet und genutzt wurde.
Für GameActivity
muss die aktive Bewegungsachse mit der Funktion GameActivityPointerAxes_enableAxis
angegeben werden. Der Aufruf Paddleboat_getActiveAxisMask
gibt eine Bitmaske der derzeit aktiven Bewegungsachsen zurück, die von verbundenen Controllern verwendet werden.
uint64_t Paddleboat_getActiveAxisMask()
Ein Beispiel für die Verarbeitung dieses Problems finden Sie im Game Controller-Bibliotheksbeispiel, in dem GameActivity
verwendet wird. Das Beispiel fragt die aktive Achsenmaske ab und informiert GameActivity
, wenn neue Achsen verwendet werden. Dies wird in der Funktion NativeEngine::CheckForNewAxis()
implementiert.
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;
}
}
}
Controller lesen
In der Game Controller-Bibliothek wird ein Indexwert verwendet, um auf einen bestimmten Controller zu verweisen. Gültige Indexwerte reichen von 0
bis PADDLEBOAT_MAX_CONTROLLERS - 1
. Die Funktion
Paddleboat_getControllerStatus
> ermittelt den Status eines angegebenen Controller-Index.
Paddleboat_ControllerStatus Paddleboat_getControllerStatus(
const int32_t controllerIndex)
Es gibt drei Funktionen zum Lesen von Informationen von einem verbundenen Controller.
- Die Funktion
Paddleboat_getControllerName
ruft den Namen des Steuergeräts ab. - Mit der Funktion
Paddleboat_getControllerInfo
werden Daten zum Controllergerät selbst abgerufen. - Die Funktion
Paddleboat_getControllerData
ruft den aktuellen Status der Controllereingaben ab.
Controller name
Die Funktion Paddleboat_getControllerName function
akzeptiert drei Eingabeparameter: einen Controller-Index, eine Puffergröße und einen Zeiger auf einen Puffer, in dem der Controller-Name gespeichert werden soll. Der Namensstring ist als C-String mit UTF-8-Codierung formatiert. Der Name des Geräts wird intern mit InputDevice.getName()
abgerufen.
Wenn Paddleboat_getControllerName
den Namen erfolgreich abruft, wird PADDLEBOAT_NO_ERROR
zurückgegeben. Andernfalls wird ein entsprechender Fehlercode zurückgegeben.
Paddleboat_ErrorCode Paddleboat_getControllerName(const int32_t controllerIndex,
const size_t bufferSize,
char *controllerName);
Parameter | Beschreibung |
---|---|
controllerIndex
|
Index des Controllers, der den Callback initiiert hat. Muss ein Wert zwischen 0 und sein. PADDLEBOAT_MAX_CONTROLLERS - 1 |
bufferSize
|
Größe des von controllerName übergebenen Puffers in Byte. Der Namensstring wird bei Bedarf gekürzt, damit er in den Puffer passt. |
controllerName
|
Ein Zeiger auf einen Puffer mit bufferSize Bytes, in dem der Controllername gespeichert werden soll. Der Name wird als C-String mit UTF-8-Codierung gespeichert. |
Informationen zum Controller-Gerät
Für Paddleboat_getControllerInfo function
sind zwei Eingabeparameter erforderlich: ein Controller-Index und ein Zeiger auf eine Paddleboat_Controller_Info
-Struktur.
Wenn Paddleboat_Controller_Info
erfolgreich mit Daten gefüllt wurde, gibt Paddleboat_getControllerInfo
den Wert PADDLEBOAT_NO_ERROR
zurück. Andernfalls wird ein entsprechender Fehlercode zurückgegeben.
Paddleboat_ErrorCode Paddleboat_getControllerInfo(const int32_t controllerIndex,
Paddleboat_Controller_Info *controllerInfo)
Die Paddleboat_Controller_Info
-Struktur enthält gerätespezifische Informationen zum Controller.
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;
Mehrere Strukturmember werden mit Werten gefüllt, die aus dem InputDevice
stammen, das dem Controller zugeordnet ist:
controllerNumber - InputDevice.getControllerNumber()
vendorId - InputDevice.getVendorId()
productId - InputDevice.getProductId()
deviceId - InputDevice.getId()
- Ein
stickFlat
-Wert gibt die Ausdehnung einer mittigen flachen Position an. Dieser Wert ist hauptsächlich nützlich, um eine standardmäßige „Totzone“ in der Mitte von selbstzentrierenden Geräten zu berechnen. - Ein
stickFuzz
-Wert gibt die Fehlertoleranz an, also wie weit der aktuelle Wert aufgrund von Rauschen und Einschränkungen der Gerätesensitivität vom tatsächlichen Wert abweichen darf.
Beide Werte werden auf einen maximalen Achsenwert von 1.0
in beiden Dimensionen normalisiert.
Das controllerFlags
-Element enthält eine Kombination aus einzelnen bitmaskierten Flags und Mehrbit-Kombinationswerten.
Wenn Sie eine logische AND
von controllerFlags
mit PADDLEBOAT_CONTROLLER_LAYOUT_MASK
ausführen, erhalten Sie einen Wert, der in die Paddleboat_ControllerButtonLayout
-Enumeration umgewandelt werden kann. Diese Enumeration gibt die Symbolgrafik und das Layout der Schaltflächen an, die vom Controller verwendet werden.
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
};
Die folgenden Konstanten definieren Capability-Bits. Um festzustellen, ob ein Controller eine bestimmte Funktion unterstützt, führen Sie eine logische AND
der entsprechenden Konstante mit controllerFlags
aus. Ein Ergebnis ungleich null bedeutet, dass die Funktion vom Controller unterstützt wird.
PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD
Wenn dieses Flag-Bit gesetzt ist, hat der Controller ein integriertes Touchpad. Wenn das Touchpad gedrückt wird, legt der Controller das PADDLEBOAT_BUTTON_TOUCHPAD
-Bit im Feld Paddleboat_Controller_Data.buttonsDown
fest.
PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE
Wenn dieses Flag-Bit gesetzt ist, emuliert der Controller ein Zeigergerät. Das virtualPointer
-Element der Paddleboat_Controller_Data
-Struktur wird mit den aktuellen Koordinaten des virtuellen Zeigers gefüllt.
Controller-Daten
Die Funktion Paddleboat_getControllerData
verwendet zwei Eingabeparameter: einen Controller-Index und einen Zeiger auf eine Paddleboat_Controller_Data
-Struktur. Wenn Paddleboat_Controller_Data
erfolgreich mit Daten gefüllt wird, gibt Paddleboat_getControllerInfo
den Wert PADDLEBOAT_NO_ERROR
zurück. Andernfalls wird ein entsprechender Fehlercode zurückgegeben.
Paddleboat_ErrorCode Paddleboat_getControllerData(const int32_t controllerIndex,
Paddleboat_Controller_Data *controllerData)
Die Paddleboat_Controller_Data
-Struktur enthält die aktuellen Steuereingabewerte des Controllers.
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;
Wertebereiche
Eingabetyp | Wertebereich |
---|---|
Thumbstick-Achse | -1.0 bis 1.0 |
Auslöser | 0.0 bis 1.0 |
Virtuelle Zeiger | 0.0 bis Fensterbreite/-höhe (in Pixeln) |
Gebäudedetails
Gebäudemitglied | Beschreibung |
---|---|
buttonsDown
|
Bitfeld-Array für Bits pro Schaltfläche. Konstanten für die Schaltflächen-Bitmaske sind in der Headerdatei paddleboat.h definiert und beginnen mit PADDLEBOAT_BUTTON_ . |
timestamp.
|
Zeitstempel des letzten Controller-Eingabeereignisses. Der Zeitstempel wird in Mikrosekunden seit der Uhren-Epoche angegeben. |
virtualPointer
|
Virtuelle Zeigerposition. Nur gültig, wenn das Flag PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE in controllerFlags festgelegt ist. Andernfalls ist der Wert 0.0, 0.0 . |