Bắt đầu với SDK Đầu vào

Chủ đề này mô tả cách thiết lập và hiển thị lớp phủ SDK Đầu vào trong các trò chơi hỗ trợ Google Play Games. Các nhiệm vụ bao gồm thêm SDK vào trò chơi của bạn và tạo liên kết đầu vào, liên kết này sẽ gán dữ liệu đầu vào của người dùng cho hành động trong trò chơi. Đối với các trò chơi hỗ trợ thay đổi liên kết phím, bạn cũng phải theo dõi và đồng bộ hoá những thay đổi này với SDK.

Trước khi bạn bắt đầu

Trước khi thêm SDK Đầu vào trò chơi của mình, bạn phải thêm tính năng hỗ trợ bàn phím và chuột.

Thêm SDK

Nhận SDK đầu vào cho Java hoặc Kotlin bằng cách thêm phần phụ thuộc vào tệp build.gradle cấp mô-đun (tệp này có thể nằm trong thư mục app của bạn):

dependencies {
  implementation 'com.google.android.libraries.play.games:inputmapping:1.0.0-beta'
  ...
}

Chưa có SDK đầu vào cho Unity để tải xuống. SDK Đầu vào sẽ được cung cấp dưới dạng unitypackagetgz cho các nhà phát triển Unity.

Bạn nhớ bày tỏ sự quan tâm để được là một trong những người đầu tiên trải nghiệm SDK mới.

Tạo liên kết đầu vào

Liên kết đầu vào đại diện cho hành động trong trò chơi được người dùng gán cho dữ liệu đầu vào để hiển thị trong lớp phủ SDK Đầu vào. Để tạo liên kết đầu vào, bạn phải tạo InputMap rồi trả về bằng InputMappingProvider.

Dưới đây là một ví dụ về bản tóm tắt của một InputMappingProvider:

Kotlin

class MyInputMapProvider : InputMappingProvider {
    override fun onProvideInputMap(): InputMap {
        TODO("Not yet implemented")
    }
}

Java

public class MyInputMapProvider implements InputMappingProvider {
    @NonNull
    @Override
    public InputMap onProvideInputMap() {
        // TODO: return an InputMap
    }
}

C#

private class MyInputMappingProvider : PlayInputMappingProvider
{
    public PlayInputMap OnProvideInputMap()
    {
        // TODO("Not yet implemented")
    }
}

Phần tiếp theo mô tả cách tạo InputMap để trả về từ InputMappingProvider.

Xác định hành động nhập

Lớp InputAction được dùng để liên kết phím hoặc tổ hợp phím với hành động trong trò chơi.

Ví dụ sau liên kết phím space với hành động nhảy:

Kotlin

val jumpInputAction = InputAction.create(
    "Jump",
    InputEventIds.JUMP.id,
    InputControls.create(
        listOf(KeyEvent.KEYCODE_SPACE),
        emptyList()
    )
)

Java

InputAction jumpInputAction = InputAction.create(
        "Jump",
        InputEventIds.JUMP.ordinal(),
        InputControls.create(
                Collections.singletonList(KeyEvent.KEYCODE_SPACE),
                Collections.emptyList()
        )
);

C#

var jumpInputAction = PlayInputAction.Create(
    "Jump",
    (int)InputEventIds.Jump,
    PlayInputControls.Create(
        new[]
        {
            AndroidKeyCode.KEYCODE_SPACE
        },
        null
    )
);

Ảnh chụp màn hình của lớp phủ đầu vào cho biết hành động nhảy được liên kết với
phím Space.

Các hành động cũng có thể đại diện cho dữ liệu nhập bằng chuột. Ví dụ sau gán thao tác nhấp chuột phải cho hành động di chuyển:

Kotlin

val cmbMove = InputAction.create(
    "Move",
    InputEventIds.CMB_MOVE.id,
    InputControls.create(
        emptyList(),
        listOf(InputControls.MOUSE_RIGHT_CLICK)
    )
)

Java

InputAction cmbMove = InputAction.create(
        "Move",
        InputEventIds.CMB_MOVE.ordinal(),
        InputControls.create(
                Collections.emptyList(),
                Collections.singletonList(InputControls.MOUSE_RIGHT_CLICK)
        )
);

C#

var cmbMove = PlayInputAction.Create(
    "Move",
    (int)InputEventIds.CmbMove,
    PlayInputControls.Create(
        null,
        new[]
        {
            PlayMouseAction.MouseRightClick
        }
    )
);

Ảnh chụp màn hình của lớp phủ nhập mà trong đó hành động di chuyển được liên kết với
thao tác nhấp chuột phải.

Các tổ hợp phím được xác định bằng cách chuyển nhiều mã phím vào InputAction. Trong ví dụ này, Space+Shift được liên kết với hành động nhảy xa, tổ hợp phím này hoạt động ngay cả khi phím Space đã được liên kết với hành động nhảy.

Kotlin

val cmbDash = InputAction.create(
    "Dash",
    InputEventIds.CMB_DASH.id,
    InputControls.create(
        listOf(KeyEvent.KEYCODE_SPACE, KeyEvent.KEYCODE_SHIFT_LEFT),
        emptyList()
    )
)

Java

InputAction cmbDash = InputAction.create(
        "Dash",
        InputEventIds.CMB_DASH.ordinal(),
        InputControls.create(
                Arrays.asList(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SPACE),
                Collections.emptyList()
        )
);

C#

var cmbDash = PlayInputAction.Create(
    "Dash",
    (int)InputEventIds.CmbDash,
    PlayInputControls.Create(
        new[]
        {
            AndroidKeyCode.KEYCODE_SPACE, AndroidKeyCode.KEYCODE_SHIFT_LEFT
        }, null
    )
);

Ảnh chụp màn hình của lớp phủ đầu vào, trong đó Shift+Space được liên kết với
hành động nhảy xa.

SDK Đầu vào cho phép bạn kết hợp chuột và nút phím để tạo một lệnh. Ví dụ này cho thấy một điểm tham chiếu sẽ được thêm vào trò chơi khi nhấn đồng thời phím Shiftchuột phải:

Kotlin

val cmbWaypoint = InputAction.create(
    "Add Waypoint",
    InputEventIds.CMB_WAYPOINT.id,
    InputControls.create(
        listOf(KeyEvent.KEYCODE_SHIFT_LEFT),
        listOf(InputControls.MOUSE_RIGHT_CLICK)
    )
)

Java

InputAction cmbWaypoint = InputAction.create(
        "Add Waypoint",
        InputEventIds.CMB_WAYPOINT.ordinal(),
        InputControls.create(
                Collections.singletonList(KeyEvent.KEYCODE_SHIFT_LEFT),
                Collections.singletonList(InputControls.MOUSE_RIGHT_CLICK)
        )
);

C#

var cmbWaypoint = PlayInputAction.Create(
    "Add Waypoint",
    (int)InputEventIds.CmbWaypoint,
    PlayInputControls.Create(
        new[]
        {
            AndroidKeyCode.KEYCODE_SHIFT_LEFT
        },
        new[]
        {
            PlayMouseAction.MouseRightClick
        }
    )
);

Ảnh chụp màn hình của lớp phủ đầu vào, trong đó hành động Thêm điểm tham chiếu
được liên kết với tổ hợp Shift+chuột phải.

Phần này mô tả các phương thức được gọi trong ví dụ về mã:

Kotlin

InputAction.create có các thông số sau:

  • actionLabel là chuỗi được hiển thị trong giao diện người dùng để thể hiện hành động này. Nội dung không được bản địa hoá tự động, bạn có thể tùy ý bản địa hoá mọi nội dung từ đầu.
  • uniqueId là giá trị nhận dạng bằng số nguyên để nhận dạng hành động này. Mỗi hành động phải có một mã nhận dạng duy nhất và thống nhất, do đó, ví dụ này sử dụng cách đánh số. Hãy xem phần Theo dõi Mã phím để biết thêm thông tin.
  • inputControls quy định các chế độ cài đặt đầu vào mà hành động sử dụng. Các chế độ cài đặt này sẽ liên kết với các ký tự tương ứng trong giao diện người dùng.

InputControls.create tạo dữ liệu đầu vào liên kết với một hành động. Các thông số như sau:

  • keycodes là danh sách các số nguyên đại diện cho dữ liệu nhập bằng bàn phím được liên kết với hành động. Các giá trị này được quy định trong lớp KeyEvent.
  • mouseActions là danh sách các số nguyên đại diện cho dữ liệu nhập bằng chuột được liên kết với hành động. Các giá trị này được quy định trong InputControls.

Java

InputAction.create có các thông số sau:

  • actionLabel là chuỗi được hiển thị trong giao diện người dùng để thể hiện hành động này. Nội dung không được bản địa hoá tự động, bạn có thể tùy ý bản địa hoá mọi nội dung từ đầu.
  • uniqueId là giá trị nhận dạng bằng số nguyên để nhận dạng hành động này. Mỗi hành động phải có một mã nhận dạng duy nhất và thống nhất, do đó, ví dụ này sử dụng cách đánh số. Hãy xem phần Theo dõi Mã phím để biết thêm thông tin.
  • inputControls quy định các chế độ cài đặt đầu vào mà hành động sử dụng. Các chế độ cài đặt này sẽ liên kết với các ký tự tương ứng trong giao diện người dùng.

InputControls.create tạo dữ liệu đầu vào liên kết với một hành động. Các thông số như sau:

  • keycodes là danh sách các số nguyên đại diện cho dữ liệu nhập bằng bàn phím được liên kết với hành động. Các giá trị này được quy định trong lớp KeyEvent.
  • mouseActions là danh sách các số nguyên thể hiện dữ liệu đầu vào nhập bằng chuột liên kết với hành động này. Các giá trị này được quy định trong InputControls.

C#

InputAction có các trường sau:

  • ActionLabel là chuỗi được hiển thị trong giao diện người dùng để thể hiện hành động này. Nội dung không được bản địa hoá tự động, bạn có thể tùy ý bản địa hoá mọi nội dung từ đầu.
  • UniqueId là giá trị nhận dạng bằng số nguyên để nhận dạng hành động này. Mỗi hành động phải có một giá trị nhận dạng riêng biệt và nhất quán, vì vậy enum được sử dụng trong mẫu này. Xem Mã theo dõi phím.
  • InputControls quy định các chế độ điều khiển đầu vào mà hành động này sử dụng. Các chế độ cài đặt này sẽ liên kết với các ký tự tương ứng trong giao diện người dùng.

InputControls đại diện cho dữ liệu nhập liên quan đến một hành động, bao gồm các trường sau:

  • AndroidKeycodes là danh sách các số nguyên đại diện cho dữ liệu nhập bằng bàn phím được liên kết với hành động. Thông tin này được xác định trong lớp AndroidKeycode.
  • MouseActions là danh sách các giá trị MouseAction đại diện cho dữ liệu nhập bằng chuột được liên kết với hành động này.

Xác định nhóm đầu vào

InputGroup là một nhóm các đối tượng InputAction tương tự nhau. Ví dụ:

  • Bạn có thể quy định các nhóm dữ liệu nhập khác nhau để điều hướng trình đơn và di chuyển trong trò chơi.
  • Bạn có thể quy định các nhóm dữ liệu nhập khác nhau tuỳ theo chế độ chuyển động trong trò chơi của bạn, chẳng hạn như lái xe và đi bộ.
  • Bạn có thể quy định các nhóm dữ liệu nhập khác nhau tuỳ theo trạng thái hiện tại của trò chơi, chẳng hạn như khám phá tổng thể hoặc chơi một cấp độ riêng lẻ.

Bằng cách xếp dữ liệu nhập thành các nhóm, bạn giúp người chơi dễ dàng tìm thấy liên kết phím chính xác cho tình huống hiện tại.

Kotlin

val movementInputGroup = InputGroup.create(
    "Basic Movement",
    listOf(jumpInputAction, leftInputAction, rightInputAction, useInputAction)
)

Java

InputGroup movementInputGroup = InputGroup.create(
        "Basic Movement",
        Arrays.asList(jumpInputAction, leftInputAction, rightInputAction, useInputAction)
);

C#

var movementInputGroup = PlayInputGroup.Create(
    "Basic Movement",
    new[]
    {
        jumpInputAction, leftInputAction, rightInputAction, useInputAction
    }
);

Phần này mô tả các lệnh gọi phương thức mà ví dụ về mã sử dụng:

Kotlin

InputGroup.create có các thông số sau:

  • groupLabel là một chuỗi hiển thị trong giao diện người dùng, có thể dùng để phân nhóm các hành động theo logic. Chuỗi này chưa được bản địa hoá cho bạn.
  • inputActions là danh sách các đối tượng InputAction mà bạn đã xác định trong bước cuối cùng. Tất cả những hành động này sẽ hiển thị trực quan dưới tiêu đề của nhóm này.

Java

InputGroup.create có các thông số sau:

  • groupLabel là một chuỗi hiển thị trong giao diện người dùng, có thể dùng để phân nhóm các hành động theo logic. Chuỗi này chưa được bản địa hoá cho bạn.
  • inputActions là danh sách các đối tượng InputAction mà bạn đã xác định trong bước cuối cùng. Tất cả những hành động này sẽ hiển thị trực quan dưới tiêu đề của nhóm này.

C#

InputGroup có các trường sau:

  • GroupLabel là một chuỗi hiển thị trong giao diện người dùng, có thể dùng để phân nhóm các hành động theo logic. Chuỗi này chưa được bản địa hoá cho bạn.
  • InputActions là danh sách các đối tượng InputAction mà bạn đã xác định trong bước cuối cùng. Tất cả những hành động này sẽ hiển thị trực quan dưới tiêu đề của nhóm này.

Xây dựng liên kết đầu vào

InputMap tập hợp tất cả các đối tượng InputGroup có trong một trò chơi, do đó sẽ có mọi đối tượng InputAction mà người chơi muốn thực hiện.

Trong ví dụ sau, các đối tượng MovementInputGroup được nhóm với các đối tượng MouseSettings. Các đối tượng MouseSettings cho biết rằng bạn có thể điều chỉnh độ nhạy của chuột và chuột được đảo ngược trên trục y:

Kotlin

return InputMap.create(
    listOf(movementInputGroup, specialInputGroup),
    MouseSettings.create(true, true)
)

Java

return InputMap.create(
        Arrays.asList(movementInputGroup, specialInputGroup),
        MouseSettings.create(true, true)
);

C#

return PlayInputMap.Create(
    new[]
    {
        movementInputGroup, specialInputGroup, combinationInputGroup
    },
    PlayMouseSettings.Create(true, false)
);

Gửi liên kết đầu vào

Sau khi đã được ghi cho một trò chơi trả về InputMap hợp lệ, InputMapProvider phải được đăng ký bằng SDK Đầu vào. Nếu dữ liệu đầu vào của trò chơi không thay đổi, thì bạn chỉ phải thực hiện việc này một lần trong suốt quá trình chơi vì InputMapProvider sẽ không bị ảnh hưởng bởi các sự kiện trong vòng đời của Android.

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val inputMappingClient = Input.getInputMappingClient(this)
    inputMappingClient.setInputMappingProvider(MyInputMapProvider())
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    InputMappingClient inputMappingClient = Input.getInputMappingClient(this);
    inputMappingClient.setInputMappingProvider(new MyInputMapProvider());
}

C#

void Start()
{
    _inputMappingProvider = new MyInputMappingProvider();
    PlayInput.GetInputMappingClient().SetInputMappingProvider(_inputMappingProvider);
}

Bạn nên huỷ đăng ký với đơn vị cung cấp liên kết đầu vào khi trò chơi kết thúc. Tuy nhiên, SDK đủ thông minh để tránh làm rò rỉ tài nguyên nếu bạn không huỷ đăng ký.

Kotlin

override fun onDestroy() {
    val inputMappingClient = Input.getInputMappingClient(this)
    inputMappingClient.clearInputMappingProvider()

    super.onDestroy()
}

Java

@Override
protected void onDestroy() {
    InputMappingClient inputMappingClient = Input.getInputMappingClient(this);
    inputMappingClient.clearInputMappingProvider();

    super.onDestroy();
}

C#

private void OnDestroy()
{
    PlayInput.GetInputMappingClient().ClearInputMappingProvider();
}

Theo dõi mã phím

Bạn cần theo dõi mã nhận dạng duy nhất cho mỗi InputAction được bạn quy định. Bảng liệt kê sau theo dõi mã nhận dạng duy nhất của tất cả các mẫu trong chủ đề này. Do mã được dùng để theo dõi các thay đổi về phím, nên đừng dùng hàm băm của tên hành động đã bản địa hoá.

Kotlin

enum class InputEventIds(val id: Int) {
    JUMP(0),
    LEFT(1),
    RIGHT(2),
    USE(3),
    SPECIAL_JUMP(4),
    SPECIAL_DUCK(5),
}

Java

public enum InputEventIds {
    JUMP,
    LEFT,
    RIGHT,
    USE,
    SPECIAL_JUMP,
    SPECIAL_DUCK
}

C#

public enum InputEventIds
{
    JUMP,
    LEFT,
    RIGHT,
    USE,
    SPECIAL_JUMP,
    SPECIAL_DUCK
}

Kiểm tra

Có hai cách để kiểm tra xem SDK Đầu vào đã được triển khai đúng cách hay chưa. Hãy mở SDK Đầu vào trong giao diện người dùng của Google Play Games để xem người chơi thấy gì hoặc trong adb shell để kiểm tra và xác minh tự động.

Giao diện người dùng

Để thử nghiệm trong giao diện người dùng của Google Play Games, hãy nhấn tổ hợp phím Shift+Tab để mở Trang tổng quan trò chơi. Trong trang tổng quan, nhấp vào Điều khiển để xem danh sách các thao tác điều khiển hiện đang được liên kết.

Hình ảnh minh hoạ quy trình được mô tả ở trên. Tổ hợp phím Shift + Tab mở Trang tổng quan trò chơi. Sau đó, nhấp vào "Control" (Điều khiển) để mở ra lớp phủ điều khiển. Lớp phủ này cho thấy một nhóm có tên "Basic Movement" (Chuyển động cơ bản) với "Jump" (Nhảy), "Left" (Trái) và "Right" (Phải) trong đó. Mỗi tuỳ chọn điều khiển sẽ hiển thị các chế độ điều khiển thực hiện hành động đó. Ví dụ: "Jump" (Nhảy) có "Key W + Key Up" (tổ hợp phím W + mũi tên lên) viết bên dưới, sau đó bên phải là hình ảnh lớn một phím có chữ "w" và một phím có hình mũi tên lên. Có một phần tên là "Special Input" (Phương thức nhập đặc biệt) có ghi "Duck" (Né).

Dòng lệnh

Dữ liệu nhập cũng có thể được xác minh qua adb tại dòng lệnh, nhờ đó giúp thử nghiệm tự động tính năng này.

Để có liên kết đầu vào hiện tại, hãy sử dụng lệnh adb shell sau (thay thế MY.PACKAGE.NAME bằng tên trò chơi của bạn):

adb shell dumpsys input_mapping_service --get MY.PACKAGE.NAME

Bạn sẽ thấy kết quả tương tự như thế này nếu đăng ký thành công InputMap của mình:

Getting input map for com.example.inputsample...
Successfully received the following inputmap:
# com.google.android.libraries.play.games.InputMap@d73526e1
input_groups {
  group_label: "Basic Movement"
  input_actions {
    action_label: "Jump"
    input_controls {
      keycodes: 51
      keycodes: 19
    }
    unique_id: 0
  }
  input_actions {
    action_label: "Left"
    input_controls {
      keycodes: 29
      keycodes: 21
    }
    unique_id: 1
  }
  input_actions {
    action_label: "Right"
    input_controls {
      keycodes: 32
      keycodes: 22
    }
    unique_id: 2
  }
  input_actions {
    action_label: "Use"
    input_controls {
      keycodes: 33
      keycodes: 66
      mouse_actions: MOUSE_LEFT_CLICK
      mouse_actions_value: 0
    }
    unique_id: 3
  }
}
input_groups {
  group_label: "Special Input"
  input_actions {
    action_label: "Jump"
    input_controls {
      keycodes: 51
      keycodes: 19
      keycodes: 62
      mouse_actions: MOUSE_LEFT_CLICK
      mouse_actions_value: 0
    }
    unique_id: 4
  }
  input_actions {
    action_label: "Duck"
    input_controls {
      keycodes: 47
      keycodes: 20
      keycodes: 113
      mouse_actions: MOUSE_RIGHT_CLICK
      mouse_actions_value: 1
    }
    unique_id: 5
  }
}
mouse_settings {
  allow_mouse_sensitivity_adjustment: true
  invert_mouse_movement: true
}

Đồng bộ hoá các thay đổi liên kết phím

Nhiều trò chơi cho phép người chơi tuỳ chỉnh liên kết phím. Do đó, bạn cần đảm bảo rằng dữ liệu bạn trả về trong InputMapProvider là dữ liệu cập nhật cho chế độ cài đặt hiện tại của người chơi. Nếu cần, bạn có thể gọi setInputMappingProvider bằng liên kết đầu vào mới nhất một cách an toàn bất cứ khi nào người chơi hoàn tất việc thay đổi giao thức nhập.

Bản địa hoá

SDK Đầu vào không sử dụng hệ thống bản địa hoá của Android. Do đó, bạn phải cung cấp các chuỗi đã bản địa hoá khi gửi InputMap. Tuy nhiên, việc này cũng cho phép bạn sử dụng hệ thống bản địa hoá của công cụ phát triển trò chơi.

Các bước tiếp theo

Sau khi tích hợp SDK Đầu vào trò chơi của mình, bạn có thể tiếp tục thực hiện mọi yêu cầu còn lại của Google Play Games. Để biết thêm thông tin, hãy xem bài viết Bắt đầu với Google Play Games.