ทำเกมด้วย Java ใน 5 สัปดาห์ (OOP Proj.)

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

บล๊อกนี้ไม่ได้ใช้ศัพท์ยาก อ่านได้ทุกคน

วิชานี้คือวิชา Object-Oriented Programming (ซึ่งทุกคนพร้อมใจกันลงความเห็นว่ามันคือวิชา Java ดีๆ นั่นแหละ) มีโจทย์คือให้พัฒนาเกมด้วยภาษา Java โดยที่อย่าง่ายหรือยากเกินไป กำหนดนำเสนอในวันที่ 21 พ.ย. 2560 โดยก่อนที่จะเริ่มทำกันได้ เราก็ต้องคิดเนื้อเรื่องและรายละเอียดคร่าวๆ ของเกมก่อนว่าจะเป็นอย่างไร แล้วนำไปคุยกับอาจารย์ว่าผ่านหรือไม่ เกมที่เราทำกันในครั้งนี้คือเกมแยกขยะครับ

เนื้อเรื่อง

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

เกมนี้เป็นเกมแนวกดตามจังหวะ (rhythm) ที่ผู้เล่นจะต้องกดถังขยะให้ตรงกับจังหวะที่ขยะเลื่อนมา (ให้นึกถึงเกม Tap Tap กับ Osu ดูครับ) ซึ่งความยากของมันนอกจากจะต้องกดให้ตรงแล้ว ก็คือการต้องแยกขยะให้ลงไปในถังขยะที่ถูกต้องด้วย

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

วางแผน

เราวางแผนการทำงานไว้ว่า ด้วยกรอบเวลาที่เร่งรัดแบบนี้ เราจะมีการประชุมกันอย่างน้อยสองครั้งต่อสัปดาห์ เรียกว่า “GHO” หรือ Google Hangouts และจะมีการนัดออกไปทำงานอย่างน้อยสัปดาห์ละครั้ง เรียกว่า “RHO” หรือ Real Hangout

จริงๆ แล้วเราไม่เคยเรียกชื่อแบบข้างบนนี้เลย 🌝

ประชุมครั้งแรก

เครื่องมือที่ใช้

  • VCS: ใช้ Gitlab ที่ดีพลอยมาเพื่อโปรเจ็กต์นี้โดยเฉพาะ เพราะ GitHub เร็วไม่ทันใจ และ Gitlab เองก็มีฟีเจอร์ที่เราต้องการเยอะด้วย (เราโฮสต์ Gitlab บน Google Cloud Platform ที่ asia-southeast1-a ครับ)
  • กระดานจัดการงาน: เนื่องจาก Gitlab มีฟีเจอร์นี้มาให้พร้อม (แถมทำงานได้ดีอีกต่างหาก) เราเลยมาใช้บอร์ดบน Gitlab ไปเลย และนี่ก็เป็นอีกเหตุผลหนึ่งที่ใช้ Gitlab แทน GitHub ด้วย (GitHub ก็มีบอร์ดนะ แต่ฟีเจอร์ไม่แน่นเท่า Gitlab)
  • แชร์ไฟล์: Dropbox
  • การสนทนา: Telegram
มุก อาร์ทของทีม

อาร์ท

อาร์ทของเกมทีแรกตั้งใจให้เป็นแนว 8 บิต แนวน่ารักๆ แบบ Tape it Up!, Tiny Tower, Super Cat Bros แต่ทำไปทำมาได้เกมมุ้งมิ้งชมพู้ชมพูมายลิตเติ้ลโพนี่มาซะงั้น อาร์ทจริงๆ แล้วสวย แต่พอเอามาโค้ดกันจริงๆ ด้วย libGDX แล้วยุ่งยากมาก ต่างจากการเขียน CSS ลิบลับ ดังนั้นจากสกรีนช็อตต่างๆ ก็จะเห็นได้ว่าดีไซน์บางจุดยังไม่ลงตัวอย่างที่มันควรจะเป็น เพราะการโค้ดมันไม่ง่ายเลยยยย 💆‍♂️

เริ่มโค้ด!

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

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

ลืมบอกไปว่าตั้งแต่สัปดาห์แรก เรามีแล็บเน็ตเวิร์กทุกเย็นวันอังคารพอดี เลิกหนึ่งทุ่ม สนุกสนานกันไปอีก

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

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

ช่วงแรกใช้แรมเกือบ 4 GB

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

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

ใช้ผังโน้ตเดียวกับ Osu

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

หาที่ทำงานยากมาก

Starbucks อีกแล้วครับท่าน
เครียดเลยครับ
น้อง Wiput เทสเตอร์คนแรก

ปัญหาหนึ่งเวลาจะนัดกันไปทำงานคือเราหาสถานที่นั่งทำงานยากมาก สุดท้ายเลยต้องไปลงเอยที่ Starbucks อยู่บ่อยๆ อันนี้เป็นที่ที่ไปนั่งทำงานกัน

  • Starbucks: ไปบ่อยสุดเพราะใกล้บ้านมีอยู่สาขาหนึ่ง และมีอีกสองสาขาที่ห่างออกไปอีกนิด สาขาที่ไปส่วนใหญ่ก็มีที่นั่งพอ มีปลั๊ก นั่งได้ยาว แต่เครื่องดื่มราคาสูง
  • McDonald’s: อยู่ตรงทางกลับบ้านพอดี นั่งยาวได้ อาหารถูก (กว่า Starbucks)
  • Burger King: อันนี้ของดี อยู่ใกล้บ้านเหมือนกัน อาหารถูก นั่งยาวได้ มีปลั๊ก โต๊ะใหญ่ นั่งได้ครบทีม ระหว่างทำงานก็ซื้ออาหารเพิ่มไปเรื่อยๆ ได้อีกแถมได้เฟรนช์ฟรายด์ฟรีถ้าทำแบบสอบถามอีก โอ้วววว
  • Dunkin’ Donuts: ใกล้บ้านอีกเช่นกัน นั่งยาวได้ ของถูก มีปลั๊ก คนน้อยมาก
  • Seacon Workspace: จริงๆ แล้วไปแค่ครั้งแรกครั้งเดียว 😂😂😂 คนเต็มตลอด ถ้าไม่ได้ไปตั้งแต่ห้างเปิดอย่าหวังจะได้นั่งถ้าไม่โชคดีจริงๆ
  • คณะ: จะขาดที่นี่ไปไม่ได้ เวลาเลิกเรียนก็นั่งทำงานกันที่นี่ก่อน
ปั่นงานกันคืนสุดท้าย

พรีเซนต์!

แก้บั๊ก

หลังจากนั่งปั่นงานกันถึงตีหนึ่งของวันพรีเซนต์ ทุกคนจึงตื่นมาพร้อมกับความรู้สึกอยากจะอาเจียนพร้อมกันโดยมิได้นัดหมาย 🧟‍♀️🧟‍♂️ (คือบอกเพื่อนไปว่าวันนี้รู้สึกเหมือนจะอาเจียน แล้วเพื่อนก็บอกว่ารู้สึกเหมือนกันทั้งกลุ่ม 😂) พวกเรามาถึงคณะกันประมาณ 8–9 โมง แล้วก็นั่งปั่นงานกันต่อ แก้บั๊ก ทำระบบบางอย่างให้เสร็จ เพื่อเตรียมพรีเซนต์เวลา 11.45 น. (เริ่ม 9.00 น. แต่เราได้คิว A9 ซึ่งเป็นคิวสุดท้ายของช่วงเช้า แต่ละกลุ่มมีเวลา 15 นาที เลยคำนวณมาได้ว่าน่าจะถึงคิวของเราเวลา 11.45 น.)

และแล้วเวลา 10.55 น. เพื่อนในกลุ่มก็บอกว่าให้รีบมา คิวต่อไปเป็นกลุ่มเราแล้ว… ตอนนั้นก็ตกใจกันสิครับ เร็วกว่าที่คำนวณไว้ตั้ง 1 ชั่วโมง เรารีบเก็บคอมแล้ววิ่งไปที่ห้อง M03 เพื่อเตรียมพรีเซนต์

ความวุ่น Y

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

เมื่อพรีเซนต์เสร็จ ถึงคราวเดโมเกม เราสลับอแดปเตอร์ VGA to USB Type-C มายังแมคอีกเครื่อง แต่ปรากฏว่าภาพไม่ติด! ลองกับแมคอีกสองเครื่องที่เหลือก็ไม่ติดอีก อาจารย์เลยเอาอแดปเตอร์ของอาจารย์มาให้ลอง แต่ก็ยังไม่ติดอีก เราเลยโคลน Git ลงไปในคอมหน้าห้อง พร้อมกับลองเอาคอมของมุกที่มีช่อง VGA มาต่อตรงดู เพราะคิดว่าอแดปเตอร์อาจจะเสีย (?) แล้วก็ปรากฏว่าต่อได้ เราจึงรีบตั้งค่าคอมของมุกเป็นโค้ดล่าสุดเช่นกัน พอภาพขึ้นจอ ก็มาพร้อมกับคำว่าแบตเตอรี่เหลือ 6 เปอร์เซ็นต์…. มุกเลยรีบไปหยิบปลั๊กมาชาร์จ วุ่นวายกันมากครับตอนนั้น 😂😂😂

ภาพจาก Dell ของมุกฉายขึ้นบนจอโปรเจ็กเตอร์ แต่แล้วมันก็ดับ พอขยับสายก็ติด แล้วก็ดับ ติดๆ ดับๆ จนพรีเซนต์ไม่ได้แน่ๆ แม้จะจับสายให้แน่นตลอดเวลาแล้วก็ตาม เอายังไงดี ถ้าจะทำให้คอมหน้าห้องรันได้ ก็ต้องไปโหลดผังโน้ตมาใส่ในเครื่องอีก (เพราะตอนนั้นยังไม่ได้เรียกผังโน้ตจาก asset ภายใน) พี่ท็อป นพณัฐ เลยเอาอแดปเตอร์ VGA to USB Type-C อีกอันมาให้ยืม ปรากฏว่าทีนี้ใช้ได้เป็นปกติแล้ว เราเลยกลับมาพรีเซนต์ต่อได้ และใช้ลำโพงบนแมคแทนลำโพงในห้อง เพราะสายเสียงก็เสีย!! 🤦‍♂️ ซึ่งก็ต้องขอบคุณที่รุ่นนี้ลำโพงดังมาก

มาคุยกับรุ่นพี่ทีหลัง เขาบอกว่า อ่อ ห้อง M03 ใช่มั้ย สาย VGA ห้องนั้นมันเป็นแบบนั้นอยู่แล้ว สายเสียงด้วย … 🙄

แล้วอาจารย์มีความเห็นอย่างไร? อาจารย์บอกว่าเกมเล่นยาก (ซึ่งมันก็จริงเพราะเรายังไม่มีใครเล่นกันผ่านเลย 😂😂😂) ถ้าจะเอาไปสอนเด็กให้แยกขยะก็น่าสนใจแต่มันเล่นยากเกินไป สุดท้ายก็พรีเซนต์กันเสร็จแบบงงๆ และรีบไปคอมไพล์เป็นไฟล์ JAR แล้วอัพโหลดขึ้นเซิร์ฟเวอร์ส่งงานต่อ

ตอนจบของเกม

ตอนจบของเกมคือ เมื่อเราเล่นครบทุกด่านและปลดล็อคขยะหมดทุกตัวแล้ว ก็จะได้รับประกาศนียบัตรนักแยกขยะ แล้วจากนั้นจะมีถังขยะโผล่มา 4 ใบ ให้เราเลือกว่าจะต้องทิ้งลงถังใบไหน จากนั้นเป็นอันจบเกม…

แต่เราทำกันไม่ทัน 🤣 แถมไม่มีการปลดล็อคขยะด้วยซ้ำเพราะทำกันไม่ทัน เลยแสดงขยะทุกตัวอยู่ในคอลเล็กชันไปเลย

ส่งท้าย

ในที่สุดก็ได้เวลาปิดโปรเจ็กต์นี้ ขอส่งท้ายกันด้วยสถิติดังนี้ครับ

วันที่มีคอมมิทมากที่สุดคือวันที่ 20 พ.ย. คืนก่อนส่งโปรเจ็กต์นั่นเอง มีคอมมิทมากถึง 47 คอมมิท (ถ้ารวม merge request ก็จะเป็น 100 กว่า) ต่างจากวันปกติที่มี 10 บ้าง 20 บ้าง แต่ช่วงใกล้ส่งก็มีคอมมิทมาถี่ขึ้น

ตอนนี้ซอร์สโค้ดย้ายมาเก็บบน GitHub แล้ว ใครสนใจสามารถเข้าไปดูได้ที่ https://github.com/sagelga/trashmelody

สุดท้ายอยากจะบอกว่า 8 × 3 = 16 นะครับ

📮 Have new posts emailed to you


Posted in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.