Cách triển khai cuộn song song trong Godot

Bạn có thể đạt được hiệu ứng hình ảnh cuộn song song ấn tượng chỉ bằng cách di chuyển đối tượng theo các hướng khác nhau. Dưới đây là hướng dẫn chi tiết.

Lập trình game

Parallax scrolling là một kỹ thuật mà nhiều game 2D dùng để tạo một hình ảnh chiều sâu và thêm sự thú vị về mặt hình ảnh cho background của game. Nó tạo hiệu ứng này bằng cách di chuyển các lớp background khác nhau theo các hướng tương quan với chuyển động camera.

Godot 4 khiến việc triển khai cuộn song song dễ dàng hơn bao giờ hết. Công cụ 2D mạnh mẽ của nó cung cấp sẵn hỗ trợ cho các lớp song song, cho phép bạn tạo hiệu ứng hình ảnh tuyệt vời mà không tốn nhiều công sức.

Thiết lập game Godot

Để bắt đầu, tạo dự án 2D mới trong công cụ game Godot và thiết lập cảnh game với một nhân vật người chơi.

Ở ví dụ này, thêm node CharacterBody2D cho chuyển động người chơi. Ngoài ra, thêm CollisionShape2D với hình chữ nhật và Sprite2D để đại diện cho nhân vật người chơi.

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)

Với code này, nhân vật người chơi có thể di chuyển sang trái, phải, lên và xuống bằng các phím mũi tên hoặc đầu vào tương tự.

Kết quả tạo game Godot đơn giản

Tạo các lớp khác nhau bằng node ParallaxLayer

Tiếp theo, tạo hiệu ứng song song bằng cách thêm nhiều node ParallaxLayer cho cảnh này. Mỗi ParallaxLayer sẽ đại diện cho một layer background khác. Để đạt được hiệu ứng song song tự nhiên, các layer ở xa máy ảnh nên di chuyển chậm hơn những layer ở gần.

Thêm node StaticBody2D với CollisionShape2D trong mỗi ParallaxLayer để tạo một số đối tượng có thể va chạm trong background. Những đối tượng có thể va chạm này sẽ tương tác với người chơi và các thành phần khác, thêm chiều sâu hơn vào gameplay.

Đây là code GDScript để tạo những layer song song với đối tượng có thể va chạm:

extends ParallaxBackground

func _ready():
    # Tạo layer song song đầu tiên
    var layer1 = ParallaxLayer.new()
    layer1.motion_scale = Vector2(0.2, 0.2)
    add_child(layer1)

    # Thêm StaticBody2D với CollisionShape2D vào layer đầu tiên
    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)

    # Tạo layer song song thứ hai
    var layer2 = ParallaxLayer.new()
    layer2.motion_scale = Vector2(0.5, 0.5)
    add_child(layer2)

    # Thêm StaticBody2D với CollisionShape2D vào layer thứ hai
    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)

    # Tạo layer song song thứ ba
    var layer3 = ParallaxLayer.new()
    layer3.motion_scale = Vector2(1.0, 1.0)
    add_child(layer3)

    # Thêm StaticBody2D với CollisionShape2D vào layer thứ ba
    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)

Với code này, mỗi layer parallax giờ chứa node StaticBody2D cùng một CollisionShape2D đại diện cho các đối tượng có thể va chạm trên nền.

Những đối tượng có thể va chạm này sẽ tương tác với nhân vật người chơi và các thành phần khác trong game. Điều này làm tăng chiều sâu và độ phức tạp cho gameplay.

Di chuyển layer với tốc độ khác nhau

Giờ các layer song song đã được thiết lập, bạn cần update vị trí của chúng dựa trên chuyển động của người chơi. Điều này sẽ tạo hiệu ứng song song, tại layer gần camera hơn sẽ di chuyển nhanh hơn những lớp ở xa.

Thêm code GDScript sau vào cảnh Player:

extends CharacterBody2D

func _physics_process(delta):
    ...
    move_and_collide(velocity * delta)

    # Update layer parallax dựa trên chuyển động của người chơi
    var parallax_background = get_parent()
    var motion = -velocity * delta
    parallax_background.set_scroll_offset(parallax_background.scroll_offset + motion)

Code này tính toán chuyển động của layer song song dựa trên chuyển động của người chơi và update offset cuộn của node ParallaxBackground tương ứng. Lưu ý, dùng ký hiệu trừ để đảm bảo các lớp di chuyển theo hướng đối lập với chuyển động của người chơi.

Thêm hướng chuyển động khác nhau

Thêm yếu tố bất ngờ vào cuộn song song ngẫu nhiên

Cuộn song song ngẫu nhiên giới thiệu một thành phần gây bất ngờ và khó dự đoán cho background của game. Bằng cách linh động trong việc tạo và xác định vị trí những layer song song trong suốt gameplay, bạn có thể tạo trải nghiệm hấp dẫn và năng động hơn cho người chơi.

Để triển khai cuộn song song ngẫu nhiên, thêm các layer song song mới với tỷ lệ và vị trí chuyển động ngẫu nhiên.

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():
    # Thêm layer parallax mới với tỷ lệ chuyển động ngẫu nhiên
    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)

    # Thêm StaticBody2D với CollisionShape2D vào layer mới
    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():
    # Loại bỏ layer song song ngẫu nhiên
    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)

Code này xác định các hằng số kiểm soát ngẫu nhiên những layer song song. Dùng hàm lerp để nội suy những giá trị nằm giữa MIN_SCALE MAX_SCALE, tạo thang chuyển động ngẫu nhiên cho mỗi layer mới. Hàm này có signature sau:

Variant lerp ( Variant from, Variant to, float weight )

Chuyển kết quả từ randf() dưới dạng trọng số cho phép bạn tạo layer có tỷ lệ ngẫu nhiên.

Hàm randf_range cung cấp cách khác để tạo những giá trị ngẫu nhiên trong một phạm vi. Tại đây, hàm create_random_layer dùng nó để tạo những vị trí ngẫu nhiên cho các layer mới trong một phạm vi cụ thể.

var x_position = randf_range(MIN_X_POSITION, MAX_X_POSITION)

Kết quả, bạn sẽ có game như sau:

Kết quả game mẫu có hiệu ứng cuộn song song

Trên đây là cách tạo hiệu ứng cuộn song song cho game phát triển trong Godot. Hi vọng bài viết hữu ích với các bạn.

Thứ Hai, 21/08/2023 16:34
51 👨 139
0 Bình luận
Sắp xếp theo