irpg Community

Full Version: Ren'Py พื้นฐาน | บทที่ 5 ตัวเลือกและทิศทางของเกม
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
ติดตามเราได้ที่ Facebook ชื่อเพจ Planila Game Developer


อะไรนะ! มีเกมแนว Visual Novel ที่ไหนไม่มีตัวเลือกให้ผู้เล่นบ้าง? ก็เกมแนว Visual Novel ที่สร้างกันในบทที่แล้วน่ะสิ สำหรับผู้อ่านที่ยังไม่ได้อ่านบทความชุด "Ren'Py พื้นฐาน" ตั้งแต่บทที่ 1 ถึงบทที่ 4 ผู้เขียนแนะนำให้ท่านย้อนกลับไปก่อนอ่านบทนี้ ในบทนี้ท่านจะได้เรียนเรื่องทิศทางการทำงานของเกมด้วยวิธีต่าง ๆ ได้แก่ การข้ามการทำงาน, การตรวจเงื่อนไข, การทำงานซ้ำ, และปิดท้ายบทนี้ด้วยการสร้างตัวเลือกให้เกมแนว Visual Novel ที่ผู้เล่นคุ้นเคยกัน

[Image: 05.png]



Block: เว้นวรรคหน้าคำสั่ง

ก่อนเรียนเรื่องใหม่ผู้เขียนต้องอธิบายเรื่องบล็อก (Block) ให้ท่านเข้าใจก่อน จะได้ไม่ต้องมาอธิบายเรื่องนี้ซ้ำบ่อย ๆ บล็อกคือกลุ่มของคำสั่งที่อยู่ในระดับเดียวกัน ผู้อ่านที่เคยเขียนโปรแกรมด้วยภาษา C หรือ Java คงจะคุ้นเคยกับเครื่องหมาย { } ที่ครอบคำสั่งหลายตัว นั่นคือการบอกว่าคำสั่งเหล่านี้อยู่ในบล็อกเดียวกันหรือระดับเดียวกัน (เช่น กลุ่มคำสั่งที่ต่อจาก if-else, while, function)

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

ในภาษา Ren'Py ไม่ได้ใช้เครื่องหมาย { } ในการแบ่งบล็อก แต่จะใช้การเว้นวรรคหน้าคำสั่งเพื่อแบ่งบล็อก (ห้ามใช้ Tab แทนการเว้นวรรค อ่านรายละเอียดใน "ข้อระวังท้ายบท" ใน Ren'Py พื้นฐาน | บทที่ 3 กล่องข้อความ) คำสั่งที่อยู่ในบล็อกเดียวกันต้องเว้นวรรคหน้าคำสั่งเท่ากัน การเว้นวรรคหน้าคำสั่งจะเว้นวรรคกี่ครั้งก็ได้ สำหรับบล็อกย่อยที่อยู่ภายในบล็อกใหญ่แล้ว บล็อกย่อยนั้นต้องมีจำนวนเว้นวรรคมากกว่าบล็อกใหญ่ ตัวอย่างเช่น


Code:
# บล็อกที่ 1 (คำสั่งที่ 1-1)
# บล็อกที่ 1 (คำสั่งที่ 1-2)

     # บล็อกที่ 2 (คำสั่งที่ 2-1)
     # บล็อกที่ 2 (คำสั่งที่ 2-2)

          # บล็อกที่ 3 (คำสั่งที่ 3-1)
          # บล็อกที่ 3 (คำสั่งที่ 3-2)

     # บล็อกที่ 2 (คำสั่งที่ 2-3)
     # บล็อกที่ 2 (คำสั่งที่ 2-4)

# บล็อกที่ 1 (คำสั่งที่ 1-3)

จากตัวอย่างข้างบนสังเกตว่าคำสั่งในบล็อกที่ 1 ไม่ได้เว้นวรรคหน้าคำสั่ง (หน้าบรรทัด) ถือว่าเป็นบล็อกที่ใหญ่ที่สุด บล็อกที่ 2 เป็นบล็อกย่อยที่อยู่ในบล็อกที่ 1 มีการเว้นวรรคหน้าบล็อกที่ 2 พอควร ต่อมาคือบล็อกที่ 3 เป็นบล็อกย่อยที่อยู่ในบล็อกที่ 2 อีกที สังเกตจากคำสั่งของบล็อกที่ 3 อยู่ต่อจากบล็อกที่ 2 และมีการเว้นวรรคมากกว่าบล็อกที่ 2

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

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


Pass

ในกรณีที่ภาษา Ren'Py บังคับให้ใส่บล็อกย่อย แต่เราไม่มีคำสั่งที่ต้องการใส่ในบล็อกย่อยนั้น ภาษา Ren'Py ไม่อนุญาตให้ปล่อยเป็นบล็อกเปล่าได้ วิธีแก้คือใส่คำสั่ง pass ในบล็อกย่อยนั้น คำสั่ง pass เป็นคำสั่งที่ไม่ทำอะไรเลย ทำหน้าที่เป็น Pseudo Statement หลอกว่าในบล็อกย่อยมีคำสั่งแล้วทั้งที่จริงไม่มีคำสั่ง ตัวอย่างการใช้คำสั่ง pass คู่กับคำสั่ง if-else เช่น

Code:
if i > 10:
     pass   #เราไม่ต้องการใส่คำสั่งในบล็อกนี้
else:
     "i มีค่าไม่เกิน 10 สินะ"   #บล็อกนี้คือบล็อกที่เราต้องการใส่คำสั่งจริง



Label & Jump: กำหนดเพื่อข้าม

Label

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


Code:
label ชื่อเฉพาะ:

เช่น label check: หมายถึงตั้งชื่อ check ให้แก่บรรทัดนั้น (บรรทัด label check) คำสั่ง label ไม่มีประโยชน์เมื่อใช้งานเดี่ยว ๆ เพราะไม่มีความจำเป็นที่ต้องตั้งชื่อให้แก่คำสั่งที่ตั้งชื่อให้ตัวเอง เปลืองบรรทัดเปล่า ๆ คำสั่ง label จะใช้คู่กับคำสั่ง jump

start คือชื่อเฉพาะที่โปรแกรม Ren'Py สงวนไว้ เกมจะเริ่มต้นทำงานที่ label start: เป็นลำดับแรกเสมอ (เปรียบเหมือนฟังก์ชัน main ในภาษา C) ดังนั้นคำสั่งทุกอย่างในเกมต้องอยู่ต่อจากบรรทัด label start: เสมอ เพื่อให้คำสั่งเหล่านั้นสามารถทำงานในเกมได้


[Image: 01.png]
รูปที่ 5.1 การทำงานของคำสั่ง label และ jump


Jump

jump คือคำสั่งที่ข้ามไปทำงานบรรทัดที่มีชื่อเฉพาะ หมายความว่าเราต้องตั้งชื่อเฉพาะให้แก่บรรทัดเป้าหมายด้วยคำสั่ง label ก่อน แล้วเราจึงสามารถข้ามไปยังบรรทัดเป้าหมายด้วยคำสั่ง jump ได้ เมื่อข้ามไปยังบรรทัดเป้าหมายแล้ว เกมจะทำงานต่อจากบรรทัดเป้าหมายไปเรื่อย ๆ ไม่กลับมาบรรทัดที่ต่อจากคำสั่ง jump อีก (เป็นการข้ามแบบถาวร) รูปแบบของคำสั่ง jump คือ


Code:
jump ชื่อเฉพาะ

ตัวอย่างการข้ามด้วยคำสั่ง jump เช่น


Code:
# บรรทัดนี้ทำงานเสมอ

jump check
# บรรทัดนี้จะไม่ทำงาน เพราะถูกข้ามไปยังบรรทัด label check:

label check:
     # บรรทัดนี้จะทำงาน

label always:
     # บรรทัดนี้ทำงานเสมอ แม้ว่าจะไม่ได้ข้ามมาบรรทัด label always: ก็ตาม

# บรรทัดนี้ทำงานเสมอ

สิ่งที่ต้องระวังคือคำสั่ง label ต้องตามท้ายด้วยเครื่องหมาย : แต่คำสั่ง jump ไม่มีเครื่องหมาย : ต่อท้าย อีกเรื่องที่ควรจำคือถ้าคำสั่งไม่ถูกข้าม เกมจะทำงานจากบรรทัดบนไปยังบรรทัดล่าง คำสั่งที่ต่อจากบรรทัด label สามารถทำงานได้โดยไม่ต้องเรียกใช้ด้วยคำสั่ง jump (เช่น คำสั่งที่ต่อจากบรรทัด label always: ในตัวอย่างข้างบน) นอกจากนี้ยังสามารถใช้คำสั่ง jump เพื่อข้ามไปยังบรรทัดที่อยู่ในไฟล์สคริปต์อื่นได้อีกด้วย เนื่องจากโปรแกรม Ren'Py มองไฟล์สคริปต์ทุกไฟล์รวมเข้าด้วยกัน



If-Else: ตรวจเงื่อนไข


......

นี่เพิ่งแค่ 39% ของบทความนี้เท่านั้น บทความฉบับเต็มมีเยอะกว่านี้อีก!


เนื่องจากติดปัญหาเรื่องนโยบายการเผยแพร่บทความ ทำให้เราไม่สามารถเผยแพร่บทความฉบับเต็มลงในเว็บนี้ได้ อ่านฉบับเต็มได้ที่บทความต้นฉบับ (ไม่มีค่าใช้จ่าย)

บทความต้นฉบับ https://planila.blogspot.com/2019/08/ren...ter05.html

[Image: %25E0%25B8%259A%25E0%25B8%2597%25E0%25B8...9%2588.png]