استخدام مكتبة وحدة تحكّم الألعاب

استخدِم الوظائف التالية لإتاحة استخدام ذراع التحكّم في الألعاب إلى لعبتك باستخدام مكتبة "وحدة التحكّم في الألعاب".

تهيئة مكتبة وحدة التحكم في الألعاب وإتلافها

استخدِم الدالة Paddleboat_init لإعداد مكتبة وحدة تحكّم الألعاب.

Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)

تتطلّب الدالة Paddleboat_init مَعلمتَين:

  • مؤشر إلى JNIEnv مرفق بسلسلة التعليمات الحالية
  • يشير إلى عنصر JNI jobject إلى فئة مشتقة من Context. ويكون أي كائن فئة مشتق من Context صالحًا، بما في ذلك على سبيل المثال لا الحصر، Activity أو NativeActivity أو GameActivity.

تعرض دالة Paddleboat_init القيمة PADDLEBOAT_NO_ERROR إذا تمت عملية الإعداد بنجاح، وإلا سيتم عرض رمز خطأ مناسب.

يمكنك استخدام Paddleboat_isInitialized للتحقق مما إذا تم إعداد مكتبة وحدة تحكُّم الألعاب بنجاح. فهي تُرجع قيمة منطقية. إذا كانت القيمة true، تكون واجهة برمجة التطبيقات متاحة للاستخدام.

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 مؤشر اختياري (قد يكون فارغًا) يؤدي إلى البيانات المحدّدة من المستخدم والتي تم تحديدها من خلال آخر طلب استدعاء الدالة Paddleboat_setControllerStatusCallback.

استدعاء وظيفة تحديث مكتبة وحدة التحكم في الألعاب

يجب استدعاء وظيفة تحديث مكتبة وحدة تحكّم الألعاب، Paddleboat_update، مرة واحدة لكل إطار في اللعبة، ويُفضَّل أن يكون ذلك قريبًا من بداية الإطار. تأخذ الدالة معلَمة واحدة، وهي مؤشر إلى JNIEnv مرتبطة بسلسلة المحادثات الحالية.

void Paddleboat_update(JNIEnv *env)

معالجة الأحداث

عند تلقّي أحداث الإدخال، تحتاج لعبتك إلى إعادة توجيهها إلى مكتبة وحدة التحكم في الألعاب لفحصها. تقيِّم مكتبة وحدة تحكُّم الألعاب ما إذا كان حدث إدخال مرتبطًا بأحد أجهزتها المُدارة. تتم معالجة الأحداث من الأجهزة المُدارة واستخدامها.

تتيح مكتبة وحدة تحكّم الألعاب نوعَين من أحداث الإدخال: AInputEvents وحدث إدخال GameActivity.

معالجة AInputEvent

يجب إعادة توجيه اللعبة إلى AInputEvents من خلال طلب الرقم Paddleboat_processInputEvent من رمز التعامل مع الحدث.

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 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 على مجموعة من العلامات الفردية ذات القناع البت وقيم تركيبة وحدات البت المتعددة.

يؤدي إجراء AND منطقي إلى controllerFlags مع PADDLEBOAT_CONTROLLER_LAYOUT_MASK إلى عرض قيمة يمكن تحويلها إلى التعداد 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
};

تحدد الثوابت التالية وحدات بت القدرة. لتحديد ما إذا كانت وحدة التحكّم تتوافق مع إمكانية معيّنة، نفِّذ AND منطقيًا للثابت المقابل في controllerFlags. تعني النتيجة غير الصفرية أن الإمكانية تدعمها وحدة التحكم.

PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD

في حال ضبط وحدة بت العلم هذه، يعني ذلك أنّ وحدة التحكّم تحتوي على لوحة لمس مدمجة. عند الضغط على لوحة اللمس، تضبط وحدة التحكّم وحدة البت PADDLEBOAT_BUTTON_TOUCHPAD في الحقل Paddleboat_Controller_Data.buttonsDown.

PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE

إذا تم تعيين بت العلامة هذا، فإن وحدة التحكم تحاكي جهاز المؤشر. تتم تعبئة العضو virtualPointer في بنية Paddleboat_Controller_Data بالإحداثيات الحالية للمؤشر الافتراضي.

بيانات مسؤول التحكّم بالبيانات

تستخدم الدالة 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 مصفوفة بت لكل زر: يتم تحديد ثابت قناع البت للزر في ملف العنوان paddleboat.h. وتبدأ بـ PADDLEBOAT_BUTTON_.
timestamp. الطابع الزمني لأحدث حدث لإدخال وحدة التحكم. الطابع الزمني بالميكرو ثانية منذ حقبة الساعة.
virtualPointer موقع المؤشر الافتراضي صالحة فقط إذا تم ضبط العلامة PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE في controllerFlags وإلا سيتم ضبط 0.0, 0.0.