ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Godot 窗口管理与 DisplayServer 完整实战指南:window_management 演示项目深度解析

Godot 窗口管理与 DisplayServer 完整实战指南:window_management 演示项目深度解析 示例工程【免费下载链接】godot-demo-projectsDemonstration and Template Projects项目地址https://gitcode.com/GitHub_Trending/go/godot-demo-projects点击查看免费下载本文基于 godot-demo-projects 仓库中的 window_management 演示项目系统讲解如何通过 Godot 的DisplayServerAPI 完成窗口移动、缩放、最小化/最大化、透明化、鼠标模式切换以及屏幕信息DPI、刷新率、多屏读取等全部窗口管理能力。读完本文你将掌握DisplayServer与Input相关 API 的完整用法并理解如何在 Web 与多平台环境下优雅降级。演示项目概览misc/window_management是 Godot 官方 demo-projects 仓库中的一个独立演示项目其核心目标正如 README.md 所述展示通过DisplayServer可用的各种窗口管理特性包括移动窗口切换可调整大小 / 固定大小并设置窗口尺寸最小化与最大化透明窗口捕获、隐藏或限制鼠标获取屏幕相关信息包括 DPI 与刷新率。该演示使用GDScript编写渲染器为CompatibilityGL Compatibility项目配置为 Godot 4.7见 project.godot 中的config/featuresPackedStringArray(4.7)。项目由三个核心文件组成文件职责control.gd窗口 / 鼠标 / 屏幕操作的完整控制逻辑observer/observer.gd3D 观察者第一人称控制器配合鼠标捕获模式演示window_management.tscn主场景UI 按钮、状态标签与 3D 场景的组织运行方式该目录是一个独立可运行的 Godot 项目目录内包含project.godot。使用与项目版本兼容的 Godot 编辑器打开misc/window_management/project.godot即可直接运行主场景为 window_management.tscn。运行后左侧为控制按钮区右侧为实时状态标签区中间则是一个 3D 场景用于配合鼠标捕获模式进行第一人称漫游演示。DisplayServer窗口管理的统一入口在 Godot 4.x 中窗口与显示相关的能力统一由DisplayServer单例提供它屏蔽了 Windows、macOS、Linux/X11、Web 等不同平台底层窗口系统的差异。control.gd中几乎每个按钮回调都直接调用DisplayServer的方法例如func _on_button_move_to_pressed() - void: DisplayServer.window_set_position(Vector2(100, 100)) func _on_button_resize_pressed() - void: DisplayServer.window_set_size(Vector2(1280, 720))可以看出窗口操作 API 的命名遵循window_xxx前缀读取屏幕信息则使用screen_xxx前缀。理解这一命名规律后查阅 Godot 官方文档 中DisplayServer类的方法列表即可快速定位所需 API。窗口基本操作移动与调整大小移动窗口DisplayServer.window_set_position(position: Vector2i)将窗口移动到指定屏幕坐标单位像素。演示中 “Move To” 按钮将其固定移动至(100, 100)control.gdDisplayServer.window_set_position(Vector2(100, 100))对应地DisplayServer.window_get_position()用于读取当前窗口位置演示在_physics_process中每帧刷新到状态标签Label_Position上$Labels/Label_Position.text str(Position: , DisplayServer.window_get_position())设置窗口尺寸“Resize” 按钮演示了将窗口强制设置为 1280×720control.gdDisplayServer.window_set_size(Vector2(1280, 720))窗口当前尺寸通过DisplayServer.window_get_size()实时读取并显示在Label_Size标签中。注意在 Web 平台窗口尺寸由浏览器控制因此演示在_ready()中会禁用 Web 平台不支持的按钮见下文“平台兼容与特性检测”章节。窗口模式全屏、最小化、最大化与固定大小DisplayServer.window_set_mode(mode)用于切换窗口的显示模式模式取值通过DisplayServer.WINDOW_MODE_*枚举常量表示。演示中“Minimized / Maximized / Fullscreen”三个按钮均按“当前状态则恢复为窗口模式”的切换逻辑实现control.gdfunc _on_button_fullscreen_pressed() - void: if DisplayServer.window_get_mode() DisplayServer.WINDOW_MODE_FULLSCREEN: DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) else: DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN) func _on_button_minimized_pressed() - void: if DisplayServer.window_get_mode() DisplayServer.WINDOW_MODE_MINIMIZED: DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) else: DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MINIMIZED)相关模式枚举枚举常量含义WINDOW_MODE_WINDOWED普通窗口模式退出全屏/最小化/最大化时的默认恢复目标WINDOW_MODE_MINIMIZED最小化到任务栏WINDOW_MODE_MAXIMIZED最大化占满工作区WINDOW_MODE_FULLSCREEN全屏独占模式演示会在_physics_process中根据window_get_mode()与window_get_flag()动态拼接当前模式文本例如Mode: Fullscreen、Fixed Size、Minimized、Maximized实时反映窗口状态control.gd。固定大小禁止调整窗口尺寸是否允许用户拖拽调整窗口大小通过窗口标志位控制这是 Godot 4 中取代旧版OS.set_window_resizable()的机制control.gd 中亦以注释形式标注了这一 API 迁移func _on_button_fixed_size_pressed() - void: if DisplayServer.window_get_flag(DisplayServer.WINDOW_FLAG_RESIZE_DISABLED): DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_RESIZE_DISABLED, false) else: DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_RESIZE_DISABLED, true)DisplayServer.WINDOW_FLAG_RESIZE_DISABLED置true时禁止调整窗口大小DisplayServer.window_get_flag(...)读取当前标志状态用于按钮的 pressed 状态同步与模式文本拼接。在 project.godot 中窗口初始状态也通过项目设置配置window/resizabletrue、window/fullscreenfalse。透明窗口让窗口背景透出桌面透明窗口是该演示的亮点之一其实现分为两步视图端口透明get_viewport().transparent_bg true系统窗口透明标志DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_TRANSPARENT, true)。完整逻辑在 observer/observer.gd场景中的“Transparent”CheckButton 信号连接到该处func _on_transparent_check_button_toggled(button_pressed: bool) - void: if not DisplayServer.has_feature(DisplayServer.FEATURE_WINDOW_TRANSPARENCY): OS.alert(Window transparency is not supported by the current display server (%s). % DisplayServer.get_name()) return get_viewport().transparent_bg button_pressed DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_TRANSPARENT, button_pressed)这里有两个值得注意的工程细节能力探测优先在调用透明 API 之前先用DisplayServer.has_feature(DisplayServer.FEATURE_WINDOW_TRANSPARENCY)检测当前显示服务器是否支持透明窗口若不支持弹窗提示OS.alert并直接返回避免无效果调用或崩溃。这也是跨平台开发推荐的能力检查模式。项目级开关透明窗口需要项目配置允许逐像素透明见 project.godot 中的window/per_pixel_transparency/allowedtrue。若缺少该配置即使代码设置transparent_bg也不会生效。鼠标模式五种模式的切换与 3D 观察者演示演示提供了五种鼠标模式按钮并配了 F1~F5 快捷键见 window_management.tscn 中按钮文本与 project.godot 中的输入映射快捷键输入动作鼠标模式Input.mouse_mode行为F1mouse_mode_visibleMOUSE_MODE_VISIBLE显示鼠标F2mouse_mode_hiddenMOUSE_MODE_HIDDEN隐藏鼠标不移出屏幕F3mouse_mode_capturedMOUSE_MODE_CAPTURED捕获鼠标光标隐藏且被锁定在窗口中心F4mouse_mode_confinedMOUSE_MODE_CONFINED限制鼠标光标不离开窗口但可自由移动F5mouse_mode_confined_hiddenMOUSE_MODE_CONFINED_HIDDEN限制 隐藏组合切换实现非常直接control.gdfunc _on_button_mouse_mode_captured_pressed() - void: Input.mouse_mode Input.MOUSE_MODE_CAPTURED observer.state observer.State.GRAB同时_input()中通过Input.is_action_pressed(mouse_mode_visible)等动作判断将 F1~F5 与按钮回调绑定control.gd。注意_input对InputEventMouseMotion的处理演示保存了input_event.position作为鼠标位置并在状态标签中以%.4v格式化输出因为某些平台会报告浮点坐标保留四位小数可避免显示抖动control.gd。捕获模式下的 3D 观察者漫游MOUSE_MODE_CAPTURED是 FPS 类游戏最常用的模式。演示通过 observer/observer.gd 中的CharacterBody3D观察者展示了它的典型用法进入捕获模式后按下 WASD 移动、移动鼠标旋转视角按 ESCui_cancel释放鼠标回到菜单态。func _process(delta: float) - void: if state ! State.GRAB: return var x_movement : Input.get_axis(move_left, move_right) var z_movement : Input.get_axis(move_forward, move_backwards) var dir : direction(Vector3(x_movement, 0, z_movement)) transform.origin dir * 10 * delta var d : delta * 0.1 rotate(Vector3.UP, d * r_pos.x) # Yaw camera.transform camera.transform.rotated(Vector3.RIGHT, d * r_pos.y) # Pitch r_pos Vector2.ZERO关键点使用screen_relative而非position_input中取input_event.screen_relative计算视角增量使鼠标灵敏度与视口分辨率无关源码注释明确说明见 observer.gd并乘上MOUSE_SENSITIVITY 3.0ESC 切换捕获模式下按 ESC 恢复MOUSE_MODE_VISIBLE并回到菜单态再按一次重新捕获——这是标准的“暂停菜单”交互范式。屏幕信息多屏、DPI 与刷新率演示右侧标签区实时显示屏幕信息全部来自DisplayServer.screen_*系列 APIcontrol.gd$Labels/Label_Screen_Count.text str(Screen_Count: , DisplayServer.get_screen_count()) $Labels/Label_Screen_Current.text str(Screen: , DisplayServer.window_get_current_screen()) $Labels/Label_Screen0_Resolution.text str(Screen0 Resolution:\n, DisplayServer.screen_get_size()) $Labels/Label_Screen0_Position.text str(Screen0 Position:\n, DisplayServer.screen_get_position()) $Labels/Label_Screen0_DPI.text str(Screen0 DPI: , DisplayServer.screen_get_dpi())多屏处理当DisplayServer.get_screen_count() 1时演示动态显示第二屏相关的按钮与标签否则隐藏。多屏切换通过DisplayServer.window_set_current_screen(screen_index)实现control.gdfunc _on_button_screen_0_pressed() - void: DisplayServer.window_set_current_screen(0) func _on_button_screen_1_pressed() - void: DisplayServer.window_set_current_screen(1)各 API 的索引含义screen_get_size()/screen_get_position()/screen_get_dpi()/screen_get_refresh_rate()均接受屏幕索引参数默认 0即主屏。刷新率的性能注意事项代码中有一处值得注意的性能优化注释control.gd# See godotengine/godot#73563, fetching the refresh rate on every frame may be slow on some platforms. $Labels/Label_Screen0_RefreshRate.text Screen0 Refresh Rate: %.2f Hz % DisplayServer.screen_get_refresh_rate() if DisplayServer.get_screen_count() 1: $Labels/Label_Screen1_RefreshRate.text Screen1 Refresh Rate: %.2f Hz % DisplayServer.screen_get_refresh_rate(1)刷新率读取只在_ready()中执行一次而不是放进_physics_process原因是某些平台每次查询都会产生系统调用开销逐帧查询可能影响性能。这个教训对需要实时获取显示参数的高频逻辑具有普遍参考价值。平台兼容与特性检测优雅降级的三道防线跨平台窗口 API 在各平台实现程度不同演示项目专门编写了兼容性处理逻辑可作为移植参考第一道防线Web 平台功能裁剪在_ready()中若OS.has_feature(web)为真则禁用 Web 上不可用的按钮并追加提示文本control.gdif OS.has_feature(web): for button: BaseButton in [ $Buttons/Button_FixedSize, $Buttons/Button_Minimized, $Buttons/Button_Maximized, $Buttons/Button_MoveTo, $Buttons/Button_Resize, $Buttons/Button_MouseModeConfined, $Buttons/Button_MouseModeConfinedHidden, $CheckButton, ]: button.disabled true button.text (not supported on Web)禁用范围包括固定大小、最小化、最大化、Move To、Resize、两种 Confined 鼠标模式以及 Transparent 开关——这些操作在浏览器环境下由浏览器本身接管或不受支持。第二道防线运行时 API 能力探测check_wm_api()control.gd逐个使用DisplayServer.has_method(方法名)检查窗口管理 API 是否在目标平台实现若缺失则弹出ImplementationDialog列出缺失方法并关闭_physics_process与_input处理以避免空转func check_wm_api() - bool: var s: String if not DisplayServer.has_method(get_screen_count): s - get_screen_count()\n if not DisplayServer.has_method(window_get_current_screen): s - window_get_current_screen()\n # ...window_set_position / window_set_size / screen_get_dpi 等逐项检测 if s.length() 0: return true else: $ImplementationDialog/Text.text s $ImplementationDialog.show() return false该方法被_ready()调用if not check_wm_api(): set_physics_process(false); set_process_input(false)。第三道防线特性标志探测如透明窗口所示对于按“特性”分类的能力而非方法使用DisplayServer.has_feature(DisplayServer.FEATURE_WINDOW_TRANSPARENCY)探测并在不支持时给出用户可见的提示。值得注意的是旧版基于OS单例的窗口 API如OS.set_window_fullscreen()、OS.set_window_resizable()、OS.is_window_minimized()等已全部废弃演示以注释形式记录了这一迁移control.gd提醒开发者不要在新代码中使用旧 API。项目配置与场景结构project.godot 关键配置project.godot 中与窗口管理直接相关的配置项配置项值作用window/stretch/modecanvas_items2D UI 按画布内容缩放保证不同窗口尺寸下 UI 适配window/stretch/aspectexpand窗口尺寸变化时向两侧扩展可视区域window/per_pixel_transparency/allowedtrue允许逐像素透明窗口透明演示的前提window/vsync/vsync_mode0垂直同步模式0 为自动/默认window/fullscreenfalse启动时不进入全屏window/resizabletrue窗口默认可调整大小renderer/rendering_methodgl_compatibility使用 Compatibility 渲染器README 声明输入映射方面项目定义了mouse_mode_visible至mouse_mode_confined_hidden五个动作分别绑定 F1~F5 物理键键码4194332~4194336即 F1~F5以及move_forward/move_backwards/move_left/move_rightW/S/A/D 与方向键供 3D 观察者使用。场景与 UI 组织window_management.tscn 的场景层级体现了“3D 场景 2D 覆盖 UI”的典型结构WindowManagement (Node3D) ├── Observer (CharacterBody3D实例化 observer/observer.tscn含 Camera3D 与 OmniLight3D) ├── TestCube / TestCube2 (MeshInstance3D半透明噪点材质立方体) └── Control (全屏锚点挂载 control.gd) ├── Buttons (VBoxContainer)Fullscreen / Fixed Size / Minimized / Maximized / Move To / Resize / Screen0 / Screen1 / 五种鼠标模式按钮 / 快捷键提示标签 ├── Labels (VBoxContainer)Mode / Position / Size / Mouse Position / Screen 系列标签 ├── ImplementationDialog (AcceptDialog)API 缺失提示框 └── CheckButton Transparent透明开关信号连接到 Observer所有按钮的pressed信号在场景文件中显式连接到control.gd中对应的_on_button_xxx_pressed回调Transparent 开关的toggled信号则连接到observer.gd的_on_transparent_check_button_toggled——这展示了一条跨脚本协作的接线方式UI 信号既可以直接连接到同节点的脚本也可以连接到场景树中任意节点的脚本方法。快速参考常用 DisplayServer 窗口 API 一览操作API演示位置移动窗口window_set_position()/window_get_position()control.gd设置/读取尺寸window_set_size()/window_get_size()control.gd全屏/最小化/最大化window_set_mode()WINDOW_MODE_*control.gd固定大小window_set_flag(WINDOW_FLAG_RESIZE_DISABLED, ...)control.gd透明窗口get_viewport().transparent_bgWINDOW_FLAG_TRANSPARENTobserver.gd鼠标模式Input.mouse_mode MOUSE_MODE_*control.gd屏幕计数/切换get_screen_count()/window_set_current_screen()control.gd屏幕分辨率/位置/DPI/刷新率screen_get_size()/screen_get_position()/screen_get_dpi()/screen_get_refresh_rate()control.gd本文所有代码均取自该演示项目的真实源码读者可直接对照 control.gd、observer.gd、project.godot 与 window_management.tscn 逐步验证。这套“功能演示 状态实时回显 平台降级检测”的写法同样适用于为自己的游戏项目搭建窗口设置面板或调试工具。赞分享示例工程【免费下载链接】godot-demo-projectsDemonstration and Template Projects项目地址https://gitcode.com/GitHub_Trending/go/godot-demo-projects点击查看免费下载相关推荐强力JavaScript字符编码转换工具encoding.js解决多语言文本处理难题强力JavaScript字符编码转换工具encoding.js解决多语言文本处理难题 在现代Web开发中处理多语言文本编码是每个开发者都会遇到的挑战。JavRust窗口管理终极指南winit完整解析与应用实战Rust窗口管理终极指南winit完整解析与应用实战 winit是一个纯Rust编写的跨平台窗口处理库为开发者提供安全高效的窗口创建和管理解决方案。作为Ru桌面应用跨平台ADClusterMapView核心功能解析从标注聚类到动画效果全揭秘ADClusterMapView核心功能解析从标注聚类到动画效果全揭秘 ADClusterMapView是一个基于MKMapView的强大地图标注聚类框架专移动开发UI库/组件上一篇猫抓插件完整指南3步掌握浏览器资源嗅探下载技巧下一篇如何快速掌握猫抓浏览器扩展终极媒体资源嗅探与下载指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表