godot-platform-mobile

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Platform: Mobile

平台:移动设备

Touch-first input, safe area handling, and battery optimization define mobile development.
触控优先的输入方式、安全区域处理和电池优化是移动开发的核心要点。

Available Scripts

可用脚本

mobile_safe_area_handler.gd

mobile_safe_area_handler.gd

Expert safe area handling for notched screens using anchored margins.
利用锚定边距实现刘海屏的专业安全区域处理。

NEVER Do in Mobile Development

移动开发中的禁忌操作

  • NEVER use mouse events for touch
    InputEventMouseButton
    on mobile? Unreliable. Use
    InputEventScreenTouch
    +
    InputEventScreenDrag
    for touch.
  • NEVER ignore safe areas — UI behind iPhone notch = unusable. Call
    DisplayServer.get_display_safe_area()
    , offset UI by top/bottom insets.
  • NEVER keep 60 FPS when backgrounded — App in background @ 60 FPS = battery drain + store rejection. Set
    Engine.max_fps = 0
    on
    NOTIFICATION_APPLICATION_FOCUS_OUT
    .
  • NEVER use desktop UI sizes — 12pt font on phone = unreadable. Minimum 16-18pt for mobile. Use
    get_viewport().size
    to scale dynamically.
  • NEVER forget VRAM compression — Uncompressed textures on mobile = out of memory crash. Enable
    rendering/textures/vram_compression/import_etc2_astc=true
    in project.godot.
  • NEVER block main thread for saves — Saving large file on touch = freeze = ANR (Application Not Responding). Use
    FileAccess
    on worker thread.
  • NEVER ignore orientation changes — Game locked to portrait but device rotates? Jarring. Handle
    size_changed
    signal or specify
    window/handheld/orientation
    in project.godot.

gdscript
undefined
  • 绝对不要用鼠标事件处理触控 — 在移动设备上使用
    InputEventMouseButton
    ?不可靠。请使用
    InputEventScreenTouch
    +
    InputEventScreenDrag
    来处理触控操作。
  • 绝对不要忽略安全区域 — UI被iPhone刘海遮挡会导致无法使用。调用
    DisplayServer.get_display_safe_area()
    ,根据顶部/底部内边距偏移UI。
  • 绝对不要在后台保持60 FPS — 应用在后台以60 FPS运行会导致电池损耗+应用商店审核被拒。在收到
    NOTIFICATION_APPLICATION_FOCUS_OUT
    时设置
    Engine.max_fps = 0
  • 绝对不要使用桌面端UI尺寸 — 手机上用12pt字体完全无法阅读。移动端最小字体为16-18pt。使用
    get_viewport().size
    实现动态缩放。
  • 绝对不要忘记VRAM压缩 — 移动设备上使用未压缩纹理会导致内存不足崩溃。在project.godot中启用
    rendering/textures/vram_compression/import_etc2_astc=true
  • 绝对不要在主线程执行大文件保存 — 触控操作时在主线程保存大文件会导致应用冻结,触发ANR(应用无响应)。请在工作线程中使用
    FileAccess
  • 绝对不要忽略屏幕方向变化 — 游戏锁定为竖屏但设备旋转?会造成糟糕的用户体验。处理
    size_changed
    信号,或在project.godot中指定
    window/handheld/orientation

gdscript
undefined

Replace mouse/keyboard with touch

Replace mouse/keyboard with touch

func _input(event: InputEvent) -> void: if event is InputEventScreenTouch: if event.pressed: on_touch_start(event.position) else: on_touch_end(event.position)
elif event is InputEventScreenDrag:
    on_touch_drag(event.position, event.relative)
undefined
func _input(event: InputEvent) -> void: if event is InputEventScreenTouch: if event.pressed: on_touch_start(event.position) else: on_touch_end(event.position)
elif event is InputEventScreenDrag:
    on_touch_drag(event.position, event.relative)
undefined

Virtual Joystick

虚拟摇杆

gdscript
undefined
gdscript
undefined

virtual_joystick.gd

virtual_joystick.gd

extends Control
signal joystick_moved(direction: Vector2)
var is_pressed := false var center: Vector2 var touch_index := -1
func _gui_input(event: InputEvent) -> void: if event is InputEventScreenTouch: if event.pressed: is_pressed = true center = event.position touch_index = event.index elif event.index == touch_index: is_pressed = false joystick_moved.emit(Vector2.ZERO)
elif event is InputEventScreenDrag and event.index == touch_index:
    var direction := (event.position - center).normalized()
    joystick_moved.emit(direction)
undefined
extends Control
signal joystick_moved(direction: Vector2)
var is_pressed := false var center: Vector2 var touch_index := -1
func _gui_input(event: InputEvent) -> void: if event is InputEventScreenTouch: if event.pressed: is_pressed = true center = event.position touch_index = event.index elif event.index == touch_index: is_pressed = false joystick_moved.emit(Vector2.ZERO)
elif event is InputEventScreenDrag and event.index == touch_index:
    var direction := (event.position - center).normalized()
    joystick_moved.emit(direction)
undefined

Responsive UI

响应式UI

gdscript
undefined
gdscript
undefined

Adapt to screen size

Adapt to screen size

func _ready() -> void: get_viewport().size_changed.connect(_on_viewport_resized) _on_viewport_resized()
func _on_viewport_resized() -> void: var viewport_size := get_viewport().get_visible_rect().size var aspect := viewport_size.x / viewport_size.y
if aspect < 1.5:  # Tall screen
    $UI.layout_mode = VBoxContainer.LAYOUT_MODE_VERTICAL
else:  # Wide screen
    $UI.layout_mode = HBoxContainer.LAYOUT_MODE_HORIZONTAL
undefined
func _ready() -> void: get_viewport().size_changed.connect(_on_viewport_resized) _on_viewport_resized()
func _on_viewport_resized() -> void: var viewport_size := get_viewport().get_visible_rect().size var aspect := viewport_size.x / viewport_size.y
if aspect < 1.5:  # Tall screen
    $UI.layout_mode = VBoxContainer.LAYOUT_MODE_VERTICAL
else:  # Wide screen
    $UI.layout_mode = HBoxContainer.LAYOUT_MODE_HORIZONTAL
undefined

Battery Optimization

电池优化

gdscript
undefined
gdscript
undefined

Lower frame rate when inactive

Lower frame rate when inactive

func _notification(what: int) -> void: match what: NOTIFICATION_APPLICATION_FOCUS_OUT: Engine.max_fps = 30 NOTIFICATION_APPLICATION_FOCUS_IN: Engine.max_fps = 60
undefined
func _notification(what: int) -> void: match what: NOTIFICATION_APPLICATION_FOCUS_OUT: Engine.max_fps = 30 NOTIFICATION_APPLICATION_FOCUS_IN: Engine.max_fps = 60
undefined

Safe Areas (Notches)

安全区域(刘海屏适配)

gdscript
func apply_safe_area() -> void:
    var safe_area := DisplayServer.get_display_safe_area()
    
    # Adjust UI margins
    $UI.offset_top = safe_area.position.y
    $UI.offset_left = safe_area.position.x
gdscript
func apply_safe_area() -> void:
    var safe_area := DisplayServer.get_display_safe_area()
    
    # Adjust UI margins
    $UI.offset_top = safe_area.position.y
    $UI.offset_left = safe_area.position.x

Performance Settings

性能设置

ini
undefined
ini
undefined

project.godot mobile settings

project.godot mobile settings

[rendering] renderer/rendering_method="mobile" textures/vram_compression/import_etc2_astc=true
[display] window/handheld/orientation="landscape"
undefined
[rendering] renderer/rendering_method="mobile" textures/vram_compression/import_etc2_astc=true
[display] window/handheld/orientation="landscape"
undefined

App Store Metadata

应用商店元数据

  • Icons: 512x512 (Android), 1024x1024 (iOS)
  • Screenshots: Multiple resolutions
  • Privacy policy required
  • Age rating
  • 图标:512x512(Android),1024x1024(iOS)
  • 截图:需包含多种分辨率
  • 必须提供隐私政策
  • 年龄分级

Best Practices

最佳实践

  1. Touch-First - Design for fingers, not mouse
  2. Performance - Target 60 FPS on mid-range
  3. Battery - Reduce FPS when backgrounded
  4. Permissions - Request only what you need
  1. 触控优先 - 为手指操作设计,而非鼠标
  2. 性能优化 - 中端设备目标帧率60 FPS
  3. 电池友好 - 后台运行时降低帧率
  4. 权限最小化 - 仅申请必要权限

Reference

参考

  • Related:
    godot-export-builds
    ,
    godot-ui-containers
  • 相关内容:
    godot-export-builds
    ,
    godot-ui-containers

Related

相关技能

  • Master Skill: godot-master
  • 核心技能:godot-master