如何在 Godot 中實現視差滾動
視差滾動是許多 2D 遊戲用來創建深度錯覺並為遊戲背景增添視覺趣味的技術。它通過相對於相機運動以不同的速度移動背景的不同層來實現效果。
Godot 4 提供了一種通過其強大的 2D 引擎實現視差滾動的無縫方法,該引擎融合了對視差層的固有支持,使開發人員能夠以最小的努力實現迷人的視覺效果。
設置戈多遊戲
要啟動該過程,請在 Godot 遊戲引擎的框架內建立一個新穎的二維項目,並通過將玩家角色納入其主要元素之一來配置遊戲環境。
本出版物中使用的代碼可以通過 GitHub 存儲庫訪問,該存儲庫根據 MIT 許可證條款免費授予其使用權限。
為了演示使用 C# 在 Unity 引擎中實現玩家移動,必須向場景中添加額外的節點。具體來說,應包含“CharacterBody2D”對象,以促進玩家與環境中其他對象之間的物理交互。此外,“CollisionShape2D”組件應附加到主體上,它將定義碰撞區域的形狀並允許適當檢測與其他對象的碰撞。最後,“Sprite2D”對象可以用作屏幕上玩家角色的視覺表示。
extends CharacterBody2D
var speed = 200
func _physics_process(delta):
var velocity = Vector2()
if Input.is_action_pressed('ui_right'):
velocity.x \+= 1
if Input.is_action_pressed('ui_left'):
velocity.x -= 1
if Input.is_action_pressed('ui_down'):
velocity.y \+= 1
if Input.is_action_pressed('ui_up'):
velocity.y -= 1
velocity = velocity.normalized() * speed
move_and_collide(velocity * delta)
此代碼使玩家角色能夠通過使用箭頭鍵在任何方向(包括向左、向右、向上和向下)移動來在水平面中導航。
使用 ParallaxLayer 節點創建不同的圖層
要在三維環境中生成視差效果,需要在場景中合併“ParallaxLayer”類的多個實例。這些附加層將共同形成構成背景的不同元素。為了使深度的視覺表示顯得真實和逼真,至關重要的是,離觀察者較遠的層的移動速度比離觀察者較近的層的移動速度要慢。
通過將 StaticBody2D 實體附加到 CollisionShape2D 對象,將它們合併到每個 ParallaxLayer 中,從而生成與玩家和其他遊戲組件互連的交互式背景元素,通過它們的交互增強整體遊戲體驗。
提供的 GDScript 代碼通過利用可碰撞對象與分層元素結合生成視差效果,從而在指定的矩形區域內實現它們之間的交互和碰撞檢測。
extends ParallaxBackground
func _ready():
# Create the first parallax layer
var layer1 = ParallaxLayer.new()
layer1.motion_scale = Vector2(0.2, 0.2)
add_child(layer1)
# Add a StaticBody2D with CollisionShape2D to the first layer
var static_body1 = StaticBody2D.new()
layer1.add_child(static_body1)
var collision_shape1 = CollisionShape2D.new()
var shape1 = RectangleShape2D.new()
shape1.extents = Vector2(32, 32)
collision_shape1.shape = shape1
static_body1.add_child(collision_shape1)
# Create the second parallax layer
var layer2 = ParallaxLayer.new()
layer2.motion_scale = Vector2(0.5, 0.5)
add_child(layer2)
# Add a StaticBody2D with CollisionShape2D to the second layer
var static_body2 = StaticBody2D.new()
layer2.add_child(static_body2)
var collision_shape2 = CollisionShape2D.new()
var shape2 = RectangleShape2D.new()
shape2.extents = Vector2(64, 64)
collision_shape2.shape = shape2
static_body2.add_child(collision_shape2)
# Create the third parallax layer
var layer3 = ParallaxLayer.new()
layer3.motion_scale = Vector2(1.0, 1.0)
add_child(layer3)
# Add a StaticBody2D with CollisionShape2D to the third layer
var static_body3 = StaticBody2D.new()
layer3.add_child(static_body3)
var collision_shape3 = CollisionShape2D.new()
var shape3 = RectangleShape2D.new()
shape3.extents = Vector2(128, 128)
collision_shape3.shape = shape3
static_body3.add_child(collision_shape3)
利用此實現,每個視差層都配備了一個 StaticBody2D 實體,該實體具有 CollisionShape2D 組件,用於表示駐留在背景中的可辨別元素。
這些可折疊實體的交互性質將吸引玩家的化身和各種遊戲內組件,從而增強遊戲體驗的整體複雜性和細微差別。
以不同的速度移動不同的層
為了在Unity中實現視差效果,必鬚根據玩家的動作調整每一層相對於相機的位置。通過這樣做,與距離較遠的層相比,距離相機較近的層看起來移動速度更快,從而產生深度和運動的錯覺。
將以下 GDScript 代碼合併到 Player 場景中,如下所示:
extends CharacterBody2D
func _physics_process(delta):
...
move_and_collide(velocity * delta)
# Update parallax layers based on player movement
var parallax_background = get_parent()
var motion = -velocity * delta
parallax_background.set_scroll_offset(parallax_background.scroll_offset \+ motion)
本實現執行與視差層相關的運動的評估,這取決於用戶的位移,並因此修改 ParallaxBackground 組件的滾動偏移。需要注意的是,使用負號來保證層的移動方向與用戶的重新定位相反。
通過隨機視差滾動添加不可預測性
視差滾動是一種通過在整個遊戲過程中不斷生成和重新定位多個圖層,為視頻遊戲的背景添加意想不到和不可預見的方面的技術。事實證明,這種方法可以提高玩家的參與度,並有助於營造更具吸引力和不斷變化的遊戲環境。
為了將任意視差滾動合併到視覺合成中,有必要引入具有不同程度的位移幅度和不可預測的空間方向的附加視差層。
extends ParallaxBackground
const MAX_LAYERS = 5
const MIN_SCALE = 0.2
const MAX_SCALE = 1.5
const MIN_SPEED = 0.01
const MAX_SPEED = 0.03
const MIN_X_POSITION = -500
const MAX_X_POSITION = 500
const MIN_Y_POSITION = -300
const MAX_Y_POSITION = 300
func _ready():
for i in range(MAX_LAYERS):
create_random_layer()
func create_random_layer():
# Add a new parallax layer with a random motion scale
var layer = ParallaxLayer.new()
var scale = lerp(MIN_SCALE, MAX_SCALE, randf())
layer.motion_scale = Vector2(scale, scale)
var x_position = randf_range(MIN_X_POSITION, MAX_X_POSITION)
var y_position = randf_range(MIN_Y_POSITION, MAX_Y_POSITION)
layer.global_transform.origin.x = x_position
layer.global_transform.origin.y = y_position
add_child(layer)
# Add a StaticBody2D with CollisionShape2D to the new layer
var static_body = StaticBody2D.new()
layer.add_child(static_body)
var collision_shape = CollisionShape2D.new()
var shape = RectangleShape2D.new()
shape.extents = Vector2(32, 32)
collision_shape.shape = shape
static_body.add_child(collision_shape)
func remove_random_layer():
# Remove a random parallax layer
if get_child_count() > 0:
var random_index = randi() % get_child_count()
var layer_to_remove = get_child(random_index)
remove_child(layer_to_remove)
本代碼建立恆定參數來調節視差層的不可預測性,利用 lerp 函數在最小和最大尺度範圍內插值。後者的特點是其具體名稱如下:
Variant lerp ( Variant from, Variant to, float weight )
利用 randf() 函數的輸出作為權重,可以創建具有隨機縮放值的層。
randf_range 函數是生成特定範圍內的隨機數的另一種方法。在這種情況下,create\_random\_layer
函數利用它為新添加的層生成任意坐標,限制在預定義的範圍內:
var x_position = randf_range(MIN_X_POSITION, MAX_X_POSITION)
事實上,演示遊戲看起來具有視覺吸引力且組織良好,具有時尚的佈局和促進用戶參與的互動元素。該設計融合了各種圖形資源,例如圖像和圖標,有助於打造整體精美的外觀。此外,空白的使用有效地創造了平衡的構圖,增強了可讀性並為用戶帶來了乾淨的視覺體驗。總體而言,演示遊戲展示了強大的設計原則,並展示了交互性、圖形和排版的無縫集成。
包括附加功能
視差滾動是提昇平台遊戲視覺吸引力的絕佳起點,但仍有機會通過整合補充元素進一步完善。以下建議可酌情採納。
背景對象
考慮在視差場景中加入額外的動態組件,包括懸浮景觀、移動障礙物或動畫背景角色。這些功能的集成可以增強平台體驗的維度和用戶參與度。
動態照明
考慮將動態光照效果合併到視差層中,以增加遊戲世界的真實感和深度。通過 Godot 先進的照明系統利用光源和陰影可以極大地提高 2D 遊戲的整體視覺質量。
粒子效果
將粒子系統融入視差層可以產生精緻的視覺現象,例如落葉、浮雲或閃爍的天體,從而增強視頻遊戲環境的大氣環境並賦予其活力感。此外,您可以將免許可的音頻效果合併到您的遊戲中,進一步增強其整體吸引力。
晝夜循環
在視差層中融入晝夜循環,根據遊戲時間改變其色調和亮度,為玩家在整個遊戲旅程中導航創造一個不斷變化的環境。
實現視差滾動的最佳實踐
為了在視頻遊戲中有效利用視差滾動,同時保持無縫且愉快的用戶體驗,堅持某些可促進最佳性能和整體滿意度的最佳實踐至關重要。
性能優化
請注意視差層的擴散及其複雜性。過多的層或高分辨率的圖形可能會導致功能缺陷,特別是在動力不足的設備上。建議盡可能簡化視覺效果並採用減少碰撞的幾何形狀,以保持最佳性能。
層排列
在安排視差層時,重要的是要注意它們的視覺層次結構和它們創建的所需深度效果。為了在設計中創造深度感和運動感,讓最靠近相機的層比距離較遠的層以更快的速度移動是有效的。
相機邊界
為了保證流暢、不間斷的遊戲體驗,必須對虛擬環境中攝像頭的移動建立限制。通過這樣做,我們可以避免當玩家接近遊戲世界邊緣時可能出現的任何不必要的空白或技術問題。
測試和調整
為了保證視差滾動在各種設備和屏幕分辨率上的最佳性能和外觀,必須在多個平台上測試設計。通過調整運動比例、層的位置和其他相關變量,可以細化視差效果以實現最理想的結果。
通過視差滾動讓 Godot 遊戲更具吸引力
結合不可預測的視差滾動效果可以顯著提高用戶對 Godot 遊戲的參與度。這種技術稱為隨機視差滾動,可動態生成並定位多個圖層,以創造身臨其境的遊戲體驗。
通過程序生成技術融入動態環境可以在遊戲環境中喚起一種運動和活力的感覺,從而為其註入一種自發性和不可預見性的氛圍。這種不斷變化的視覺背景為玩家的遊戲之旅提供了額外的驚心動魄的維度,從而增強了玩家的沉浸感。