ใช้ไลบรารีเกมคอนโทรลเลอร์

ใช้ฟังก์ชันต่อไปนี้เพื่อเพิ่มการรองรับตัวควบคุมเกมลงในเกมโดยใช้ ไลบรารีตัวควบคุมเกม

เริ่มต้นและทำลายไลบรารี Game Controller

ใช้ฟังก์ชัน Paddleboat_init เพื่อเริ่มต้นไลบรารีตัวควบคุมเกม

Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)

Paddleboat_init ใช้พารามิเตอร์ 2 ตัวดังนี้

  • ตัวชี้ไปยัง 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)

แจ้งให้ห้องสมุดทราบถึงเหตุการณ์ในวงจรของรายการ

ต้องแจ้งให้ทราบถึงไลบรารีตัวควบคุมเกมเกี่ยวกับ วงจรกิจกรรม onStop และ onStart เรียกใช้ฟังก์ชัน Paddleboat_onStop และ Paddleboat_onStart จากโค้ดการจัดการเหตุการณ์หยุดและเริ่ม ฟังก์ชันทั้งสองจะใช้พารามิเตอร์เดียวคือพอยน์เตอร์ไปยัง JNIEnv ที่แนบมากับเธรดปัจจุบัน

void Paddleboat_onStop(JNIEnv *env)
void Paddleboat_onStart(JNIEnv *env)

ลงทะเบียนหรือนำการเรียกกลับสถานะของตัวควบคุมออก

ไลบรารีตัวควบคุมเกมใช้การเรียกกลับสถานะตัวควบคุมเพื่อแจ้งให้เกมทราบ เมื่อมีการเชื่อมต่อหรือยกเลิกการเชื่อมต่อตัวควบคุม โดยจะรองรับการเรียกกลับสถานะของตัวควบคุมได้ครั้งละ 1 รายการเท่านั้น

  • หากต้องการลงทะเบียนการเรียกกลับสถานะของตัวควบคุมหรือแทนที่การเรียกกลับที่ลงทะเบียนไว้ก่อนหน้านี้ ด้วยฟังก์ชันการเรียกกลับใหม่ ให้เรียกใช้ฟังก์ชัน 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 ค่า enum ของ PADDLEBOAT_CONTROLLER_JUST_CONNECTED หรือ
PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED
userData พอยน์เตอร์ที่ไม่บังคับ (อาจเป็น NULL) ไปยังข้อมูลที่ผู้ใช้ กำหนดซึ่งระบุโดยการเรียกใช้ครั้งล่าสุดไปยัง Paddleboat_setControllerStatusCallback

เรียกฟังก์ชันอัปเดตไลบรารีเกมคอนโทรลเลอร์

ควรเรียกใช้ฟังก์ชันอัปเดตไลบรารี Game Controller Paddleboat_update 1 ครั้งต่อเฟรมเกม โดยควรเรียกใช้ใกล้กับจุดเริ่มต้นของเฟรม ฟังก์ชันนี้ใช้พารามิเตอร์เดียว ซึ่งเป็นตัวชี้ไปยัง JNIEnv ที่แนบมากับ เธรดปัจจุบัน

void Paddleboat_update(JNIEnv *env)

ประมวลผลเหตุการณ์

เมื่อได้รับเหตุการณ์อินพุต เกมของคุณต้อง ส่งต่อเหตุการณ์เหล่านั้นไปยังไลบรารีอุปกรณ์ควบคุมเกมเพื่อตรวจสอบ ไลบรารี Game Controller จะประเมินว่าเหตุการณ์อินพุตเชื่อมโยงกับอุปกรณ์ที่มีการจัดการ เครื่องใดเครื่องหนึ่งหรือไม่ ระบบจะประมวลผลและใช้เหตุการณ์จากอุปกรณ์ที่มีการจัดการ

ไลบรารี Game Controller รองรับเหตุการณ์อินพุต 2 ประเภท ได้แก่ เหตุการณ์อินพุต 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

ทั้ง 2 ฟังก์ชันจะแสดงผล 0 หากระบบไม่สนใจเหตุการณ์ และ 1 หากไลบรารี Game Controller ประมวลผลและใช้เหตุการณ์

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)

มีฟังก์ชัน 3 อย่างสำหรับการอ่านข้อมูลจากคอนโทรลเลอร์ที่เชื่อมต่อ

  • ฟังก์ชัน Paddleboat_getControllerName จะดึงชื่อของอุปกรณ์ควบคุม
  • ฟังก์ชัน Paddleboat_getControllerInfo จะดึงข้อมูลเกี่ยวกับอุปกรณ์ควบคุมเอง
  • ฟังก์ชัน Paddleboat_getControllerData จะเรียกสถานะปัจจุบันของอินพุตของคอนโทรลเลอร์

ชื่อตัวควบคุม

Paddleboat_getControllerName function ใช้พารามิเตอร์อินพุต 2 รายการ ได้แก่ ดัชนีคอนโทรลเลอร์ ขนาดบัฟเฟอร์ และพอยน์เตอร์ไปยัง บัฟเฟอร์เพื่อจัดเก็บสตริงชื่อคอนโทรลเลอร์ สตริงชื่อจะจัดรูปแบบเป็นสตริง 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 ใช้พารามิเตอร์อินพุต 2 ตัว ได้แก่ ดัชนีของ คอนโทรลเลอร์และพอยน์เตอร์ไปยังโครงสร้าง 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 ที่เชื่อมโยงกับ คอนโทรลเลอร์ลงในสมาชิก struct หลายรายการ

controllerNumber    -   InputDevice.getControllerNumber()
vendorId              - InputDevice.getVendorId()
productId             - InputDevice.getProductId()
deviceId              - InputDevice.getId()
  • stickFlat ค่าแสดงถึงขอบเขตของตำแหน่งที่อยู่ตรงกลาง ค่านี้มีประโยชน์หลักๆ ในการคำนวณ "เดดโซน" ตรงกลางเริ่มต้นใน อุปกรณ์ที่ปรับศูนย์ด้วยตัวเอง
  • ค่า stickFuzz แสดงถึงค่าความคลาดเคลื่อน หรือค่าปัจจุบันอาจเบี่ยงเบนจากค่าจริงมากน้อยเพียงใดเนื่องจากข้อจำกัดด้านสัญญาณรบกวนและความไวของอุปกรณ์

ทั้ง 2 ค่าจะได้รับการปรับให้เป็นมาตรฐานโดยมีค่าแกนสูงสุดเป็น 1.0 ในมิติข้อมูลใดมิติข้อมูลหนึ่ง

controllerFlags สมาชิกประกอบด้วยชุดค่าผสมของบิตมาสก์แต่ละรายการ และค่าชุดค่าผสมแบบหลายบิต

การดำเนินการทางตรรกะ AND ของ controllerFlags กับ PADDLEBOAT_CONTROLLER_LAYOUT_MASK จะส่งผลให้ได้ค่าที่อาจส่งไปยัง Paddleboat_ControllerButtonLayout enum การแจงนับนี้ระบุไอคอนและเลย์เอาต์ของปุ่มที่ตัวควบคุมใช้

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 ผลลัพธ์ที่ไม่ใช่ 0 หมายความว่าคอนโทรลเลอร์รองรับความสามารถนี้

PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD

หากตั้งค่าบิตของแฟล็กนี้ ตัวควบคุมจะมีทัชแพดในตัว หากกด ทัชแพด ตัวควบคุมจะตั้งค่าบิต PADDLEBOAT_BUTTON_TOUCHPAD ในฟิลด์ Paddleboat_Controller_Data.buttonsDown

PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE

หากตั้งค่าบิตของแฟล็กนี้ ตัวควบคุมจะจำลองอุปกรณ์พอยน์เตอร์ ระบบจะป้อนข้อมูลพิกัดปัจจุบันของเคอร์เซอร์เสมือนลงในสมาชิก virtualPointer ของโครงสร้าง Paddleboat_Controller_Data

ข้อมูลตัวควบคุม

ฟังก์ชัน Paddleboat_getControllerData ใช้พารามิเตอร์อินพุต 2 รายการ ได้แก่ ดัชนีคอนโทรลเลอร์และพอยน์เตอร์ไปยังโครงสร้าง 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 ถึงความกว้าง/ความสูงของหน้าต่าง (เป็นพิกเซล)
ตั้งค่าบิตมาสก์ของปุ่มเมื่อกดด้วย (กล่าวคือ PADDLEBOAT_BUTTON_L1)

รายละเอียดโครงสร้าง

สมาชิกในบ้าน คำอธิบาย
buttonsDown อาร์เรย์ฟิลด์บิตแบบบิตต่อปุ่ม ค่าคงที่ของบิตแมสก์ปุ่ม จะกำหนดไว้ในไฟล์ส่วนหัว paddleboat.h และขึ้นต้นด้วย PADDLEBOAT_BUTTON_
timestamp. การประทับเวลาของเหตุการณ์อินพุตของคอนโทรลเลอร์ล่าสุด การประทับเวลาเป็นไมโครวินาทีนับตั้งแต่ Epoch ของนาฬิกา
virtualPointer ตำแหน่งของเคอร์เซอร์เสมือน ใช้ได้ก็ต่อเมื่อตั้งค่า PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE Flag ใน controllerFlags มิเช่นนั้นจะเป็น 0.0, 0.0