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 ChromeOS và Google 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 giao diện máy tính chính. Trên máy tính bảng và thiết bị có thể gập lại mới chạy Android 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 cho kích thước cửa sổ và hướng trên một số thiết bị.
Khả năng đổi kích thước với trò chơi Unity
Cấu hình cơ bản cho màn hình lớn
Khai báo xem 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 thể hỗ trợ tính 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ổ trong khi vẫn tuân theo tỷ lệ khung hình đã chỉ định. Kích thước cửa sổ được tự động khoá ở các kích thước tối ưu. Bạn cần hỗ trợ ít nhất tỷ lệ khung hình 16:9 nếu hướng chính là hướng 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 tỷ lệ khung hình 21:9, 16:10 và 3:2 cho trò chơi theo hướng ngang. Bạn không bắt buộc phải có khả năng đổi kích thước cửa sổ ở đây, nhưng vẫn nên có để tương thích với các kiểu 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 trên ChromeOS và Android
Để tối đa hoá khu vực hiển thị 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ế độ chìm đắm toàn màn hình và ẩn các 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 này xảy ra trên thiết bị ChromeOS.
Xin lưu ý rằng trên các thiết bị Android có màn hình lớn, trò chơi của bạn có thể chạy trong các cấu hình mà bạn chưa xử lý. Nếu trò chơi của bạn không hỗ trợ tất cả cấu hình kích thước cửa sổ và hướng, thì nền tảng sẽ tạo hiệu ứng hòm thư cho trò chơi của bạn ở chế độ tương thích và nhắc người chơi trước khi chuyển sang cấu hình không được hỗ trợ (nếu cần).

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 chọn tải lại trò chơi và tạo lại hoạt động để phù hợp nhất với bố cục cửa sổ mới, điều này sẽ làm 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ổ (kích thước cửa sổ 2/3, 1/2, 1/3) và xác minh rằng không có thành phần nào trong trò chơi hoặc giao diện người dùng bị cắt bớt hoặc không truy cập được. Ngoài ra, hãy kiểm thử cách trò chơi của bạn phản hồi tính năng liên tục trên thiết bị có thể gập lại khi di chuyển giữa màn hình trong và màn hình ngoài trên thiết bị có thể gập lại. Nếu bạn thấy 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ợ đổi kích thước màn hình lớn nâng cao.
Khả năng đổi kích thước màn hình lớn nâng cao
Để 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:
Khai báo hoạt động chính có thể đổi kích thước:
<android:resizeableActivity="true" />
Khai báo rõ ràng tính năng hỗ trợ "orientation" (hướng), "screenSize" (kích thước màn hình), "smallestScreenSize" (kích thước màn hình nhỏ nhất), "screenLayout" (bố cục màn hình) và "density" (mật độ) trong thuộc tính
android:configChanges
của phần tử<activity>
trong tệp kê khai trò chơi để nhận tất cả sự kiện cấu hình màn hình lớn:<android:configChanges="screenSize | smallestScreenSize | screenLayout | orientation | keyboard | keyboardHidden | density" />
Ghi đè
onConfigurationChanged()
và xử lý sự kiện cấu hình, bao gồm 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 chế độ xoay thiết bị hiện tại. Sử dụng siêu dữ liệu này, hãy kiểm tra kích thước cửa sổ mới và hiển thị ở kích thước cửa sổ đầy đủ. Cách này có thể không hiệu quả trong mọi trường hợp do sự khác biệt về tỷ lệ khung hình. Vì vậy, bạn có thể neo giao diện người dùng trò chơi của mình theo kích thước cửa sổ mới và tạo hiệu ứng hòm thư cho nội dung trò chơi cốt lõi. Nếu có các giới hạn kỹ thuật hoặc thiết kế ngăn cản một trong hai phương pháp này, hãy tự tạo hộp thư trong công cụ để giữ nguyên tỷ lệ khung hình và điều chỉnh theo kích thước tốt nhất có thể trong khi khai báo resizeableActivity = false
và tránh chế độ cấu hình.
Bất kể bạn sử dụng phương pháp nào, hãy kiểm thử trò chơi của bạn trong nhiều cấu hình (gập và mở, nhiều thay đổi về độ xoay, chế độ chia đôi màn hình) và đảm bảo không có thành phần giao diện người dùng bị cắt bớt hoặc chồng chéo trong trò chơi, các vấn đề về khả năng hỗ trợ tiếp cận mục tiêu chạm hoặc các vấn đề về tỷ lệ khung hình khiến trò chơi bị kéo giãn, bị bẹp hoặc bị méo.
Ngoài ra, màn hình lớn hơn thường có nghĩa là pixel lớn hơn, vì bạn có cùng số pixel cho một khu vực lớn hơn nhiều. Điều này có thể gây ra hiện tượng tạo điểm ảnh cho vùng đệm kết xuất thu nhỏ hoặc các thành phần có độ phân giải thấp hơn. Sử dụng các thành phần có chất lượng cao nhất trên thiết bị màn hình lớn và phân tích hiệu suất trò chơi để đảm bảo không có vấn đề gì. Nếu trò chơi của bạn hỗ trợ nhiều cấp độ chất lượng, hãy đảm bảo rằng trò chơi đó tính đến các thiết bị 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 đồng thời chia sẻ 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 chế độ nhiều cửa sổ sẽ thay đổi theo các phiên bản Android khác nhau (xem phần Vòng đời hoạt động ở chế độ nhiều cửa sổ trong phần Hỗ trợ chế độ nhiều cửa sổ).
Khi người chơi đặt một ứng dụng hoặc trò chơi vào chế độ nhiều cửa sổ, hệ thống sẽ thông báo cho hoạt động về sự thay đổi cấu hình như được chỉ định trong phần Khả năng đổ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 đưa trò chơi trở lại 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 được chuyển sang chế độ nhiều cửa sổ. Do đó, nếu bạn sử 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 lấy tiêu điểm (onWindowFocusChanged()
có giá trị tiêu điểm là true) để tiếp tục trò 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 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 cần phải chạy ở chế độ toàn màn hình và bạn nên khai báo kích thước cửa sổ cho trường hợp đó. Bạn nên áp dụng một trong hai cách sau.
Cách đầ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. Các thuộc tính defaultHeight
và defaultWidth
kiểm soát các kích thước ban đầu. Ngoài ra, hãy lưu ý đến các thuộc tính minHeight
và minWidth
để ngăn người chơi đổi kích thước cửa sổ trò chơi thành các kích thước mà bạn không hỗ trợ. Cuối cùng, có thuộc tính gravity
xác định vị trí cửa sổ xuất hiện trên màn hình khi khởi chạy. Sau đây là ví dụ về thẻ bố cục 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" />
Tuỳ chọn thứ hai để đặt kích thước cửa 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 mở rộng 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 bạn đang sử dụng phiên bản mới nhất (Unity 2019.4.40 và Unreal 5.3 trở lên) có hỗ trợ tốt cho chế độ nhiều cửa sổ.
Hỗ trợ tư thế gập
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à sự đắm chìm của người chơi:

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); }