Loading...
Loading...
Compare original and translation side by side
MANDATORY: Read the appropriate script before implementing the corresponding pattern.
强制要求:在实现对应方案前,请先阅读相应脚本。
| Genre | Recommended Control | Example |
|---|---|---|
| Platformer | Virtual joystick (left) + jump button (right) | Super Mario Run |
| Top-down shooter | Dual-stick (move left, aim right) | Brawl Stars |
| Turn-based | Direct tap on units/tiles | Into the Breach |
| Puzzle | Tap, swipe, pinch gestures | Candy Crush |
| Card game | Drag-and-drop | Hearthstone |
| Racing | Tilt steering or tap left/right | Asphalt 9 |
| 游戏类型 | 推荐控制方式 | 示例 |
|---|---|---|
| 平台跳跃类 | 左侧虚拟摇杆 + 右侧跳跃按钮 | 《超级马里奥酷跑》 |
| 俯视角射击类 | 双摇杆(左摇杆移动,右摇杆瞄准) | 《荒野乱斗》 |
| 回合制策略类 | 直接点击单位/格子 | 《陷阵之志》 |
| 益智解谜类 | 点击、滑动、捏合手势 | 《糖果传奇》 |
| 卡牌类 | 拖拽操作 | 《炉石传说》 |
| 赛车类 | 重力感应或点击左右 | 《狂野飙车9》 |
undefinedundefinedelif event is InputEventScreenDrag and event.index == touch_index:
update_knob(event.position)# Clamp to max distance
if offset.length() > max_distance:
offset = offset.normalized() * max_distance
knob.position = stick_center + offset
# Calculate direction (-1 to 1)
var direction := offset / max_distance
if direction.length() < dead_zone:
direction = Vector2.ZERO
direction_changed.emit(direction)undefinedelif event is InputEventScreenDrag and event.index == touch_index:
update_knob(event.position)# Clamp to max distance
if offset.length() > max_distance:
offset = offset.normalized() * max_distance
knob.position = stick_center + offset
# Calculate direction (-1 to 1)
var direction := offset / max_distance
if direction.length() < dead_zone:
direction = Vector2.ZERO
direction_changed.emit(direction)undefinedundefinedundefinedelif event is InputEventScreenDrag:
_handle_drag(event)var start_data = touch_start[event.index]
var distance := event.position.distance_to(start_data.position)
var duration := (Time.get_ticks_msec() * 0.001) - start_data.time
# Tap detection
if distance < TAP_MAX_DISTANCE and duration < TAP_MAX_DURATION:
tap_detected.emit(event.position)
# Swipe detection
elif distance > SWIPE_THRESHOLD:
var direction := (event.position - start_data.position).normalized()
swipe_detected.emit(direction)
touch_start.erase(event.index) var current_distance := positions[0].distance_to(positions[1])
if pinch_start_distance == 0.0:
pinch_start_distance = current_distance
else:
var scale := current_distance / pinch_start_distance
pinch_detected.emit(scale)
pinch_start_distance = current_distance
---elif event is InputEventScreenDrag:
_handle_drag(event)var start_data = touch_start[event.index]
var distance := event.position.distance_to(start_data.position)
var duration := (Time.get_ticks_msec() * 0.001) - start_data.time
# Tap detection
if distance < TAP_MAX_DISTANCE and duration < TAP_MAX_DURATION:
tap_detected.emit(event.position)
# Swipe detection
elif distance > SWIPE_THRESHOLD:
var direction := (event.position - start_data.position).normalized()
swipe_detected.emit(direction)
touch_start.erase(event.index) var current_distance := positions[0].distance_to(positions[1])
if pinch_start_distance == 0.0:
pinch_start_distance = current_distance
else:
var scale := current_distance / pinch_start_distance
pinch_detected.emit(scale)
pinch_start_distance = current_distance
---undefinedundefined# Adjust for different aspect ratios
if aspect_ratio > 2.0: # Ultra-wide (tablets in landscape)
scale_ui_for_tablet()
elif aspect_ratio < 0.6: # Tall (phones in portrait)
scale_ui_for_phone()
# Adjust touch button sizes
for button in get_tree().get_nodes_in_group("touch_buttons"):
var min_size := 88 # 44pt * 2 for Retina
button.custom_minimum_size = Vector2(min_size, min_size)
---# Adjust for different aspect ratios
if aspect_ratio > 2.0: # Ultra-wide (tablets in landscape)
scale_ui_for_tablet()
elif aspect_ratio < 0.6: # Tall (phones in portrait)
scale_ui_for_phone()
# Adjust touch button sizes
for button in get_tree().get_nodes_in_group("touch_buttons"):
var min_size := 88 # 44pt * 2 for Retina
button.custom_minimum_size = Vector2(min_size, min_size)
---undefinedundefined# Lower shadow quality
RenderingServer.directional_shadow_atlas_set_size(2048, false) # Down from 4096
# Reduce particle counts
for particle in get_tree().get_nodes_in_group("godot-particles"):
if particle is GPUParticles2D:
particle.amount = max(10, particle.amount / 2)
# Lower physics tick rate
Engine.physics_ticks_per_second = 30 # Down from 60
# Disable expensive effects
var env := get_viewport().world_3d.environment
if env:
env.glow_enabled = false
env.ssao_enabled = false
env.ssr_enabled = falseundefined# Lower shadow quality
RenderingServer.directional_shadow_atlas_set_size(2048, false) # Down from 4096
# Reduce particle counts
for particle in get_tree().get_nodes_in_group("godot-particles"):
if particle is GPUParticles2D:
particle.amount = max(10, particle.amount / 2)
# Lower physics tick rate
Engine.physics_ticks_per_second = 30 # Down from 60
# Disable expensive effects
var env := get_viewport().world_3d.environment
if env:
env.glow_enabled = false
env.ssao_enabled = false
env.ssr_enabled = falseundefinedundefinedundefined if current_fps < target_fps - 10 and quality_level > 0:
quality_level -= 1
apply_quality(quality_level)
elif current_fps > target_fps + 5 and quality_level < 2:
quality_level += 1
apply_quality(quality_level)
timer = 0.0
--- if current_fps < target_fps - 10 and quality_level > 0:
quality_level -= 1
apply_quality(quality_level)
elif current_fps > target_fps + 5 and quality_level < 2:
quality_level += 1
apply_quality(quality_level)
timer = 0.0
---undefinedundefined# Pause physics
get_tree().paused = true
# Stop audio
AudioServer.set_bus_mute(AudioServer.get_bus_index("Master"), true)# Resume
get_tree().paused = false
AudioServer.set_bus_mute(AudioServer.get_bus_index("Master"), false)
---# Pause physics
get_tree().paused = true
# Stop audio
AudioServer.set_bus_mute(AudioServer.get_bus_index("Master"), true)# Resume
get_tree().paused = false
AudioServer.set_bus_mute(AudioServer.get_bus_index("Master"), false)
---undefinedundefined # Adjust UI margins
$TopBar.position.y = safe_area.position.y
$BottomControls.position.y = viewport_size.y - safe_area.end.y - 100undefined # Adjust UI margins
$TopBar.position.y = safe_area.position.y
$BottomControls.position.y = viewport_size.y - safe_area.end.y - 100undefinedfunc trigger_haptic(intensity: float) -> void:
if OS.has_feature("mobile"):
# Android
if OS.get_name() == "Android":
var duration_ms := int(intensity * 100)
OS.vibrate_handheld(duration_ms)
# iOS (requires plugin)
# Use third-party plugin for iOS hapticsfunc trigger_haptic(intensity: float) -> void:
if OS.has_feature("mobile"):
# Android
if OS.get_name() == "Android":
var duration_ms := int(intensity * 100)
OS.vibrate_handheld(duration_ms)
# iOS (requires plugin)
# Use third-party plugin for iOS hapticsundefinedundefined
---
---undefinedundefinedundefinedundefinedundefinedundefinedreturn (position.x > edge_margin and
position.x < viewport_size.x - edge_margin and
position.y > edge_margin and
position.y < viewport_size.y - edge_margin)
---return (position.x > edge_margin and
position.x < viewport_size.x - edge_margin and
position.y > edge_margin and
position.y < viewport_size.y - edge_margin)
---