游戏场景和 UI 的屏幕自适应本页总览游戏场景和 UI 的屏幕自适应 在游戏开发中,屏幕自适应是一项至关重要的功能。无论玩家使用何种设备或窗口尺寸,都希望能获得最佳的视觉体验。本教程将带您一步步了解如何在 Dora SSR 引擎中实现游戏场景和游戏 UI 的屏幕自适应。 1. 理解屏幕自适应 在不同设备上,屏幕尺寸和分辨率各不相同。如果不进行自适应处理,游戏可能会在某些设备上显示不完整,或者元素位置错乱。屏幕自适应的目标是确保游戏内容在各种屏幕上都能正确显示,并保持良好的用户体验。 2. 实现游戏场景的自适应 游戏场景的自适应主要涉及根据窗口尺寸调整摄像机的视野,以确保场景内容完整地显示在屏幕中。 2.1 定义设计尺寸 首先,定义游戏的设计尺寸。这是您在设计和开发过程中所基于的参考尺寸。 LuaTealTypeScriptYueScriptlocal DesignSceneHeight <const> = 1024local DesignSceneHeight <const> = 1024const DesignSceneHeight = 1024;const DesignSceneHeight = 1024 在这里,我们将设计高度设为 1024。这意味着我们以高度为 1024 的尺寸进行场景设计。并希望游戏在做自适应时,会确保纵向的场景区域得到完整展示,横向超出屏幕区域的场景会被裁减,或是因为小于屏幕区域而被居中展示。 2.2 调整摄像机缩放 接下来,需要根据当前窗口的实际尺寸,调整摄像机的缩放比例。 LuaTealTypeScriptYueScriptlocal Director <const> = require("Director")local View <const> = require("View")local function updateViewSize() Director.currentCamera.zoom = View.size.height / DesignSceneHeightendlocal Director <const> = require("Director")local type Camera2D = require("Camera2D")local View <const> = require("View")local function updateViewSize() local camera = Director.currentCamera as Camera2D.Type camera.zoom = View.size.height / DesignSceneHeightendimport { Director, View, TypeName, tolua } from 'Dora';const updateViewSize = () => { const camera = tolua.cast(Director.currentCamera, TypeName.Camera2D); if (camera) { camera.zoom = View.size.height / DesignSceneHeight; }};_ENV = DoraupdateViewSize = -> Director.currentCamera.zoom = View.size.height / DesignSceneHeight 说明: Director.currentCamera:当前场景的摄像机对象。 zoom:摄像机的缩放属性,影响视野范围。 View.size.height:当前窗口的实际高度。 通过计算 View.size.height / DesignSceneHeight,我们得到实际高度与设计高度的比例,然后将其设置为摄像机的缩放值。 2.3 监听窗口尺寸变化 为了在窗口尺寸发生变化时(例如用户调整窗口大小或设备旋转)及时更新摄像机缩放,需要监听应用的尺寸变化事件。 LuaTealTypeScriptYueScriptupdateViewSize() -- 初始化时调用一次Director.entry:onAppChange(function(settingName) if settingName == "Size" then updateViewSize() -- 每次触发尺寸变化时更新 endend)updateViewSize() -- 初始化时调用一次Director.entry:onAppChange(function(settingName: string) if settingName == "Size" then updateViewSize() -- 每次触发尺寸变化时更新 endend)updateViewSize(); // 初始化时调用一次Director.entry.onAppChange(settingName => { if (settingName === 'Size') { updateViewSize(); // 每次触发尺寸变化时更新 }});updateViewSize! -- 初始化时调用一次Director.entry\onAppChange (settingName) -> if settingName == "Size" updateViewSize! -- 每次触发尺寸变化时 更新 说明: Director.entry:onAppChange:注册一个监听器,当应用的设置发生变化时被触发。 settingName:表示发生变化的设置项名称。 当 settingName 为 "Size" 时,表示窗口尺寸发生了变化,此时调用 updateViewSize() 更新摄像机缩放。 2.4 完整代码 LuaTealTypeScriptYueScript-- 自适应游戏场景示例-- 导入模块local DrawNode <const> = require("DrawNode")local Director <const> = require("Director")local View <const> = require("View")local Vec2 <const> = require("Vec2")-- 定义设计尺寸local DesignSceneHeight <const> = 1024-- 创建场景local node = DrawNode()node:drawDot(Vec2.zero, DesignSceneHeight / 2)node:addTo(Director.entry)-- 处理窗口尺寸变化local function updateViewSize() Director.currentCamera.zoom = View.size.height / DesignSceneHeightendupdateViewSize()-- 注册窗口尺寸变化的事件回调Director.entry:onAppChange(function(settingName) if settingName == "Size" then updateViewSize() endend)-- 自适应游戏场景示例-- 导入模块local DrawNode <const> = require("DrawNode")local Director <const> = require("Director")local View <const> = require("View")local Vec2 <const> = require("Vec2")local type Camera2D = require("Camera2D")-- 定义设计尺寸local DesignSceneHeight <const> = 1024-- 创建场景local node = DrawNode()node:drawDot(Vec2.zero, DesignSceneHeight / 2)node:addTo(Director.entry)-- 处理窗口尺寸变化local function updateViewSize() local camera = Director.currentCamera as Camera2D.Type camera.zoom = View.size.height / DesignSceneHeightendupdateViewSize()-- 注册窗口尺寸变化的事件回调Director.entry:onAppChange(function(settingName: string) if settingName == "Size" then updateViewSize() endend)// 自适应游戏场景示例// 导入模块import { DrawNode, Director, View, Vec2, TypeName } from 'Dora';// 定义设计尺寸const DesignSceneHeight = 1024;// 创建场景const node = DrawNode();node.drawDot(Vec2.zero, DesignSceneHeight / 2);node.addTo(Director.entry);// 处理窗口尺寸变化const updateViewSize = () => { const camera = tolua.cast(Director.currentCamera, TypeName.Camera2D); if (camera) { camera.zoom = View.size.height / DesignSceneHeight; }};updateViewSize();// 注册窗口尺寸变化的事件回调Director.entry.onAppChange(settingName => { if (settingName === 'Size') { updateViewSize(); }});-- 自适应游戏场景示例-- 导入模块_ENV = Dora-- 定义设计尺寸const DesignSceneHeight = 1024-- 创建场景const node = DrawNode!node.drawDot Vec2.zero, DesignSceneHeight / 2node.addTo Director.entry-- 处理窗口尺寸变化updateViewSize! -- 初始化时调用一次Director.entry\onAppChange (settingName) -> if settingName == "Size" updateViewSize! -- 每次触发尺寸变化时更新 3. 实现游戏 UI 的自适应 游戏 UI 的自适应需要确保界面元素在不同尺寸的屏幕上都能合理布局。我们将使用 Dora SSR 集成的 Yoga 布局引擎,通过类似 CSS 的 Flex 布局语法来定义元素的布局关系。 3.1 引入 Yoga 布局引擎 Yoga 是一个跨平台的布局引擎,支持基于 Flexbox 的布局方式。它允许我们使用熟悉的 CSS 语法来定义元素的布局。 LuaTealTypeScriptYueScriptlocal AlignNode <const> = require("AlignNode")local AlignNode <const> = require("AlignNode")import { AlignNode } from 'Dora';import "AlignNode" AlignNode 是 Dora SSR 中支持布局的节点类型。 3.2 使用 CSS Flex 布局 推荐一个学习 CSS Flex 布局的游戏想要快速学习 Flex 布局,可以试试 Flexbox Froggy 这款在线小游 戏:https://flexboxfroggy.com/ 首先,创建一个根节点,并设置其布局属性。 LuaTealTypeScriptYueScriptlocal root = AlignNode(true)root:css("justify-content: center; align-items: center")root:addTo(Director.ui)local root = AlignNode(true)root:css("justify-content: center; align-items: center")root:addTo(Director.ui)const root = AlignNode(true);root.css("justify-content: center; align-items: center");root.addTo(Director.ui);root = with AlignNode true \css "justify-content: center; align-items: center" \addTo Director.ui 说明: AlignNode(true):创建一个支持布局的节点,true 表示该节点作为窗口根节点的布局容器。 css(...):为节点应用 CSS 布局样式。 justify-content: center:水平居中对齐子节点。 align-items: center:垂直居中对齐子节点。 root:addTo(Director.ui):将根节点添加到引擎内置 UI 层的场景中。 接下来,创建一个子节点,并设置其尺寸为相对于父节点的百分比。 LuaTealTypeScriptYueScriptlocal centerNode = AlignNode()centerNode:css("width: 60%; height: 60%")centerNode:addTo(root)