Hỗ trợ đổi kích thước màn hình lớn

Việc mở rộng từ điện thoại sang nhiều kiểu dáng màn hình lớn sẽ đưa ra những điểm cần cân nhắc về cách trò chơi của bạn xử lý việc quản lý cửa sổ. Trên ChromeOSGoogle Play Games trên máy tính, trò chơi của bạn có thể chạy ở chế độ cửa sổ trên một giao diện chính trên máy tính. Trên máy tính bảng và thiết bị có thể gập lại Android mới chạy Android 12L (API cấp 32) trở lên có chiều rộng màn hình > 600 dp, trò chơi của bạn có thể chạy cạnh nhau ở chế độ chia đôi màn hình với các ứng dụng khác, đổi kích thước và thậm chí di chuyển giữa màn hình trong và ngoài trên thiết bị có thể gập lại dẫn đến thay đổi cấu hình đối với kích thước cửa sổ và hướng trên một số thiết bị.

Cấu hình cơ bản cho màn hình lớn

Khai báo về việc trò chơi của bạn có thể xử lý khả năng đổi kích thước hay không:

<android:resizeableActivity="true" or "false" />

Nếu không hỗ trợ khả năng đổi kích thước, hãy đảm bảo tệp kê khai trò chơi xác định rõ tỷ lệ khung hình tối thiểu và tối đa được hỗ trợ:

<!-- Render full screen between 3:2 and 21:9 aspect ratio -->
<!-- Let the platform letterbox otherwise -->
<activity android:minAspectRatio="1.5">
<activity android:maxAspectRatio="2.33">

Google Play Games trên máy tính

Đối với Google Play Games trên máy tính, nền tảng này xử lý khả năng đổi kích thước cửa sổ mà vẫn tuân thủ tỷ lệ khung hình được chỉ định. Kích thước cửa sổ được tự động khoá theo kích thước tối ưu. Bạn cần hỗ trợ tỷ lệ khung hình ít nhất là 16:9 nếu hướng chính là ngang và tỷ lệ khung hình 9:16 nếu trò chơi của bạn ở chế độ dọc. Để có trải nghiệm tốt nhất, hãy hỗ trợ rõ ràng các tỷ lệ khung hình 21:9, 16:10 và 3:2 cho trò chơi ở chế độ ngang. Ở đây, bạn không bắt buộc phải đổi kích thước cửa sổ, nhưng vẫn cần có khả năng tương thích với các hệ số hình dạng khác.

Để biết thêm thông tin và các phương pháp hay nhất, hãy xem bài viết Định cấu hình đồ hoạ cho Google Play Games trên máy tính.

Màn hình lớn của ChromeOS và Android

Để mở rộng tối đa khu vực xem được cho trò chơi ở chế độ toàn màn hình trên ChromeOS và các thiết bị Android màn hình lớn, hãy hỗ trợ chế độ sống động toàn màn hình và ẩn thanh hệ thống bằng cách đặt cờ trên decorView, chế độ hiển thị giao diện người dùng hệ thống hoặc thông qua API WindowInsetsCompat. Bạn cũng nên xử lý linh hoạt các sự kiện xoay và đổi kích thước cấu hình hoặc ngăn các sự kiện đó xảy ra trên thiết bị ChromeOS.

Xin lưu ý rằng trên thiết bị Android có màn hình lớn, trò chơi của bạn có thể chạy ở cấu hình mà có thể bạn chưa xử lý. Nếu trò chơi của bạn không hỗ trợ tất cả các cấu hình kích thước và hướng cửa sổ, thì nền tảng này sẽ tạo hiệu ứng hòm thư cho trò chơi ở chế độ tương thích và nếu cần, sẽ nhắc người chơi trước khi chuyển sang một cấu hình không được hỗ trợ.

Hình 1. Hộp thoại về khả năng tương thích với cấu hình.

Trên một số thiết bị, khi người chơi chuyển sang một cấu hình không được hỗ trợ, họ có thể được nhắc tải lại trò chơi và tạo lại hoạt động cho phù hợp nhất với bố cục cửa sổ mới. Điều này gây gián đoạn trải nghiệm chơi. Kiểm thử trò chơi của bạn ở nhiều cấu hình chế độ nhiều cửa sổ (2/3, 1/2, 1/3 kích thước cửa sổ) và xác minh không có lối chơi hoặc các yếu tố giao diện người dùng nào bị cắt hoặc không thể truy cập được. Ngoài ra, hãy kiểm thử xem trò chơi của bạn đáp ứng tính liên tục của thiết bị có thể gập lại như thế nào khi di chuyển giữa màn hình trong và ngoài trên các thiết bị có thể gập lại. Nếu bạn gặp vấn đề, hãy xử lý rõ ràng các sự kiện cấu hình này và thêm tính năng hỗ trợ nâng cao về khả năng đổi kích thước màn hình lớn.

Khả năng đổi kích thước màn hình lớn nâng cao

Hình 2. Nhiều giao diện người dùng trên máy tính và thiết bị có thể gập lại ở tư thế trên mặt bàn.

Để thoát khỏi chế độ tương thích và tránh tạo lại hoạt động, hãy làm như sau:

  1. Khai báo hoạt động chính có thể đổi kích thước:

    <android:resizeableActivity="true" />
    
  2. Khai báo tính năng hỗ trợ rõ ràng cho "Orientation", "screenSize", "smallestScreenSize", "screenLayout" và "density" trong thuộc tính android:configChanges của phần tử <activity> của tệp kê khai trò chơi để nhận tất cả sự kiện định cấu hình màn hình lớn:

    <android:configChanges="screenSize | smallestScreenSize | screenLayout | orientation | keyboard |
                            keyboardHidden | density" />
    
  3. Ghi đè onConfigurationChanged() và xử lý sự kiện cấu hình, bao gồm cả hướng, kích thước cửa sổ, chiều rộng và chiều cao hiện tại:

    Kotlin

    override fun onConfigurationChanged(newConfig: Configuration) {
       super.onConfigurationChanged(newConfig)
       val density: Float = resources.displayMetrics.density
       val newScreenWidthPixels =
    (newConfig.screenWidthDp * density).toInt()
       val newScreenHeightPixels =
    (newConfig.screenHeightDp * density).toInt()
    
       // Configuration.ORIENTATION_PORTRAIT or ORIENTATION_LANDSCAPE
       val newScreenOrientation: Int = newConfig.orientation
    
       // ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270
       val newScreenRotation: Int =
    windowManager.defaultDisplay.rotation
    }
    

    Java

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
       super.onConfigurationChanged(newConfig);
       float density = getResources().getDisplayMetrics().density;
       int newScreenWidthPixels = (int) (newConfig.screenWidthDp * density);
       int newScreenHeightPixels = (int) (newConfig.screenHeightDp * density);
    
       // Configuration.ORIENTATION_PORTRAIT or ORIENTATION_LANDSCAPE
       int newScreenOrientation = newConfig.orientation;
    
       // ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270
       int newScreenRotation = getWindowManager().getDefaultDisplay()
               .getRotation();
    }
    

Bạn cũng có thể truy vấn WindowManager để kiểm tra hướng xoay thiết bị hiện tại. Hãy sử dụng siêu dữ liệu này để kiểm tra kích thước cửa sổ mới và hiển thị ở kích thước đầy đủ của cửa sổ. Tính năng này có thể không hiệu quả trong một số trường hợp do sự khác biệt về tỷ lệ khung hình. Vì vậy, bạn có thể cố định giao diện người dùng của trò chơi vào kích thước cửa sổ mới và tạo khung viền hòm thư cho nội dung cốt lõi về lối chơi. Nếu có hạn chế về mặt kỹ thuật hoặc thiết kế ngăn cản một trong hai cách tiếp cận, hãy tạo hiệu ứng hòm thư của riêng bạn trong công cụ để duy trì tỷ lệ khung hình và điều chỉnh theo tỷ lệ theo kích thước phù hợp nhất có thể trong khi khai báo resizeableActivity = false và tránh chế độ cấu hình.

Dù chọn phương pháp nào, hãy kiểm thử trò chơi ở nhiều cấu hình (gập và mở, thay đổi chế độ xoay, chế độ chia đôi màn hình) và đảm bảo không có thành phần trên giao diện người dùng trong trò chơi bị cắt hoặc chồng chéo, vấn đề về hỗ trợ tiếp cận đích chạm hoặc vấn đề về tỷ lệ khung hình khiến trò chơi bị kéo giãn, bị bung hoặc bị méo.

Ngoài ra, màn hình lớn hơn thường có nghĩa là số pixel lớn hơn, vì bạn có cùng số lượng pixel cho khu vực lớn hơn nhiều. Điều này có thể gây ra hiệu ứng nhiễu điểm ảnh cho vùng đệm kết xuất bị giảm kích thước hoặc các thành phần có độ phân giải thấp hơn. Sử dụng thành phần có chất lượng cao nhất trên thiết bị màn hình lớn và hồ sơ hiệu suất cho trò chơi của bạn để đảm bảo không có vấn đề. Nếu trò chơi của bạn hỗ trợ nhiều mức chất lượng, hãy đảm bảo rằng trò chơi đó phù hợp với các thiết bị có màn hình lớn.

Chế độ nhiều cửa sổ

Chế độ nhiều cửa sổ cho phép nhiều ứng dụng chia sẻ đồng thời cùng một màn hình. Chế độ nhiều cửa sổ không thay đổi vòng đời hoạt động; tuy nhiên, trạng thái tiếp tục của các ứng dụng trong nhiều cửa sổ sẽ khác nhau trên các phiên bản Android khác nhau (xem Vòng đời hoạt động ở chế độ nhiều cửa sổ trong phần Hỗ trợ nhiều cửa sổ).

Khi người chơi đặt một ứng dụng hoặc trò chơi ở chế độ nhiều cửa sổ, hệ thống sẽ thông báo cho hoạt động về thay đổi cấu hình như nêu trong phần Thay đổi kích thước màn hình lớn nâng cao. Việc thay đổi cấu hình cũng xảy ra khi người chơi đổi kích thước trò chơi hoặc đặt trò chơi về chế độ toàn màn hình.

Không có gì đảm bảo rằng ứng dụng sẽ lấy lại tiêu điểm khi bị đặt ở chế độ nhiều cửa sổ. Do đó, nếu bạn dùng bất kỳ sự kiện trạng thái ứng dụng nào để tạm dừng trò chơi, đừng dựa vào sự kiện thu nạp người dùng (onWindowFocusChanged() có giá trị tâm điểm là true) để tiếp tục chơi. Thay vào đó, hãy sử dụng các trình xử lý sự kiện hoặc trình xử lý thay đổi trạng thái khác như onConfigurationChanged() hoặc onResume(). Xin lưu ý rằng bạn luôn có thể sử dụng phương thức isInMultiWindowMode() để phát hiện xem hoạt động hiện tại có đang chạy ở chế độ nhiều cửa sổ hay không.

Với chế độ nhiều cửa sổ trên ChromeOS, kích thước của cửa sổ ban đầu trở thành một yếu tố quan trọng cần cân nhắc. Trò chơi không nhất thiết phải ở chế độ toàn màn hình nhưng bạn cần khai báo kích thước của cửa sổ trong trường hợp đó. Có 2 cách được đề xuất để xử lý vấn đề này.

Lựa chọn đầu tiên hoạt động bằng cách sử dụng các thuộc tính cụ thể trên thẻ <layout> trong tệp kê khai Android. Thuộc tính defaultHeightdefaultWidth kiểm soát các chiều ban đầu. Ngoài ra, hãy lưu ý đến các thuộc tính minHeightminWidth để ngăn người chơi đổi kích thước cửa sổ trò chơi thành những kích thước mà bạn không hỗ trợ. Cuối cùng, thuộc tính gravity xác định vị trí trên màn hình cửa sổ sẽ xuất hiện khi khởi chạy. Dưới đây là một thẻ bố cục mẫu sử dụng các thuộc tính này:

<layout android:defaultHeight="500dp"
        android:defaultWidth="600dp"
        android:gravity="top|end"
        android:minHeight="450dp"
        android:minWidth="300dp" />

Lựa chọn thứ hai để đặt kích thước cửa sổ sẽ hoạt động thông qua việc sử dụng giới hạn khởi chạy động. Bằng cách sử dụng setLaunchBounds(Rect)⁠⁠, bạn có thể xác định kích thước cửa sổ bắt đầu. Nếu bạn chỉ định một hình chữ nhật trống, thì hoạt động sẽ bắt đầu ở trạng thái tối đa.

Ngoài ra, nếu bạn đang sử dụng công cụ phát triển trò chơi Unity hoặc Unreal, hãy đảm bảo rằng bạn đang sử dụng phiên bản mới (Unity 2019.4.40 và Unreal 5.3 trở lên) hỗ trợ tốt cho chế độ nhiều cửa sổ.

Giá đỡ hỗ trợ tư thế gập lại

Sử dụng thư viện bố cục WindowManager của Jetpack để hỗ trợ các tư thế có thể gập lại (chẳng hạn như trên mặt bàn) nhằm tăng mức độ tương tác và mức độ tương tác của người chơi:

Hình 3. Trò chơi ở tư thế trên mặt bàn với chế độ xem chính là phần màn hình dọc, các nút điều khiển ở phần ngang.

Kotlin

fun isTableTopPosture(foldFeature : FoldingFeature?) : Boolean {
    contract { returns(true) implies (foldFeature != null) }
    return foldFeature?.state == FoldingFeature.State.HALF_OPENED &&
            foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
}

Java

boolean isTableTopPosture(FoldingFeature foldFeature) {
    return (foldFeature != null) &&
           (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) &&
           (foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL);
}