از کتابخانه Game Controller استفاده کنید

از توابع زیر برای اضافه کردن پشتیبانی از کنترلر بازی به بازی خود با استفاده از کتابخانه 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 با موفقیت مقداردهی اولیه شده است. یک مقدار بولی برمی گرداند. اگر درست باشد، API برای استفاده در دسترس است.

bool Paddleboat_isInitialized()

قبل از خاتمه برنامه، از تابع Paddleboat_destroy برای خاموش کردن کتابخانه Game Controller استفاده کنید. تابع یک پارامتر واحد می گیرد، یک اشاره گر به JNIEnv متصل به رشته فعلی. Paddleboat_init ممکن است پس از Paddleboat_destroy دوباره فراخوانی شود.

void Paddleboat_destroy(JNIEnv *env)

کتابخانه را از رویدادهای چرخه حیات مطلع کنید

کتابخانه Game Controller باید از چرخه حیات فعالیت 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 به تابع callback ارسال می شود. این اشاره گر به صورت داخلی حفظ می شود تا زمانی که با فراخوانی بعدی به Paddleboat_setControllerStatusCallback تغییر یابد.
void Paddleboat_setControllerStatusCallback(Paddleboat_ControllerStatusCallback
  statusCallback, void *userData)

امضای تابع تابع callback عبارت است از:

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 را فراخوانی کنید

تابع به‌روزرسانی کتابخانه کنترلر بازی، 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 و اگر رویداد توسط کتابخانه Game Controller پردازش و مصرف شود، 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 و اگر رویداد توسط کتابخانه Game Controller پردازش و مصرف شود، 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 خواهد بود.