Contents

วิธีการใช้ Parallax Scrolling ใน Godot

การเลื่อนพารัลแลกซ์เป็นเทคนิคที่เกม 2 มิติหลายเกมใช้เพื่อสร้างภาพลวงตาของความลึกและเพิ่มความน่าสนใจทางภาพให้กับพื้นหลังของเกม บรรลุผลโดยการย้ายเลเยอร์ต่างๆ ของพื้นหลังด้วยความเร็วที่แตกต่างกันตามการเคลื่อนไหวของกล้อง

Godot 4 นำเสนอวิธีการที่ไร้รอยต่อในการปรับใช้การเลื่อนพารัลแลกซ์ผ่านเอ็นจิ้น 2 มิติอันแข็งแกร่ง ซึ่งรวมการรองรับเลเยอร์พารัลแลกซ์โดยธรรมชาติ ช่วยให้นักพัฒนาสามารถบรรลุเอฟเฟกต์ภาพที่น่าดึงดูดใจโดยออกแรงน้อยที่สุด

การตั้งค่าเกม Godot

ในการเริ่มต้นกระบวนการ ให้สร้างโปรเจ็กต์สองมิติที่แปลกใหม่ภายในเฟรมเวิร์กของเอ็นจิ้นเกม Godot และกำหนดค่าสภาพแวดล้อมของเกมโดยการรวมเอาบุคลิกของผู้เล่นเป็นหนึ่งในองค์ประกอบหลัก

รหัสที่ใช้ในสิ่งพิมพ์นี้สามารถเข้าถึงได้ผ่านที่เก็บ GitHub ซึ่งให้สิทธิ์ในการใช้งานโดยไม่มีค่าใช้จ่ายภายใต้เงื่อนไขของใบอนุญาต MIT

เพื่อสาธิตการใช้งานการเคลื่อนไหวของผู้เล่นภายในเอนจิ้น Unity โดยใช้ C# จะต้องเพิ่มโหนดเพิ่มเติมในฉาก โดยเฉพาะอย่างยิ่ง ควรรวมวัตถุ 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)

รหัสนี้ช่วยให้ตัวละครของผู้เล่นสามารถนำทางในระนาบแนวนอนได้โดยใช้ปุ่มลูกศรเพื่อเคลื่อนที่ไปในทิศทางใดก็ได้ รวมทั้งซ้าย ขวา ขึ้น และลง

/th/images/simple-player-in-godot-game-1.jpg

การสร้างเลเยอร์ต่างๆ ด้วยโหนด ParallaxLayer

ในการสร้างเอฟเฟกต์พารัลแลกซ์ในสภาพแวดล้อมสามมิติ จำเป็นต้องรวมอินสแตนซ์ของคลาส ParallaxLayer หลายอินสแตนซ์ไว้ในฉาก เลเยอร์เพิ่มเติมเหล่านี้จะรวมกันเป็นองค์ประกอบที่หลากหลายซึ่งประกอบกันเป็นฉากหลัง เพื่อให้การแสดงความลึกของภาพดูสมจริงและสมจริง จำเป็นอย่างยิ่งที่จะต้องย้ายเลเยอร์ที่อยู่ห่างจากผู้ชมในอัตราที่ช้ากว่าเลเยอร์ที่อยู่ใกล้กว่า

รวมเอนทิตี StaticBody2D ภายใน ParallaxLayer แต่ละอันโดยแนบกับวัตถุ CollisionShape2D ซึ่งจะสร้างองค์ประกอบพื้นหลังแบบโต้ตอบที่เชื่อมต่อกับผู้เล่นและส่วนประกอบเกมเพิ่มเติม ยกระดับประสบการณ์การเล่นเกมโดยรวมผ่านการโต้ตอบ

โค้ด 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) 

การใช้งานปัจจุบันทำการประเมินการเคลื่อนไหวที่เกี่ยวข้องกับพารัลแลกซ์เลเยอร์ ซึ่งขึ้นอยู่กับการกระจัดของผู้ใช้ และแก้ไขการชดเชยการเลื่อนขององค์ประกอบพารัลแลกซ์แบ็คกราวด์ สิ่งสำคัญคือต้องสังเกตว่ามีการใช้เครื่องหมายลบเพื่อรับประกันว่าเลเยอร์จะเคลื่อนที่ไปในทิศทางตรงกันข้ามกับการย้ายตำแหน่งของผู้ใช้

/th/images/parallax-in-godot.jpg

เพิ่มความคาดเดาไม่ได้ด้วยการเลื่อนพารัลแลกซ์แบบสุ่ม

การเลื่อนพารัลแลกซ์เป็นเทคนิคที่เพิ่มลักษณะที่คาดไม่ถึงและคาดไม่ถึงให้กับพื้นหลังของวิดีโอเกม โดยการสร้างและเปลี่ยนตำแหน่งหลายเลเยอร์อย่างต่อเนื่องตลอดเวลาที่เล่น วิธีนี้ได้รับการพิสูจน์แล้วว่าช่วยเพิ่มการมีส่วนร่วมของผู้เล่นและนำไปสู่สภาพแวดล้อมในเกมที่น่าดึงดูดใจและเปลี่ยนแปลงตลอดเวลา

ในการรวมการเลื่อนพารัลแลกซ์โดยพลการไว้ในองค์ประกอบภาพ จำเป็นต้องแนะนำเลเยอร์พารัลแลกซ์เพิ่มเติมซึ่งมีระดับขนาดการกระจัดที่แตกต่างกันและการวางแนวเชิงพื้นที่ที่คาดเดาไม่ได้

 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) 

แท้จริงแล้ว เกมสาธิตดูเหมือนจะดึงดูดสายตาและมีการจัดระเบียบที่ดี โดยมีเลย์เอาต์ที่ทันสมัยพร้อมองค์ประกอบแบบอินเทอร์แอคทีฟที่เอื้อต่อการมีส่วนร่วมของผู้ใช้ การออกแบบรวมเอาเนื้อหากราฟิกต่างๆ เช่น รูปภาพและไอคอน ซึ่งช่วยให้ดูสวยงามโดยรวม นอกจากนี้ การใช้ช่องว่างอย่างมีประสิทธิภาพจะสร้างองค์ประกอบที่สมดุล เพิ่มความสามารถในการอ่านและส่งเสริมประสบการณ์การมองเห็นที่สะอาดตาสำหรับผู้ใช้ โดยรวมแล้ว เกมสาธิตแสดงหลักการออกแบบที่แข็งแกร่งและนำเสนอการผสานการโต้ตอบ กราฟิก และการพิมพ์ที่ไร้รอยต่อ

/th/images/random-parallax-in-godot.jpg

รวมถึงคุณสมบัติเพิ่มเติม

การเลื่อนแบบพารัลแลกซ์ทำหน้าที่เป็นจุดเริ่มต้นที่ยอดเยี่ยมในการยกระดับเสน่ห์ทางสายตาของเกม platformer แต่ยังมีโอกาสสำหรับการปรับแต่งเพิ่มเติมผ่านการรวมองค์ประกอบเสริม คำแนะนำต่อไปนี้อาจใช้ภายใต้คำแนะนำ

วัตถุพื้นหลัง

พิจารณาการรวมองค์ประกอบไดนามิกเพิ่มเติมภายในฉากพารัลแลกซ์ของคุณ รวมถึงทิวทัศน์ที่ถูกระงับ สิ่งกีดขวางเคลื่อนที่ หรือตัวละครฉากหลังที่เคลื่อนไหวได้ การรวมคุณสมบัติเหล่านี้อาจเพิ่มมิติและการมีส่วนร่วมของผู้ใช้สำหรับประสบการณ์การสร้างแพลตฟอร์มของคุณ

แสงแบบไดนามิก

พิจารณารวมเอฟเฟกต์แสงแบบไดนามิกเข้ากับเลเยอร์พารัลแลกซ์ของคุณเพื่อเพิ่มเลเยอร์ของความสมจริงและความลึกในโลกของเกมของคุณ การใช้แหล่งกำเนิดแสงและเงาผ่านระบบแสงขั้นสูงของ Godot สามารถปรับปรุงคุณภาพภาพโดยรวมของเกม 2 มิติของคุณได้อย่างมาก

ผลกระทบของอนุภาค

การรวมระบบอนุภาคภายในเลเยอร์พารัลแลกซ์สามารถสร้างปรากฏการณ์ทางภาพที่ละเอียดอ่อน เช่น ใบไม้ร่วง เมฆลอย หรือเทห์ฟากฟ้าที่ส่องแสงเป็นประกาย ซึ่งจะทำให้สภาพแวดล้อมในบรรยากาศของวิดีโอเกมสูงขึ้นและทำให้บรรยากาศมีชีวิตชีวา นอกจากนี้ คุณอาจใส่เอฟเฟ็กต์เสียงที่ได้รับการยกเว้นใบอนุญาตลงในเกมของคุณ เพื่อเพิ่มเสน่ห์โดยรวม

รอบกลางวันและกลางคืน

รวมวัฏจักรกลางวันและกลางคืนไว้ในเลเยอร์พารัลแลกซ์เพื่อเปลี่ยนสีและความส่องสว่างตามเวลาของเกม สร้างสภาพแวดล้อมที่เปลี่ยนแปลงตลอดเวลาเพื่อให้ผู้เล่นนำทางตลอดเส้นทางการเล่นเกม

แนวทางปฏิบัติที่ดีที่สุดสำหรับการใช้ Parallax Scrolling

ในการใช้การเลื่อนพารัลแลกซ์ในวิดีโอเกมอย่างมีประสิทธิภาพในขณะที่ยังคงรักษาประสบการณ์การใช้งานที่ราบรื่นและน่าพึงพอใจ สิ่งสำคัญคือต้องปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดบางประการที่ส่งเสริมประสิทธิภาพสูงสุดและความพึงพอใจโดยรวม

การเพิ่มประสิทธิภาพการทำงาน

โปรดระวังการแพร่กระจายของพารัลแลกซ์เลเยอร์รวมถึงความซับซ้อนของมัน ปริมาณเลเยอร์ที่มากเกินไปหรือกราฟิกที่มีความละเอียดสูงอาจทำให้การทำงานขาดตกบกพร่อง โดยเฉพาะอย่างยิ่งบนอุปกรณ์ที่ใช้พลังงานน้อย ขอแนะนำให้ปรับปรุงภาพของคุณ และใช้รูปทรงเรขาคณิตที่ลดการชนกันในทุกที่ที่ทำได้เพื่อรักษาประสิทธิภาพสูงสุด

การจัดเรียงเลเยอร์

เมื่อจัดเรียงเลเยอร์พารัลแลกซ์ สิ่งสำคัญคือต้องคำนึงถึงลำดับชั้นของภาพและเอฟเฟกต์ความลึกที่ต้องการซึ่งสร้างขึ้น การให้เลเยอร์ที่อยู่ใกล้กับกล้องมากที่สุดสามารถเคลื่อนที่ได้เร็วกว่าเลเยอร์ที่อยู่ห่างออกไปเพื่อสร้างความลึกและการเคลื่อนไหวภายในการออกแบบได้ผลดี

ขอบเขตของกล้อง

เพื่อรับประกันประสบการณ์การเล่นเกมที่ราบรื่นและไม่ขาดตอน สิ่งสำคัญคือต้องกำหนดขีดจำกัดการเคลื่อนไหวของกล้องภายในสภาพแวดล้อมเสมือนจริง ด้วยการทำเช่นนี้ เราสามารถหลีกเลี่ยงช่องว่างที่ไม่จำเป็นหรือปัญหาทางเทคนิคที่อาจเกิดขึ้นเมื่อผู้เล่นเข้าใกล้ขอบเขตของโลกของเกม

การทดสอบและการปรับแต่ง

เพื่อรับประกันประสิทธิภาพและรูปลักษณ์ที่เหมาะสมที่สุดของการเลื่อนพารัลแลกซ์บนอุปกรณ์และความละเอียดหน้าจอที่หลากหลาย จำเป็นต้องทดสอบการออกแบบบนหลายแพลตฟอร์ม โดยการปรับขนาดการเคลื่อนไหว ตำแหน่งของเลเยอร์ และตัวแปรที่เกี่ยวข้องอื่นๆ เราอาจปรับแต่งเอฟเฟกต์พารัลแลกซ์เพื่อให้ได้ผลลัพธ์ที่ต้องการมากที่สุด

ทำให้เกม Godot มีส่วนร่วมมากขึ้นด้วยการเลื่อนพารัลแลกซ์

การรวมเอฟเฟกต์การเลื่อนพารัลแลกซ์ที่คาดเดาไม่ได้สามารถเพิ่มการมีส่วนร่วมของผู้ใช้ในเกม Godot ได้อย่างมาก เทคนิคนี้เรียกว่าการเลื่อนพารัลแลกซ์แบบสุ่ม สร้างและวางตำแหน่งหลายเลเยอร์ได้ทันทีเพื่อสร้างประสบการณ์การเล่นเกมที่ดื่มด่ำ

การผสมผสานสภาพแวดล้อมแบบไดนามิกผ่านเทคนิคการสร้างขั้นตอนสามารถทำให้เกิดความรู้สึกเคลื่อนไหวและความมีชีวิตชีวาภายในฉากของเกม ดังนั้นจึงผสมผสานเข้ากับบรรยากาศที่เป็นธรรมชาติและคาดเดาไม่ได้ ฉากหลังภาพที่เปลี่ยนแปลงตลอดเวลานี้ช่วยเพิ่มความดื่มด่ำของผู้เล่นด้วยการมอบมิติที่น่าตื่นเต้นเพิ่มเติมให้กับเส้นทางการเล่นเกมของพวกเขา