Hãy sử dụng các hàm sau để thêm tính năng hỗ trợ tay điều khiển trò chơi bằng cách sử dụng thư viện Tay điều khiển trò chơi.
Khởi động và huỷ bỏ thư viện Tay điều khiển trò chơi
Sử dụng hàm Paddleboat_init
để khởi động thư viện Tay điều khiển trò chơi.
Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)
Paddleboat_init
nhận hai thông số:
- Con trỏ trỏ đến
JNIEnv
được gắn với luồng hiện tại - Đối tượng JNI
jobject
tham chiếu đến lớp cơ sởContext
. Mọi đối tượng lớp cơ sở xuất phát từContext
đều hợp lệ, bao gồm nhưng không giới hạn ởActivity
,NativeActivity
hoặcGameActivity
.
Paddleboat_init
sẽ trả về PADDLEBOAT_NO_ERROR
nếu khởi động thành công, nếu không, một mã lỗi thích hợp sẽ được trả về.
Bạn có thể sử dụng Paddleboat_isInitialized
để kiểm tra xem thư viện Tay điều khiển trò chơi đã được khởi động thành công hay chưa. Phương thức này trả về một giá trị boolean. Nếu là đúng (true), thì bạn có thể sử dụng API.
bool Paddleboat_isInitialized()
Trước khi chấm dứt việc chạy ứng dụng, hãy sử dụng hàm Paddleboat_destroy
để tắt thư viện Tay điều khiển trò chơi. Hàm này nhận một thông số duy nhất là con trỏ trỏ đến JNIEnv
được gắn với luồng hiện tại.
Paddleboat_init
có thể được gọi lại sau Paddleboat_destroy
.
void Paddleboat_destroy(JNIEnv *env)
Thông báo cho thư viện về các sự kiện trong vòng đời
Bạn phải thông báo cho thư viện Tay điều khiển về các sự kiện vòng đời hoạt động onStop
và onStart
.
Gọi các hàm Paddleboat_onStop
và Paddleboat_onStart
từ mã xử lý sự kiện dừng và bắt đầu của bạn. Cả hai hàm này đều nhận một thông số duy nhất: con trỏ trỏ đến JNIEnv
được gắn với luồng hiện tại.
void Paddleboat_onStop(JNIEnv *env)
void Paddleboat_onStart(JNIEnv *env)
Đăng ký hoặc loại bỏ lệnh gọi lại trạng thái tay điều khiển
Thư viện Tay điều khiển trò chơi sử dụng lệnh gọi lại trạng thái tay điều khiển để thông báo cho trò chơi khi tay điều khiển đã được kết nối hoặc bị ngắt kết nối. Tính năng này chỉ hỗ trợ mỗi lần một lệnh gọi lại trạng thái tay điều khiển.
- Để đăng ký lệnh gọi lại trạng thái tay điều khiển hoặc thay thế bất kỳ lệnh gọi lại nào đã đăng ký trước đó bằng hàm callback mới, hãy gọi hàm
Paddleboat_setControllerStatusCallback
. - Để loại bỏ bất kỳ lệnh gọi lại nào hiện đã đăng ký, hãy truyền
NULL
hoặcnullptr
. - Thông số
userData
là con trỏ tuỳ chọn trỏ đến dữ liệu do người dùng xác định. Thông sốuserData
sẽ được truyền đến hàm callback. Con trỏ này được duy trì nội bộ cho đến khi được một lệnh gọi tiếp theo thay đổi thànhPaddleboat_setControllerStatusCallback
.
void Paddleboat_setControllerStatusCallback(Paddleboat_ControllerStatusCallback
statusCallback, void *userData)
Chữ ký của hàm callback là:
typedef void (*Paddleboat_ControllerStatusCallback)(
const int32_t controllerIndex,
const Paddleboat_ControllerStatus controllerStatus,
void *userData)
Thông số | Mô tả |
---|---|
controllerIndex
|
Chỉ mục của tay điều khiển đã khởi tạo lệnh gọi lại. Sẽ là một giá trị nằm trong khoảng từ 0 đến PADDLEBOAT_MAX_CONTROLLERS - 1 |
controllerStatus
|
Giá trị enum của PADDLEBOAT_CONTROLLER_JUST_CONNECTED hoặc PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED . |
userData
|
Con trỏ tuỳ chọn (có thể là NULL (RỖNG)) trỏ đến dữ liệu do người dùng xác định được lệnh gọi gần nhất chỉ định cho Paddleboat_setControllerStatusCallback . |
Gọi hàm cập nhật thư viện Tay điều khiển trò chơi
Hàm cập nhật thư viện Tay điều khiển trò chơi, Paddleboat_update
, phải được gọi một lần cho mỗi khung hình của trò chơi, tốt nhất là ở gần đầu khung hình.
Hàm này nhận một tham số duy nhất là con trỏ trỏ đến JNIEnv
được gắn với luồng hiện tại.
void Paddleboat_update(JNIEnv *env)
Xử lý sự kiện
Khi nhận được sự kiện nhập, trò chơi cần chuyển tiếp các sự kiện đó đến thư viện Tay điều khiển trò chơi để kiểm tra. Thư viện Tay điều khiển trò chơi sẽ đánh giá xem sự kiện nhập đó có được liên kết với một trong các thiết bị do mình quản lý hay không. Các sự kiện từ thiết bị được quản lý sẽ được xử lý và sử dụng.
Thư viện Tay điều khiển trò chơi hỗ trợ hai loại sự kiện nhập: sự kiện nhập AInputEvents
và
GameActivity
.
Xử lý AInputEvent
Trò chơi sẽ chuyển tiếp AInputEvents
bằng cách gọi Paddleboat_processInputEvent
từ mã xử lý sự kiện.
int32_t Paddleboat_processInputEvent(const AInputEvent *event)
Paddleboat_processInputEvent
sẽ trả về 0
nếu sự kiện bị bỏ qua và 1
nếu sự kiện đã được thư viện Tay điều khiển trò chơi xử lý và sử dụng.
Xử lý sự kiện GameActivity
Nếu trò chơi của bạn sử dụng GameActivity
, hãy chuyển tiếp sự kiện GameActivityKeyEvent
và GameActivityMotionEvent
bằng cách gọi Paddleboat_processGameActivityKeyInputEvent
hoặc Paddleboat_processGameActivityMotionInputEvent
từ mã xử lý sự kiện.
int32_t Paddleboat_processGameActivityKeyInputEvent(const void *event,
const size_t eventSize)
int32_t Paddleboat_processGameActivityMotionInputEvent(const void *event,
const size_t eventSize)
Tham số | Mô tả |
---|---|
event
|
Con trỏ trỏ đến cấu trúc GameActivityKeyEvent hoặc GameActivityMotionEvent , tuỳ thuộc vào hàm được gọi. |
eventSize
|
Dung lượng tính bằng byte của cấu trúc sự kiện được truyền trong thông số event . |
Cả hai hàm sẽ trả về 0
nếu sự kiện bị bỏ qua và 1
nếu sự kiện được thư viện Tay điều khiển trò chơi xử lý và sử dụng.
GameActivity
đòi hỏi chỉ định trục chuyển động hoạt động bằng cách sử dụng hàm GameActivityPointerAxes_enableAxis
. Lệnh gọi Paddleboat_getActiveAxisMask
sẽ trả về một mặt nạ bit của trục chuyển động hiện đang hoạt động do tay điều khiển được kết nối sử dụng.
uint64_t Paddleboat_getActiveAxisMask()
Để biết ví dụ về cách xử lý, hãy xem mẫu thư viện Tay điều khiển trò chơi sử dụng GameActivity
. Mẫu này kiểm tra vòng mặt nạ trục hoạt động và thông báo cho GameActivity
khi trục mới được sử dụng. Việc này được triển khai trong hàm 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;
}
}
}
Đọc tay điều khiển
Thư viện Tay điều khiển trò chơi sử dụng một giá trị chỉ mục để tham chiếu đến một tay điều khiển cụ thể. Phạm vi giá trị chỉ mục hợp lệ nằm trong khoảng từ 0
đến PADDLEBOAT_MAX_CONTROLLERS - 1
. Hàm Paddleboat_getControllerStatus
xác định trạng thái của chỉ mục tay điều khiển đã chỉ định.
Paddleboat_ControllerStatus Paddleboat_getControllerStatus(
const int32_t controllerIndex)
Có ba hàm để đọc thông tin từ tay điều khiển được kết nối.
- Hàm
Paddleboat_getControllerName
truy xuất tên của thiết bị tay điều khiển. - Hàm
Paddleboat_getControllerInfo
truy xuất dữ liệu về chính thiết bị tay điều khiển đó. - Hàm
Paddleboat_getControllerData
truy xuất trạng thái hiện tại của hoạt động nhập từ tay điều khiển.
Tên tay điều khiển
Paddleboat_getControllerName function
nhận hai thông số đầu vào: chỉ mục tay điều khiển, dung lượng vùng đệm và con trỏ trỏ đến vùng đệm để lưu trữ chuỗi tên tay điều khiển. Chuỗi tên được định dạng là chuỗi C bằng cách sử dụng bộ mã hoá UTF-8. Tên thiết bị được thu thập nội bộ bằng InputDevice.getName()
.
Nếu bạn truy xuất tên thành công, Paddleboat_getControllerName
sẽ trả về PADDLEBOAT_NO_ERROR
, nếu không, một mã lỗi thích hợp sẽ được trả về.
Paddleboat_ErrorCode Paddleboat_getControllerName(const int32_t controllerIndex,
const size_t bufferSize,
char *controllerName);
Thông số | Mô tả |
---|---|
controllerIndex
|
Chỉ mục của tay điều khiển đã khởi tạo lệnh gọi lại. Sẽ là một giá trị nằm trong khoảng từ 0 đến PADDLEBOAT_MAX_CONTROLLERS - 1 |
bufferSize
|
Dung lượng tính bằng byte của vùng đệm được controllerName truyền, chuỗi tên sẽ được rút ngắn nếu cần để vừa với vùng đệm. |
controllerName
|
Con trỏ trỏ đến vùng đệm gồm bufferSize byte để lưu trữ tên tay điều khiển. Tên sẽ được lưu trữ dưới dạng chuỗi C bằng cách sử dụng bộ mã hoá UTF-8. |
Thông tin thiết bị điều khiển
Paddleboat_getControllerInfo function
nhận hai thông số đầu vào: chỉ mục tay điều khiển và con trỏ trỏ đến cấu trúc Paddleboat_Controller_Info
.
Nếu Paddleboat_Controller_Info
được điền sẵn dữ liệu thành công, Paddleboat_getControllerInfo
sẽ trả về PADDLEBOAT_NO_ERROR
, nếu không, một mã lỗi thích hợp sẽ được trả về.
Paddleboat_ErrorCode Paddleboat_getControllerInfo(const int32_t controllerIndex,
Paddleboat_Controller_Info *controllerInfo)
Cấu trúc Paddleboat_Controller_Info
chứa thông tin dành riêng cho từng thiết bị về tay điều khiển.
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;
Một số thành phần cấu trúc được điền sẵn các giá trị lấy từ InputDevice
liên kết với tay điều khiển:
controllerNumber - InputDevice.getControllerNumber()
vendorId - InputDevice.getVendorId()
productId - InputDevice.getProductId()
deviceId - InputDevice.getId()
- Giá trị
stickFlat
thể hiện phạm vi của một vị trí phẳng nằm ở trung tâm. Giá trị này chủ yếu hữu ích cho việc tính toán "vùng không nhận biết" trung tâm mặc định trên các thiết bị tự căn giữa. - Giá trị
stickFuzz
thể hiện khả năng chịu lỗi hoặc khoảng cách mà giá trị hiện tại có thể sai lệch so với giá trị thực tế do các giới hạn về độ nhạy của thiết bị và độ nhiễu.
Cả hai giá trị này đều được chuẩn hoá theo giá trị trục tối đa là 1.0
ở cả hai chiều.
Thành phần controllerFlags
kết hợp các cờ mặt nạ bit riêng lẻ và các giá trị kết hợp nhiều bit.
Việc thực hiện thao tác AND
logic cho controllerFlags
với PADDLEBOAT_CONTROLLER_LAYOUT_MASK
dẫn đến một giá trị có thể được truyền đến enum Paddleboat_ControllerButtonLayout
. Enum này chỉ định biểu tượng và bố cục nút mà tay điều khiển sử dụng.
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
};
Các hằng số sau đây xác định các bit chức năng. Để xác định xem một tay điều khiển có hỗ trợ chức năng cụ thể nào đó hay không, hãy thực hiện thao tác AND
logic cho hằng số tương ứng so với controllerFlags
. Kết quả khác 0 nghĩa là tay điều khiển có hỗ trợ chức năng đó.
PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD
Nếu bit cờ này được đặt, thì tay điều khiển có bàn di chuột tích hợp. Nếu nhấn vào bàn di chuột, tay điều khiển sẽ đặt bit PADDLEBOAT_BUTTON_TOUCHPAD
trong trường Paddleboat_Controller_Data.buttonsDown
.
PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE
Nếu bit cờ này được đặt, thì tay điều khiển mô phỏng thiết bị trỏ. Thành phần virtualPointer
của cấu trúc Paddleboat_Controller_Data
được điền sẵn toạ độ hiện tại của con trỏ ảo.
Dữ liệu tay điều khiển
Hàm Paddleboat_getControllerData
nhận hai thông số đầu vào: chỉ mục tay điều khiển và con trỏ trỏ đến cấu trúc Paddleboat_Controller_Data
. Nếu Paddleboat_Controller_Data
được điền sẵn dữ liệu thành công, Paddleboat_getControllerInfo
sẽ trả về PADDLEBOAT_NO_ERROR
, nếu không, một mã lỗi thích hợp sẽ được trả về.
Paddleboat_ErrorCode Paddleboat_getControllerData(const int32_t controllerIndex,
Paddleboat_Controller_Data *controllerData)
Cấu trúc Paddleboat_Controller_Data
chứa các giá trị đầu vào điều khiển hiện tại của bộ điều khiển.
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;
Khoảng giá trị
Loại đầu vào | Phạm vi giá trị |
---|---|
Trục gậy điều khiển | -1.0 đến 1.0 |
Cò | 0.0 đến 1.0 |
Con trỏ ảo | 0.0 so với chiều rộng/chiều cao của cửa sổ (tính bằng pixel) |
Chi tiết cấu trúc
Thành phần cấu trúc | Mô tả |
---|---|
buttonsDown
|
Mảng trường bit bit trên mỗi nút. Hằng số mặt nạ bit của nút được xác định trong tệp tiêu đề paddleboat.h và bắt đầu bằng PADDLEBOAT_BUTTON_ . |
timestamp.
|
Dấu thời gian của sự kiện nhập tay điều khiển gần đây nhất. Dấu thời gian tính theo micrô giây kể từ thời gian bắt đầu của đồng hồ. |
virtualPointer
|
Vị trí con trỏ ảo. Chỉ hợp lệ nếu cờ PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE được đặt trong controllerFlags , nếu không, sẽ là 0.0, 0.0 . |