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

استخدِم الوظائف التالية لإتاحة استخدام وحدات التحكّم في الألعاب في لعبتك من خلال مكتبة Game Controller.

تهيئة مكتبة Game Controller وإيقافها

استخدِم الدالة Paddleboat_init لإعداد مكتبة Game Controller.

Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)

تتضمّن Paddleboat_init مَعلمتَين:

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

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

يمكنك استخدام Paddleboat_isInitialized للتحقّق مما إذا تم إعداد مكتبة Game Controller بنجاح. تعرض هذه الدالة قيمة منطقية. إذا كانت القيمة صحيحة، تكون واجهة برمجة التطبيقات متاحة للاستخدام.

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)

تسجيل أو إزالة دالة ردّ الاتصال الخاصة بحالة وحدة التحكّم

تستخدِم مكتبة Game Controller برنامج معالجة ردود الاتصال الخاص بحالة وحدة التحكّم لإرسال إشعار إلى إحدى الألعاب عند توصيل وحدة تحكّم أو فصلها. يمكن استخدام ردّ اتصال واحد فقط لحالة وحدة التحكّم في كل مرة.

  • لتسجيل دالة رد اتصال لحالة وحدة التحكّم أو استبدال أي دالة رد اتصال مسجّلة سابقًا بدالة رد اتصال جديدة، استدعِ الدالة 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.

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

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

void Paddleboat_update(JNIEnv *env)

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

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

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

معالجة AInputEvent

يجب أن تعيد لعبتك توجيه AInputEvents من خلال استدعاء Paddleboat_processInputEvent من رمز معالجة الأحداث.

int32_t Paddleboat_processInputEvent(const AInputEvent *event)

ستعرض الدالة Paddleboat_processInputEvent القيمة 0 إذا تم تجاهل الحدث، والقيمة 1 إذا تمت معالجة الحدث واستخدامه من خلال مكتبة Game Controller.

معالجة أحداث 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()

للاطّلاع على مثال حول كيفية التعامل مع ذلك، راجِع نموذج مكتبة Game Controller الذي يستخدم 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;
        }
    }
}

وحدات التحكّم في القراءة

تستخدِم مكتبة Game Controller قيمة فهرس للإشارة إلى وحدة تحكّم معيّنة. تتراوح قيم الفهرس الصالحة من 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.