1. 移处GUI.ts对象,屏幕适配逻辑移动到LayerManager.ts中

2. 添加自动设置固定宽或高屏幕适配,默认开启自动设置,有特殊适配需求修改oops.gui.autoFixedWidthOrHeight=false,则为原版适配模式
This commit is contained in:
dgflash
2024-10-05 12:47:33 +08:00
parent dad566f6eb
commit 29f9ff7d95
4 changed files with 76 additions and 131 deletions

View File

@@ -16,7 +16,6 @@ import { StorageManager } from "./common/storage/StorageManager";
import { StorageSecuritySimple } from "./common/storage/StorageSecuritySimple";
import { TimerManager } from "./common/timer/TimerManager";
import { GameManager } from "./game/GameManager";
import { GUI } from "./gui/GUI";
import { LayerManager } from "./gui/layer/LayerManager";
const { property } = _decorator;
@@ -144,9 +143,6 @@ export class Root extends Component {
// 游戏隐藏事件
game.on(Game.EVENT_HIDE, this.onHide, this);
// 添加游戏界面屏幕自适应管理组件
this.gui.addComponent(GUI);
// 游戏尺寸修改事件
if (!sys.isMobile) {
screen.on("window-resize", () => {

View File

@@ -1,82 +0,0 @@
/*
* @Author: dgflash
* @Date: 2021-07-03 16:13:17
* @LastEditors: dgflash
* @LastEditTime: 2023-01-19 14:52:40
*/
import { Component, ResolutionPolicy, UITransform, _decorator, math, screen, view } from "cc";
import { oops } from "../Oops";
const { ccclass } = _decorator;
/** 游戏界面屏幕自适应管理 */
@ccclass('GUI')
export class GUI extends Component {
/** 是否为竖屏显示 */
portrait!: boolean;
/** 竖屏设计尺寸 */
private portraitDrz: math.Size = null!;
/** 横屏设计尺寸 */
private landscapeDrz: math.Size = null!;
/** 界面层矩形信息组件 */
private transform: UITransform = null!;
onLoad() {
this.init();
}
/** 初始化引擎 */
protected init() {
this.transform = this.getComponent(UITransform)!;
if (view.getDesignResolutionSize().width > view.getDesignResolutionSize().height) {
this.landscapeDrz = view.getDesignResolutionSize();
this.portraitDrz = new math.Size(this.landscapeDrz.height, this.landscapeDrz.width);
}
else {
this.portraitDrz = view.getDesignResolutionSize();
this.landscapeDrz = new math.Size(this.portraitDrz.height, this.portraitDrz.width);
}
this.resize();
}
/** 游戏画布尺寸变化 */
resize() {
let dr;
if (view.getDesignResolutionSize().width > view.getDesignResolutionSize().height) {
dr = this.landscapeDrz;
}
else {
dr = this.portraitDrz;
}
const s = screen.windowSize;
const rw = s.width;
const rh = s.height;
let finalW = rw;
let finalH = rh;
if ((rw / rh) > (dr.width / dr.height)) {
// 如果更长,则用定高
finalH = dr.height;
finalW = finalH * rw / rh;
this.portrait = false;
}
else {
// 如果更短,则用定宽
finalW = dr.width;
finalH = finalW * rh / rw;
this.portrait = true;
}
// 通过设置设计分辨率和匹配模式来进行游戏画面的屏幕适配
view.setDesignResolutionSize(finalW, finalH, ResolutionPolicy.UNKNOWN);
this.transform.width = finalW;
this.transform.height = finalH;
oops.log.logView(dr, "设计尺寸");
oops.log.logView(s, "屏幕尺寸");
}
}

View File

@@ -1,13 +0,0 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "9461c77f-7463-4418-ae48-e49db8c58e8b",
"files": [],
"subMetas": {},
"userData": {
"moduleId": "project:///assets/script/core/gui/GUI.js",
"importerSettings": 4,
"simulateGlobals": []
}
}

View File

@@ -1,5 +1,5 @@
import { Camera, Layers, Node, warn, Widget } from "cc";
import { GUI } from "../GUI";
import { Camera, Layers, Node, ResolutionPolicy, Widget, macro, screen, view, warn } from "cc";
import { oops } from "../../Oops";
import { UICallbacks } from "./Defines";
import { DelegateComponent } from "./DelegateComponent";
import { LayerDialog } from "./LayerDialog";
@@ -7,6 +7,16 @@ import { LayerNotify } from "./LayerNotify";
import { LayerPopUp } from "./LayerPopup";
import { LayerUI } from "./LayerUI";
/** 屏幕适配类型 */
export enum ScreenAdapterType {
/** 自动适配 */
Auto,
/** 横屏适配 */
Landscape,
/** 竖屏适配 */
Portrait
}
/** 界面层类型 */
export enum LayerType {
/** 二维游戏层 */
@@ -71,6 +81,9 @@ export class LayerManager {
/** 新手引导层 */
guide!: Node;
/** 是否自动设置固定宽或高适配 */
autoFixedWidthOrHeight: boolean = true;
/** 界面层 */
private readonly ui!: LayerUI;
/** 弹窗层 */
@@ -84,9 +97,67 @@ export class LayerManager {
/** UI配置 */
private configs: { [key: number]: UIConfig } = {};
/** 是否为竖屏显示 */
get portrait() {
return this.root.getComponent(GUI)!.portrait;
private initScreenAdapter() {
const drs = view.getDesignResolutionSize();
const ws = screen.windowSize;
const windowAspectRatio = ws.width / ws.height;
const designAspectRatio = drs.width / drs.height;
// 自动设置固定宽或高适配屏幕
if (this.autoFixedWidthOrHeight) {
if (windowAspectRatio > designAspectRatio) {
view.setResolutionPolicy(ResolutionPolicy.FIXED_HEIGHT);
view.setOrientation(macro.ORIENTATION_LANDSCAPE);
oops.log.logView("自动适配屏幕高度", "【横屏】");
}
else if (windowAspectRatio < designAspectRatio) {
view.setResolutionPolicy(ResolutionPolicy.FIXED_WIDTH);
view.setOrientation(macro.ORIENTATION_PORTRAIT);
oops.log.logView("自动适配屏幕宽度", "【竖屏】");
}
}
// 手动设置屏幕适配
else {
let finalW: number = 0;
let finalH: number = 0;
if (windowAspectRatio > designAspectRatio) {
finalH = drs.height;
finalW = finalH * ws.width / ws.height;
oops.log.logView("自动适配屏幕高度", "【横屏】");
}
else {
finalW = drs.width;
finalH = finalW * ws.height / ws.width;
oops.log.logView("自动适配屏幕宽度", "【竖屏】");
}
view.setDesignResolutionSize(finalW, finalH, ResolutionPolicy.UNKNOWN);
}
}
/**
* 构造函数
* @param root 界面根节点
*/
constructor(root: Node) {
this.root = root;
this.initScreenAdapter();
this.camera = this.root.getComponentInChildren(Camera)!;
this.game = this.create_node(LayerType.Game);
this.ui = new LayerUI(LayerType.UI);
this.popup = new LayerPopUp(LayerType.PopUp);
this.dialog = new LayerDialog(LayerType.Dialog);
this.system = new LayerDialog(LayerType.System);
this.notify = new LayerNotify(LayerType.Notify);
this.guide = this.create_node(LayerType.Guide);
root.addChild(this.game);
root.addChild(this.ui);
root.addChild(this.popup);
root.addChild(this.dialog);
root.addChild(this.system);
root.addChild(this.notify);
root.addChild(this.guide);
}
/**
@@ -375,33 +446,6 @@ export class LayerManager {
this.system.clear(isDestroy);
}
/**
* 构造函数
* @param root 界面根节点
*/
constructor(root: Node) {
this.root = root;
this.camera = this.root.getComponentInChildren(Camera)!;
this.game = this.create_node(LayerType.Game);
this.ui = new LayerUI(LayerType.UI);
this.popup = new LayerPopUp(LayerType.PopUp);
this.dialog = new LayerDialog(LayerType.Dialog);
this.system = new LayerDialog(LayerType.System);
this.notify = new LayerNotify(LayerType.Notify);
this.guide = this.create_node(LayerType.Guide);
root.addChild(this.game);
root.addChild(this.ui);
root.addChild(this.popup);
root.addChild(this.dialog);
root.addChild(this.system);
root.addChild(this.notify);
root.addChild(this.guide);
}
private create_node(name: string) {
const node = new Node(name);
node.layer = Layers.Enum.UI_2D;