พื้นฐานการโม Script เบื้องต้น - Printable Version +- irpg Community (https://irpg.in.th) +-- Forum: irpg Fabella RPG Maker Academia (https://irpg.in.th/forum-4.html) +--- Forum: RPG Maker Engine School (https://irpg.in.th/forum-7.html) +---- Forum: Scripting Academy (https://irpg.in.th/forum-12.html) +---- Thread: พื้นฐานการโม Script เบื้องต้น (/thread-2441.html) |
พื้นฐานการโม Script เบื้องต้น - splendith - 06-12-2015 พื้นฐานการโม Script เบื้องต้น บทความนี้เป็นบทความเบื้องต้น อย่างไรก็ตาม เนื้อหามีความยาวถึงยาวที่สุด เหมาะสำหรับผู้ที่ต้องการเขียน script อย่างจริงจังในอนาคต บทความนี้ตั้งใจเขียนมาก พยายามอธิบายให้ง่ายที่สุด อย่างไรก็ตาม หากไม่เข้าใจ มีข้อสงสัยหรือข้อเสนอแนะ โปรดคอมเมนต์ด้วยนะครับ หรือถ้าไม่รู้เรื่องตรงไหนบอกได้เลยครับ หรือหากมีข้อผิดพลาด แจ้งได้เลยนะครับ แม้ในบทความนี้จะใช้ RGSS3 เป็นหลัก แต่หลักการสอนในบทความนี้สามารถนำไปประยุกต์ใช้ได้ทุกเวอร์ชันครับ หรือแม้แต่นำหลักการไปใช้ทำอย่างอื่นนอกจากใช้ใน RPG Maker ก็ได้ครับ เคยไหม บางทีอยากได้ระบบตามที่ต้องการ ในบางกรณีการแก้ด้วย event หรือ database นั้นยังมีขีดจำกัดอยู่ จึงไม่สามารถเปลี่ยนแปลงได้ดั่งใจ ทำให้ต้องหวังพึ่งการใช้ script ในการทำระบบที่ต้องการ ซึ่งหลายๆ คนเมื่อเปิดหน้าจอ script editor ดูก็รู้สึกเอียน มึนหัว ตาลาย ไม่อยากไปแตะต้องเลย... ถ้าโชคดี เจอ script ที่มีคนเขียนมาก่อน ก็โหลดมาลงแล้วใช้งานได้เลย แต่ถ้าเราต้องการ script ที่มันเฉพาะเจาะจงจริงๆ ทักษะการโม script ก็ทำให้เราได้เปรียบไม่ใช่น้อย จริงๆ แล้วก่อนที่จะทำการโม script นั้น แนะนำให้ศึกษาพื้นฐานการเขียน Ruby script ก่อน เพราะจะทำให้เราเข้าใจ script ได้อย่างรวดเร็วมากขึ้น แต่อย่างไรก็ตาม ในบทความนี้จะพยายามยกตัวอย่างที่ทุกท่านเข้าใจได้ไม่ยาก ซึ่งบทเรียนจะมีดังนี้ครับ จะมาราธอนสอนตั้งแต่ต้นจนจบในกระทู้นี้เลยครับ
เข้าใจส่วนต่างๆ ในหน้าจอ script ของ RGSS3 สิ่งสำคัญที่ต้องรู้เป็นอันดับแรกเลยนั่นคือ ต้องรู้ว่าส่วนต่างๆ ของ script ในหน้า script editor นั้นมีหน้าที่อะไรบ้าง เพื่อจะนำไปสู่การคาดเดาเพื่อโม script ในอนาคต ใน RGSS3 นั้น ทีมพัฒนาได้เขียนโค้ดอ่านเข้าใจง่าย และเป็นระเบียบมากๆ มีการพัฒนาจากรุ่นก่อนๆ อย่างเห็นได้ชัด ให้ท่านลองปุ่ม F11 ดู จะมีหน้าจอ script editor ปรากฎขึ้นมา มองไปทางซ้าย สังเกตว่ามันจะแบ่งเป็นส่วนๆ ชัดเจน ให้ลองดูตามไปเลยนะครับ 1. ส่วนของ Modules ส่วนนี้จะอยู่ด้านบนซ้ายสุดของหน้าจอ แบ่งเป็นสองส่วนย่อย 1.1 ส่วนของการจัดการข้อมูลที่ใช้ในเกม
ส่วนนี้จะส่วนที่คอยควบคุมข้อมูลต่างๆ ในเกมครับ เทียบได้กับ "ผู้จัดการ" ที่สั่งพนักงานทำงานต่างๆ นั่นเอง
2. ส่วนของ Game Objects ในส่วนนี้จะเป็นส่วนของการเก็บข้อมูลต่างๆ ในเกมในขณะที่เล่นอยู่ เช่น ข้อมูลปาร์ตี้ ข้อมูลศัตรู หรืออื่นๆ โดยข้อมูลจะเป็นข้อมูลที่ถูกสร้างระหว่างที่อยู่ในเกม ไม่เกี่ยวข้องกับข้อมูลในฐานข้อมูลแต่อย่างใด เช่น เมื่อเดินเจอศัตรูปุ๊บ ข้อมูลศัตรูที่เจอก็จะถูกสร้าง แล้วก็มีข้อมูล hp, mp, atk, เป็นต้น ซึ่งสังเกตว่าข้อมูลบางอย่างจะมีการเปลี่ยนแปลงได้ตลอดเวลา เช่น เราโจมตี มอนสเตอร์ hp ลด เป็นต้น ในส่วนนี้แบ่งออกเป็นไฟล์ต่างๆ มากมาย และจะขึ้นต้นด้วย Game_ เพื่อแบ่งแยกประเภทชัดเจน 3. ส่วนของ Sprites ในส่วนนี้จะเป็นส่วนของการจัดการสิ่งของในเกมที่เกี่ยวกับภาพทั้งหมด ไม่ว่าจะเป็นท่าเดินของตัวละคร ภาพตัวละคร ภาพศัตรู รูปภาพ ฉากต่างๆ หรือเอฟเฟกต์ต่อสู้ เป็นต้น 4. ส่วนของ Windows ในส่วนนี้จะเป็นส่วนของหน้าต่างที่ใช้สื่อสารกับผูเล่นทั้งหมดในเกม ไม่ว่าจะเป็น กล่องข้อความ หน้าต่างตัวเลือก หรือหน้าต่างแสดงรายการเมนู หน้าหน้าต่างแสดงรายละเอียดผู้เล่น หน้าต่างแสดงข้อมูลเครื่องสวมใส่ เป็นต้น พูดง่ายๆ อะไรที่เป็นกล่องๆ มีเส้นขอบขาวๆ พื้นหลังสีน้ำเงิน (ในกรณีที่ไม่ได้ปรับแต่งอะไรเพิ่มเติม) มีข้อความข้างใน จะอยู่ในส่วนของ Windows หมด 5. ส่วนของ Scenes ในส่วนนี้จะเป็นส่วนของการเก็บฉากต่างๆ ในเกม ไม่ว่าจะเป็นฉาก Title, ฉาก Map (ฉากขณะเล่นเกม), ฉากเมนู, ฉากต่อสู้, ฉาก Game Over เป็นต้น อย่าสับสนกับส่วนของ Windows นะ หลายคนงงว่าทำไมส่วนของ Windows ก็มี Menu ส่วนของ Scene ก็มี Menu ในที่นี้ส่วนของ Scene จะหมายถึงการเข้าฉากที่เป็นเมนูเกม ซึ่งในเมนูเกมนั้นจะประกอบไปด้วย หน้าต่างเลือกเมนู หน้าต่างแสดงข้อมูลปาร์ตี้ หน้าต่าง หน้าต่างแสดงจำนวนเงิน ซึ่งหน้าต่างทั้งหลายเหล่านี้จะอยู่ใน ฉากของ Menu อีกทีนั่นเอง RPG Maker VX Ace Database Module นอกจากส่วนที่อยู่ในหน้าจอ script editor แล้ว ยังมีข้อมูลอีกส่วนหนึ่งที่สามารถเรียกใช้ได้เช่นกัน แต่ไม่มีบอกในหน้าจอดังกล่าว นั่นคือ RPG Module ซึ่งเป็นโมดูลที่เก็บข้อมูล Database เกมทั้งหมด และส่วนใหญ่จะดึงข้อมูลจาก database editor (F9) เมื่อนำไปใช้ในเกม ในส่วนนี้จะเป็นค่าที่เรียกใช้ข้อมูลอย่างเดียว ไม่สามารถเปลี่ยนแปลงแก้ไขขณะอยู่ในเกมได้เลย แนวคิดในการโม script เอาล่ะ เมื่อรู้ข้อมูลเบื้องต้นแล้ว ในตอนนี้เราจะสามารถคาดเดาได้บ้างแล้ว ว่าอยากแก้แบบนี้ ควรจะไปแก้ที่ไหน ทุกส่วนที่กล่าวมาล้วนมีความจำเป็นในการโม script ทั้งสิ้น แนวคิดหลักๆ เลยคือ
คำถาม อยากแก้ข้อความ Buy, Sell, Cancel ใน shop ทำอย่างไร วิธีการคาดเดา เรารู้ว่าใน Module Vocab นั้นใช้เก็บข้อความในเกมแทบทั้งหมด ฉะนั้นรออยู่ไย ลองเข้าไปหากันเลย แล้วลองสำรวจว่าบรรทัดไหนที่มีข้อความทำนองนั้น ให้แก้โดยพลัน ~ คำถาม อยากลบเมนูเซฟเกมในหน้าจอเมนูออกไปเลย ให้ไม่แสดงในหน้าจอเมนู วิธีการคาดเดา ก็ต้องดูก่อนว่าคำสั่งเซฟเกมควรจะอยู่ในส่วนไหนของ script ซึ่งแน่นอนว่ามันอยู่ใน window object อะไรสักอย่างแน่ๆ (เพราะมีลักษณะเป็นกล่องๆ) เมื่อไล่ดูแล้วก็จะพอเดาได้ว่าอยู่ใน Window_MenuCommand ต่อมาลองพิจารณาประมาณบรรทัดที่ 40 ซึ่งเขียนว่า add_save_command โอ้โห! โป๊ะเชะ น่าจะอันนี้แหละ แต่จะลบทิ้งก็ยังไงอยู่ แนะนำให้ลองใส่ # ด้านหน้าบรรทัดดังกล่าวเพื่อ comment แทนการลบ จากนั้นลองรันเกมแล้วเปิดเมนูดู ถ้าเมนูเซฟหายไป แปลว่า ท่านเดาถูกแล้วล่ะ คำถาม เรือ (boat) ในเกมวิ่งช้าจุงเบย อยากให้มันเร็วกว่านี้ วิธีการคาดเดา ในข้อนี้เป็นการแก้ข้อมูลของตัวเกม ดังนั้นมีความเป็นไปได้สูงสุดที่จะอยู่ในส่วนของ Game Objects เราก็ลองไล่ๆ ดู อ๊ะ อันนี้น่าจะเข้าเค้าสุดละ Game_Vehicles นั่นเอง เข้าไปแล้วลองไล่ๆโค้ดดูอย่างใจเย็นๆ บรรทัดประมาณ 34 จะเห็นโค้ด @move_speed = 4 if @type == :boat อ่านแล้วค่อนข้างเข้าใจง่ายมากๆ ว่าแล้วก็ลองแก้จาก 4 เป็น 10 แล้วลองวางเรือ เข้าเกมไปลองขึ้นเรือดู ว้าว เห็นผล วิ่งเร็วยังกับจรวด!!! ในช่วงแรกๆ อาจจะยังเดาได้ไม่คล่อง หรือรู้สึกยาก อย่าท้อครับ ให้พยายามไปเรื่อยๆ เราจะเริ่มจับทางได้เอง ยิ่งใครเคยเขียนโปรแกรมมาก่อน ยิ่งได้เปรียบเลยครับ จากโจทย์ด้านบน สังเกตว่าเราแก้ปัญหาโดยไปเปลี่ยนโค้ดในส่วนต่างๆ ที่ต้องการ ซึ่งในการใช้จริงในอนาคต การแก้แบบด้านบนเป็นตัวอย่างที่ไม่ดี และไม่แนะนำเป็นอย่างยิ่ง เหตุผลและวิธีการแก้ปัญหาอยู่ในหัวข้อถัดไปเลยจ้า เข้าใจการ alias method และ overwrite method สิ่งสำคัญที่หลายคนมองข้าม! ขอบอกล่วงหน้าว่าหัวข้อนี้ค่อนข้างยาวและซับซ้อน ค่อยๆ อ่านใจเย็นๆ นะครับ มันสำคัญมากๆๆๆ สำหรับผู้ที่ต้องการเขียน script อย่างจริงจังในอนาคต หากเข้าใจทั้งหมด มันคือกำไรชีวิตแน่นอนครับผมการันตี ในหัวข้อก่อนหน้าเรามีคำแนะนำทิ้งท้ายว่าวิธีการแก้โค้ดในส่วนต่างๆ นั้น ไม่แนะนำอย่างยิ่ง สิ่งที่ผมต้องการจะสื่อจริงๆ นั่นคือ ไม่ควรเพิ่ม / ลบ / แก้ไข โค้ดต้นฉบับที่มีอยู่แล้วนั่นเอง (ยกเว้น module Vocab ที่พออนุโลมได้) เพราะมันมีผลกระทบดังนี้
ซึ่งคำตอบมีอยู่สองหนทางก็คือ
ให้พิจารณาโค้ดด้านล่างนี้ โค้ดใน RGSS มักจะอยู่ในรูปแบบนี้เสมอ (ยกเว้นในส่วนของ Module จะเปลี่ยนจากคำว่า class เป็น module แทน) ซึ่งชั้นนอกจะเรียกว่า class และในคลาสจะประกอบไปด้วยสิ่งที่เรียกว่า method ตัวอย่างเช่น โค้ดบรรทัดที่ 9 โค้ด @energy = -20 นั้นอยู่ใน method ชื่อ run และอยู่ใน class ชื่อ Person หรือโค้ดบรรทัดที่ 21 นั้นอยู่ใน method ชื่อ go_forward และอยู่ใน class ชื่อ Car เป็นต้น พอจะดูออกแล้วใช่ไหมครับ ทีนี้อยากให้ท่านลองดู script ต่างๆ ที่มีใน script editor สังเกตว่าแทบทุกไฟล์จะมีรูปแบบเหมือนกับภาพตัวอย่างเลยใช่ไหมครับ นั่นคือมี class มี method ต่อมาอยากให้ท่านกด F11 แล้วในฝั่งซ้าย เลื่อนลงมาล่างๆ จะเจอกับส่วนที่เรียกว่า Materials ลองคลิกขวา ตรงคำว่า ( Insert here ) แล้วเลือก Insert จะได้ช่องเปล่าเพิ่มขึ้นมา 1 ช่อง ในส่วนของ Name ให้ตั้งชื่ออะไรก็ได้ จากตัวอย่างนี้ ให้ตั้งเป็น My Script ละกันครับ สิ่งที่ท่านได้ทำไปคือการสร้างไฟล์ใหม่ขึ้นมานั่นเอง ซึ่งเป็นไฟล์เปล่าๆ ที่จะใช้เขียน script อะไรก็ได้ลงไป เราจะใช้ที่ว่างใหม่นี้ในการเขียนโค้ดเพิ่มเติมโดยไม่ไปยุ่งกับโค้ดส่วนเก่าอีกเลย เมื่อเข้าใจกระจ่างแล้ว ย้อนกลับไปที่การ overwrite script และการ alias method ดีกว่า การ Overwrite Script วิธีการนี้จะเป็นการเขียนโค้ดทับโค้ดเก่าแบบดื้อๆ เพื่อให้ตัวเกมอ่านโค้ดใหม่ของเราเป็นหลักแทนที่จะอ่านโค้ดเดิมที่มีอยู่ ซึ่งการที่จะ overwrite script ได้นั้นจำเป็นต้องรู้ว่าอยู่ใน method ไหนและอยู่ใน class อะไรเสมอ ตัวอย่างจากคำถามข้อ 2 ในหัวข้อที่ผ่านมา คำถาม อยากลบเมนูเซฟเกมในหน้าจอเมนูออกไปเลย ให้ไม่แสดงในหน้าจอเมนู เราจะไม่ลบ add_save_command เหมือนที่ผ่านมาแล้ว แต่ให้ท่านสังเกตว่า add_save_command นั้นอยู่ใน method อะไร และใน class อะไร (อย่าเพิ่งอ่านต่อนะ ลองคิดเองก่อน หุหุ) ซึ่งจะพบว่าอยู่ใน method make_command_list และ class Window_MenuCommand < Window_Command ใช่ไหมครับ (เครื่องหมาย < คืออะไรไม่ต้องสนใจในจุดนี้ เอามันมาทั้งบรรทัด เหมือนเดิม อธิบายที่นี่ยาวแน่นอน *0*) ให้เราไปที่ script ที่เพิ่งสร้างขึ้นใน Materials เมื่อตะกี๊ แล้วเขียนโค้ดดังนี้ [shcode=rails] class Window_MenuCommand < Window_Command def make_command_list add_main_commands add_formation_command add_original_commands add_game_end_command end end [/shcode] สังเกตว่าเราดึง class และ method มาเขียนลงไฟล์ใหม่นั่นเอง และใน method ที่เขียนใหม่ของเรานั้นมีโค้ดเหมือนอันเก่าทุกประการ แต่ได้เอา add_save_command ออกไป (ต้องมีโค้ดใน method ส่วนเดิมให้ครบนำ สำคัญมาก เพราะเกมจะไม่อ่านโค้ดเดิมอีกแล้ว) เมื่อเรารันเกม เกมก็จะมาอ่าน method make_command_list ใน class Window_MenuCommand < Window_Command ที่เราเขียนใหม่ แทนที่จะไปอ่านของเดิม ผลลัพธ์การรันเกมจะเหมือนตัวอย่างที่ทำอันที่แล้วทุกประการ นี่แหละที่เรียกว่า การ overwrite script ซึ่งการเขียน overwrite ใหม่นั้น ไม่จำเป็นว่าในคลาสต้องมีเพียง method เดียว อาจจะ overwrite โดยเขียนหลายๆ method ไว้ใน class เดียวเลยก็ได้ (หากแก้หลายที่) และที่สำคัญ อาจสถาปนา method ขึ้นใหม่ด้วยชื่อใหม่เองก็ได้ (แต่การเขียน method ขึ้นใหม่เองอาจยังไม่เหมาะกับมือใหม่ จะไม่กล่าวในบทความนี้) แล้วโค้ดเดิมไปไหน ทำไมจึงเป็นเช่นนั้น? หลักการของภาษา Ruby นั่นคือ หากเจอ class ซ้ำกัน หรือ method ซ้ำกันที่อยู่ใน class เดียวกัน มันจะใช้งานโค้ดที่อยู่ด้านล่างเป็นหลัก ซึ่งหากเราพิจารณาแล้ว script ส่วนของ Materials ที่เราเขียนเพิ่ม มันแทบจะอยู่ล่างสุดเลยใช่ไหมครับ มันจึงเป็นเหตุผลว่าทำไมโปรแกรมถึงจัดวางที่เขียนโค้ดให้เราด้านล่างนั่นเอง ^^ นอกจากนี้ยังสามารถ overwrite โค้ดใน class นอก method ได้อีกด้วย แต่ช่างมันเต๊อะ ไว้จะเขียนให้ในบทความที่ advance กว่านี้นะคับ แหะๆ การ Alias Method หลังจากที่รู้จักการ overwrite script ไปแล้ว ยังมีอีกสิ่งหนึ่งเรียกว่า การ alias method ซึ่งขอเกริ่นนำด้วยตัวอย่างโจทย์เลยละกันครับ คำถาม: อยากให้เลเวลอัพแล้วฟื้นฟูเลือดจนเต็ม ลองหาวิธีก่อนนะครับ อาจจะยังทำไม่ได้ไม่เป็นไร ลองมาดูเฉลยครับ ขอทำด้วยวิธีการ overwrite เหมือนอันที่แล้วเพื่อให้เห็นภาพก่อนครับ ข้อนี้มี keyword ตรง level up ลองนึกดูว่าอะไรที่สามารถ level up ได้ นั่นก็คือตัวละครนั่นเอง ซึ่งตัวละครใน RPG Maker จะใช้คำว่า Actor ซึ่งมี script ที่เข้าเค้าคือ Game_Actor (ไม่ใช่ Game_Actors นะ ดูดีๆ) เข้าไปแล้วหากโค้ดมีหลายบรรทัดลองกด Ctrl+F เพื่อหาเอาเลยครับ ลอง search ว่า level แล้วไล่ดูเรื่อยๆ จะพบ method ที่น่าสนใจคือ method level_up ประมาณบรรทัดที่ 426 งวดนี้จะไม่ได้แก้ข้อมูลด้านใน แต่ละเพิ่มคำสั่งเข้าไปใน method แทน ให้ทำการหา class ของ method นี้ด้วย เพื่อจะทำการเขียนโค้ด overwrite ใหม่ ไปที่ โค้ดที่สร้างขึ้นใน Materials เหมือนเดิม ไฟล์เดิมก็ได้ครับ จากนั้นก็อปโค้ดส่วน method level_up ที่เราหามาได้ แล้วอย่าลืมใส่ class ที่หามาครอบด้วยนะ เขียนต่อโค้ดเก่าที่มีได้เลย (ไฟล์นึงจะมีกี่ overwrite ก็ได้ แต่หากเขียนโค้ดเยอะขึ้น แยกให้เป็นหมวดหมู่ก็ดีครับ) ทำแล้วได้เหมือนผมไหมครับ [shcode=rails] class Game_Actor < Game_Battler def level_up # โค้ดเดิมก็อปมาใส่ใหม่ @level += 1 self.class.learnings.each do |learning| learn_skill(learning.skill_id) if learning.level == @level end # โค้ดใหม่ @hp = mhp #ตั้ง hp ของเรา ให้มีค่าเท่ากับ max hp @mp = mmp #ตั้ง mp ของเรา ให้มีค่าเท่ากับ max mp end end [/shcode] @hp กับ @mp เป็นตัวแปรที่ใช้แทน hp, mp ปัจจุบันของตัวละครดังกล่าว ส่วน mhp, mmp เป็นตัวแปรอ้างถึง max hp, max mp ครับ (ส่วนรู้ได้ยังไงว่าหาจากไหน อาศัยประสบการณ์การแกะโค้ดและการหาข้อมูลจาก google เอาครับ หาเรื่อยๆ อ่านเรื่อยๆ เดี๋ยวก็เข้าสมองเองครับ หุหุ) สังเกตว่าการ overwrite นั้นจำเป็นต้องใส่โค้ดเก่าด้วยเสมอ (เพราะอย่าลืม มันไม่อ่านโค้ดเดิมอีกแล้ว) แล้วในข้อนี้เราแค่เติมโค้ดเพิ่มเข้าไปสองบรรทัด ซึ่งในการทำ overwrite นั้น มีข้อเสียอยู่เช่นกัน (แต่ยังไงก็ดีกว่าแก้โค้ดเดิมแน่นอนครับ) ข้อเสียของการเขียน overwrite
[shcode=rails] class Game_Actor < Game_Battler def level_up @level += 1 self.class.learnings.each do |learning| learn_skill(learning.skill_id) if learning.level == @level end $game_party.gain_gold(5000) # คนอื่นใส่โค้ดนี้เพิ่มมา end end [/shcode] ลองทายดูสิครับว่า หากมีทั้งโค้ดของเรา และโค้ดของคนอื่นดังกล่าว ผลจะเป็นอย่างไรครับ... แน่นอนว่า จากกฎการ overwrite มันจะทำงานเฉพาะอันที่อยู่ล่างสุดใช่ไหมครับ ^^ ดังนั้น หากโค้ดของเราอยู่ด้านล่าง เมื่อเลเวลอัพตัวละครก็จะเลือดเต็มเท่านั้น และหากโค้ดของคนอื่นอยู่ด้านล่าง เมื่อเลเวลอัพก็จะได้เงินเพิ่ม 5000G เท่านั้น... วิธีการ alias method จะมาแก้ปัญหาข้างบนนี้ การประกาศ alias method หมายถึงการสร้าง method ใหม่ขึ้นมาให้มีโค้ดเหมือน method เดิม และสามารถตั้งชื่อ method ใหม่ที่ก็อปมาได้ โดยมีรูปแบบการเขียนดังนี้ alias_method :copied_method_name, :current_method_name เช่น [shcode=rails] def run p "Go go!" p "Wow, very quickly." p "Run Run Run!" end [/shcode] จากนั้นบรรทัดถัดมาผมเพิ่ม [shcode=rails] alias_method :run_copied, :run [/shcode] จากโค้ดด้านบน เป็นการ copy method run_copied เพิ่มมาอีกอัน และมีคำสั่งด้านในเหมือน method run ในปัจจุบัน ดังนั้น มันจะแอบไปเพิ่มโค้ดด้านล่างนี้ขึ้นมาเอง (เราไม่ต้องเขียนนะ) [shcode=rails] def run_copied p "Go go!" p "Wow, very quickly." p "Run Run Run!" end [/shcode] แล้วมีประโยชน์อย่างไร สมมุติผมมีโค้ดด้านบนแล้ว ผมต้องการ overwrite method run ด้านบน ปรกติผมเขียนแบบนี้ใช่ไหม [shcode=rails] def run p "Go go!" p "Wow, very quickly." p "Run Run Run!" p "YEAHHHHHHHHHH!!!" # เพิ่มเข้ามา end [/shcode] เนื่องจากมีการ copy method ไปใส่ใน run_copied แล้ว ผมสามารถเขียนใหม่เป็นแบบนี้ได้ [shcode=rails] def run run_copied # เรียก method ชื่อ run_copied p "YEAHHHHHHHHHH!!!" # เพิ่มเข้ามา end [/shcode] ซึ่งหลักการทำงานจะเป็นดังนี้ ในครั้งนี้ เราได้ทำการ override method run โดยใช้การเรียก method run_copied ด้านใน แล้วต่อด้วยคำสั่งที่ต้องการเพิ่ม ทำให้การ overwrite เราไม่จำเป็นต้องพิมพ์คำสั่งทั้งหมดที่อยู่ใน method run เดิมอีกต่อไป ซึ่งทำให้ลดความซ้ำซ้อนลงได้เป็นอย่างมาก ทีนี้มันแก้ปัญหาโค้ดตีกันกับชาวบ้านได้อย่างไร มาดูกันครับ กลับมาที่โค้ดเลเวลอัพเหมือนเดิม ผมแก้โค้ดของผมจากโค้ดเดิมเป็นอันนี้ [shcode=rails] class Game_Actor < Game_Battler alias_method :level_up_copied, :level_up def level_up level_up_copied # โค้ดใหม่ @hp = mhp #ตั้ง hp ของเรา ให้มีค่าเท่ากับ max hp @mp = mmp #ตั้ง mp ของเรา ให้มีค่าเท่ากับ max mp end end [/shcode] แล้วผมเอาไปไว้ใต้โค้ดของคนอื่น (ที่เลเวลอัพแล้วเพิ่ม 5000G) ย้ำว่าเอาไว้ข้างใต้นะครับ! ลองรันเกมดู จะพบว่าเมื่อเลเวลอัพ เราจะได้ทั้งเงิน 5000G และเลือดตัวละครที่เลเวลอัพเต็มไปพร้อมกัน เพราะอะไร ฝากไปคิดเป็นการบ้านนะครับ ฝากการบ้านอีกข้อครับ ถ้าหากเราเอาโค้ดของเราไว้ด้านบนโค้ดของคนอื่น (ที่เลเวลอัพแล้วเพิ่ม 5000G) แทนล่ะ จะเกิดอะไรขึ้น เพราะอะไร โอโหวววว alias method ดีขนาดนี้ ทำไมไม่ใช้มันทุกครั้งไปเลย แม้ว่าการแก้ปัญหาด้วยวิธีการ alias method นั้นจะเป็นไปได้ด้วยดี แต่ว่ามันมีข้อจำกัดคือ เราสามารถใช้วิธีได้ หากเป็นกรณีที่เราแทรกโค้ดเพิ่มเท่านั้น เราไม่สามารถลบของได้เลย เช่น จากคำถามเมื่อปีมะโว้ ถ้าเราต้องการเอาเมนูเซฟออก ก็ไม่สามารถใช้วิธี alias method ได้ เพราะเราต้อง ลบโค้ดบางส่วนออกจากของเดิมนั่นเอง (แต่จริงๆ มันก็ได้แหละ แต่อาจจะตองใช้กระบวนท่าซับซ้อน) สรุปข้อดีของการ overwrite script
สรุป
สรุปทั้งหมด สิ่งที่บทความนี่ต้องการสื่อคือ บอกแนวทางการโม script และการเขียน script ให้เป็นระเบียบ ดังนั้นหากอ่านจบแล้วยังรู้สึกว่าโมอะไรไม่ได้เลย อย่าเสียใจหรือท้อแท้นะครับ เพราะสิ่งที่ท่านได้รับในบทความนี้คือพื้นฐาน แนวทางและทฤษฎี ยังไม่ได้ลองปฏิบัติก็ไม่แปลกที่ยังทำไม่ได้ครับ อนึ่ง สังเกตว่าสิ่งที่แก้ในบทความนี้นั้น มักจะเป็นการ เดา เดา และเดา ใช่ครับ การแก้โค้ดของคนอื่นไม่ใช่เรื่องง่าย ไม่ว่าจะเป็น RGSS หรือโค้ดภาษาอะไรในโลกก็ตาม ดังนั้นหากเป็นครั้งแรกที่ท่านทำอะไรแบบนี้แล้วไม่รู้เรื่อง งง ก็อย่าแปลกใจครับ อาศัยประสบการณ์ฝึกฝนเอาครับ เราฟันธงไม่ได้หรอกว่าโค้ดส่วนไหนคืออะไร แต่เนื่องจากโครงสร้างที่ผู้สร้าง RGSS ออกแบบมาดีมาก รวมถึงมีคอมเมนต์สีเขียวที่อ่านเข้าใจง่าย เชื่อผมว่า ฝึกไม่นานครับ ^^ และแน่นอนว่า ท่านก็อาจไม่รู้เหมือนกันว่าจะเก็บประสบการณ์จากไหน เพราะไม่รู้จะฝึกอย่างไร ในจุดนี้หากมีคนสนใจบทความนี้เป็นจำนวนหนึ่ง ผมจะตั้งกระทู้ใหม่เรื่อยๆ เป็น WORKSHOP ให้ทำ ตั้งแต่การตั้งโจทย์ แนวคิด วิธีแก้ไขปัญหา ไปจนถึงการเขียนโค้ดทุกขั้นตอน ดังนั้นไม่ต้องกลัวครับ ผมมีโจทย์มาให้ฝึกแน่นอน ^^ และผมยังคงบอกได้คำเดิมว่า เนื้อหาในบทความนี้เป็นเพียงเนื้อหาเบื้องต้นเท่านั้น ในการฝึกช่วงแรกๆ อย่าไปโมอะไรที่มันหลุดโลกเกินไป เพราะในบางเคสนั้น การเดาโค้ดอาจต้องกระโดดไปมาดู 4-5 ไฟล์ถึงจะเข้าใจว่าโค้ดทำงานอย่างไร ทำไม่ได้จะท้อเปล่าๆ ซึ่งหากมีเวลาว่างพอ ผมจะมาเขียนบทความในส่วนของเทคนิคการเดาโค้ดแบบกระโดดข้ามไฟล์อีกครั้งครับ ตอนนี้เอาส่วนนี้ให้แม่นก่อนละกันนะคร้าบ แต่ถ้ามั่นใจว่าทำได้ ลุยเลยครับผม! สุดท้ายนี้ ขอให้สนุกกับการเขียนโค้ดทุกคนครับ แบบฝึกหัด ทุกข้อต้องใช้วิธีการ overwrite / alias method ตามความเหมาะสม ให้สร้างโปรเจกต์ใหม่ขึ้นมา โดยไม่ต้องใส่ script อื่นใด
RE: พื้นฐานการโม Script เบื้องต้น - Neoz Kaho - 06-12-2015 ชอบมากครับบทความนี้ เกลียดสุดๆ เลยการต้องโมสคริปต์แล้วมานั่งงง พอมีอธิบายแบบนี้ค่อยเข้าใจง่ายขึ้นเยอะเลย RE: พื้นฐานการโม Script เบื้องต้น - Mysticphoenix - 06-12-2015 มีประโยชน์มากเลยคับ RE: พื้นฐานการโม Script เบื้องต้น - dreamknight - 06-12-2015 ;3 ปักหมุดไว้เลยครับ กระทู้แบบนี้ ;w;b RE: พื้นฐานการโม Script เบื้องต้น - Nazuth - 06-12-2015 เยี่ยมครับเดี๋ยวปักหมุดกระทู้ไว้ให้คนศึกษาเลย RE: พื้นฐานการโม Script เบื้องต้น - anime13master - 06-12-2015 โคตรจะมีประโยชน์เลยครับ ท่านอธิบายได้เข้าใจง่ายและเห็นภาพมากๆ ส่วน Aliasing นี่ผมยังทำไม่เป็นเลย ใช้วิธี Overwrite เอาตลอด พออ่านบทความท่านแล้วเข้าใจหลักการ ที่นี้ก็ทำเป็นขึ้นมาทันทีเลยทีเดียว RE: พื้นฐานการโม Script เบื้องต้น - Muge9thD - 06-12-2015 อธิบายได้เข้าใจง่ายดีฮับ จากที่เคยเข้าใจอะไรผิดๆในส่วนของการ alias ก็เข้าใจได้ถูกต้องกว่าเดิมแล้ว RE: พื้นฐานการโม Script เบื้องต้น - lottovvv - 06-12-2015 ขอบคุณมากๆ ค่ะ เดี๋ยวมีเวลาแล้วจะมานั่งศึกษา/ทดลองจริงๆ จังๆ ซะที RE: พื้นฐานการโม Script เบื้องต้น - zychrominny - 06-12-2015 กระทู้เลอค่า ต้องปริ้นเก็บไว้อ่านเสียแล้ว RE: พื้นฐานการโม Script เบื้องต้น - splendith - 06-13-2015 ขอบคุณทุกท่านสำหรับความเห็นนะครับ และขอขอบคุณเป็นอย่างยิ่งที่เห็นความสำคัญและปักหมุดบทความเล็กๆ บทความนี้ -/\- ถ้ามีโอกาสจะเขียนบทความเกี่ยวกับ พื้นฐาน Ruby และ Class โดยละเอียดอีกครั้งครับ |