ควรมี flash game ถีบเนยสดได้แล้ว คือจับเวลา 1 นาที ให้เราพิมพ์คำว่าถีบเนยสดให้ได้มากที่สุด แล้วแมวเนยสดก็หน้าน่วมๆไปด้วยไรงี้ เก็บสถิติด้วย
— แม็คคลี่ (@McKiEz) December 14, 2013
(ว่าแต่ใครมันจุดกระแส #ถีบเนยสด ฟระ Orz)
เลยจัดการซะคืนนั้นเลย ... ถ้าไล่ดูตาม commit log จะเห็นว่าใช้เวลาไป 2 เดือนพอดีจนปิดโปรเจคได้ ก็นับว่าใช้เวลาเยอะโขอยู่กับโปรเจคขำๆ
ทำให้รู้เลยว่า ส่วนที่ยากที่สุดของการทำเกมนั้น ไม่ใช่การ coding ไม่ใช่การ debug แต่เป็นการออกแบบ game play ให้น่าสนใจ ผู้เล่นต้องรู้สึกว่าไม่ยากเกินความสามารถ ในขณะเดียวกัน เมื่อเล่นจบแล้วก็ยังกลับมาเล่นซ้ำๆ ได้อีกโดยไม่เบื่อ
ซึ่งเวลาส่วนใหญ่ที่หมดไปก็เพราะเจ้าเนี่ยแหละ จริงๆ ถ้าดูตาม log อย่างละเอียดแล้วลองคำนวณเวลาที่ใช้ จะพบว่าโปรเจคนี้ทำเสร็จภายใน 42 ชั่วโมง (บวกลบไม่เกิน 10%) ถ้ามีไอเดียเจ๋งๆ เกี่ยวกับ game play เตรียมไว้อยู่แล้ว
แต่ก่อนที่จะไปดูการออกแบบเกมนี้ ลองเรียนรู้จากเกมอื่นๆ ก่อน
Flappy Bird
- infinity - เล่นได้เรื่อยๆ จนกว่าจะพลาดหรือเบื่อ
- social - อวดคะแนนแข่งเพื่อน
- reflex - ตอบสนองทันทีต่อสิ่งใหม่
Super Hexagon
- goal set - เกมตั้งจุดมุ่งหมายให้แล้ว
- social - แต่จะแข่งกับเพื่อนก็ได้
- reflex - ตอบสนองทันทีต่อสิ่งใหม่
Jubeat
- goal set - เกมตั้งจุดมุ่งหมายให้แล้ว
- social - แต่จะแข่งกับเพื่อนก็ได้
- rhythm - เกมเข้าจังหวะ
The Typing of the Dead
- goal set - เกมตั้งจุดมุ่งหมายให้แล้ว
- co-op - ร่วมมือกันเล่นได้
- reflex - ตอบสนองทันทีต่อสิ่งใหม่
Diablo II
- goal set - เกมตั้งจุดมุ่งหมายให้แล้ว
- co-op - ร่วมมือกันเล่นได้
- leveling - ตัวละคร/ด่านมีพัฒนาการ
จริงๆ ตอนเอาไอเดียมาแปลงเป็น game play ก็ไม่ได้ไล่คิดถึงเกมอื่นเยอะขนาดนี้หรอก (เอ หรือมันจะเป็น unconscious?) แต่อยากได้แบบ infinity+leveling และคิดว่าต้องปรับแน่ๆ ดังนี้
- เกมฝึกพิมพ์ภาษาไทยยากมาก ทั้ง font เล็ก ทั้งสระบนล่าง ... ทำภาษาอังกฤษง่ายกว่า
- 1 นาทีจะว่านานก็นานเกินไปสำหรับเกมฝึกพิมพ์ ยิ่งเจอแต่คำซ้ำๆ นี่ยิ่งน่าเบื่อ
- แต่ 1 นาทีก็สั้นเกินไปถ้า random คำมาได้ไม่ซ้ำกันเลย
- เลยคิดว่าทำเป็นระบบหัวใจดีกว่า พิมพ์ไม่ทันก็โดนโจมตี หัวใจหมดเมื่อไหร่ก็จบเกม
- ถึงแม้ส่วนกริยาจะไม่ซ้ำจากการ random แล้ว แต่ให้พิมพ์ชื่อ (@neizod) บ่อยๆ ก็เบื่อได้เช่นกัน เลยทำระบบเก็บคำกริยาหลายๆ คำไว้ก่อน แล้วค่อยพิมพ์ชื่อเมื่อต้องการจบประโยค
- อนึ่ง ในความเป็นจริงเกมก็ไม่ได้มี word list ใหญ่ขนาดนั้น เลยหาแผนมารับมือเวลาเจอคำซ้ำไม่ให้รู้สึกเบื่อ คือเมื่อพิมพ์ศัพท์ซ้ำจะทำการดึงคำนั้นออกจากประโยคที่กำลังสร้างซะเลย
ตอนนี้ก็ได้ game play หลักมาครบแล้ว ซึ่งเอาจริงๆ prototype พวกนี้ให้ทำ 3-4 วันก็เสร็จ
แต่ก่อนหน้านั้นก็มีสิ่งที่สำคัญไม่แพ้กัน คือการเลือก engine สำหรับโปรเจคนี้ครับ
- เลือกเป็นเว็บเพราะทำ GUI ได้ง่ายและเร็วสุด (จริงๆ คือเป็นอยู่แค่เว็บ 555+)
- ตอนแรกก็ว่าจะใช้ canvas เพราะทุกอย่างสามารถยัดเป็น JavaScript ล้วนเลยได้ แต่ก็จะไม่ได้ฝึก CSS อีกทั้งเกมนี้ยังเป็นแบบ text-base ไม่ใช่เกมตัวละครลุยด่าน เลยคิดว่าเล่นกับ DOM ดีกว่า
- จะเล่นกับ DOM ทั้งที ก็ต้อง jQuery และ
position: absolute
สิครัช - ถ้า JavaScript เขียนสั้นๆ ก็พอไหว แต่มาเขียนซับซ้อนๆ แบบนี้ CoffeeScript เถอะครัฟ จะได้ไม่เป็นภาระ @plynoi
- ไม่ได้ใช้ framework อื่นใดช่วยอีกเพราะไม่ค่อยรู้จัก + learning curve ท่าทางจะสูงน่าดู รอลุยโปรเจคนี้เสร็จพลังวัตรน่าจะกระโดดข้ามไปอีกขั้น
- ไม่อยากแตะ database เท่าไหร่เพราะต้องใช้ host แยก ไม่งั้นก็ไปขอ AppEngine ที่ตอนนี้เก็บครบโควต้าแล้ว
- เลยกะว่าเอาง่าย เล่นเกมเสร็จก็ทวีตคะแนนซะเลย ใครจะโกงก็ช่างมัน (แต่ประสบการณ์ก็บอกว่าไม่ค่อยมีใครโกงหรอก เท่าที่สังเกตจาก Temple Run)
- พอไม่แตะ database ทุกอย่างเป็น static หมด ก็หา host ง่ายขึ้นจม แต่มีที่เดียวที่ผุดมาในใจคือ GitHub Pages
พอรู้ spec env ครบก็สบายใจไปกว่าครึ่งแล้ว
จุดต่อมาคือระบบคิดคะแนนต่างๆ (ที่อู้ไปเป็นเดือนเพราะคิดส่วนนี้ไม่ออก) การจะออกแบบตรงนี้ได้ถ้ารู้จักแนวโน้มกราฟแบบต่างๆ จะได้เปรียบพอสมควร ผลสุดท้ายผมออกแบบดังนี้
- ค่าหลักของเกมคือคะแนน ซึ่งควรคิดตามจำนวนตัวอักษรต่อคำที่พิมพ์เข้าไป เช่น kick ได้ 4 คะแนน เพราะมี 4 ตัวอักษร
- อย่างไรก็ตาม การคิดคะแนนที่ 1 ตัวอักษร = 1 คะแนน อาจทำให้เบื่อได้ และยังไม่ได้ใช้ประโยชน์จากการบังคับพิมพ์ชื่อ (@neizod) เท่าไหร่ด้วย
- คิดว่าอีกปัจจัยที่ควรจะมีผลต่อคะแนนคือเลเวล (เหมือนเกมอื่นๆ) ยิ่งผู้เล่นเลเวลสูงก็น่าจะได้คะแนนเยอะ เลยเอาคะแนนที่ได้ไปคูณด้วยเลเวลเมื่อพิมพ์จบประโยค
- แต่ก็ไม่อยากให้ผู้เล่นเก็บคำศัพท์ไว้เป็น 20 คำแล้วค่อยจบประโยคเพื่อคูณคะแนนตูมเดียว เลยให้แค่คำแรกของประโยคที่ได้คูณเลเวลเต็มๆ คำถัดๆ มาก็คูณกับค่าเลเวลที่ลดลงเรื่อยๆ จนคำท้ายๆ ไม่ได้ประโยชน์จากการเก็บดองคำศัพท์ไว้ไม่ยอมสร้างเป็นประโยคซักที
- ส่วนการเพิ่มเลเวลนั้นก็คิดจากคะแนน ตรงนี้ไม่อยากให้คะแนนต่อเลเวลเป็นกราฟเส้นตรง เพราะจะทำให้ตัวคูณเพิ่มเร็วมาก และเนื่อจากไม่ค่อยชอบกราฟกำลังสอง เลยเลือกค่าคะแนนสำหรับเพิ่มเลเวลต่อไปเป็นแบบเอกซ์โพเนนเชียลซะ
- หัวใจลดได้ก็ย่อมเพิ่มได้ ง่ายสุดไม่คิดอะไรแล้ว เลเวลเพิ่มเมื่อไหร่ หัวใจเพิ่มเมื่อนั้น (เชื่อว่าระบบการเพิ่มเลเวลถูกออกแบบมาเป็นอย่างดี 555+)
- แต่แน่นอนว่าเพิ่มเลเวล = เพิ่มความยาก ในที่นี้ก็คือเพิ่มจำนวนคำศัพท์บนหน้าจอให้ออกมาเท่ากับเลเวล และเพิ่มความเร็วให้มันทีละนิดๆ
ถ้าแม่น math หน่อย ระบบพวกนี้ implement เข้าไปไม่นานครับ ดีไม่ดีเร็วกว่าออก prototype ข้างบนอีก ปัญหาคือจะทำได้เร็วๆ นี่ต้องไอเดียบรรเจิดมาก ควรหา paper ด้านจิตวิทยาและการออกแบบเกมอ่านตุนไว้เป็นอย่างยิ่ง :p
พอ core ทั้งหลายเสร็จแล้ว ก็แต่งสวยครับ
- จริงๆ ก็อยากให้เจ้าแมวสดโดนชก/ถีบหน้าน่วมนะ แต่มันทำยากซะเหลือเกิน เลยเลือกๆ อารมณ์มาตรฐานที่เว็บมันมีให้มาให้แทน ได้มา 8-9 แบบก็น่าจะพอ
- พื้นหลังนี้ก็เลือกนานเหมือนกัน คิดไว้ว่าอยากได้โทนสว่างๆ ก็เลือกเหลืองอ่อน เลยได้น้ำเงินอ่อนติดมาด้วยในตอนแรก (สีคู่ตรงข้ามกันพอดี) ทำไปทำมาได้สีแดงตอนจบเกมมาด้วย เลยต้องเลื่อนสีน้ำเงินให้ออกไปฟ้าๆ หน่อย โทนสีจะได้เป็นรูปสามเหลี่ยม
- ตอนแรกไม่ได้คิดว่าจะเอาเจ้าแมวสดมาไว้ด้านล่าง แต่จะเอาไว้เป็น background เลย ซึ่งคิดไปคิดมาก็คงไม่เหมาะเพราะรบกวนสมาธิผู้เล่นเกินไป เลยย้ายมาอยู่มุมล่างขวา ด้านที่คำศัพท์ต่างๆ พรั่งพรูออกมานั่นเอง
- ทำให้พวก status ผู้เล่นอย่างคะแนนสะสม/เลเวล/หัวใจที่ตอนแรกวางไว้ว่าจะให้กระจัดกระจายตามขอบต่างๆ ของจอ ถูกจับมาอัดรวมกันไว้เป็นกล่องทางด้านซ้ายในสไตล์เดียวกัน
- ที่เหลือก็จับปุ่มโน่นนี่นั่นยัดเข้ามาไม่ให้มันดูโล่ง
- สุดท้ายคือ tutorial เกม หัวใจสำคัญที่ขาดไม่ได้แม้เกมจะง่ายแค่ไหน ใครจะไม่ดูก็ช่างเขาแต่เราจะพรีเซนต์!
หลังจาก implement เสร็จหมดก็ได้ฤกษ์ปล่อยเกม ตามไปเล่น (ด้วยความรัก) ได้ที่ neizod.github.io/kick เลยครับ \(;w ;)/