Translate

แสดงบทความที่มีป้ายกำกับ android game แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ android game แสดงบทความทั้งหมด

วันอังคารที่ 22 เมษายน พ.ศ. 2557

พัฒนาเกม RPG บน android ด้วย AndEngine (3)

นานโขที่ไม่ได้ update blog ส่วนตัวเลย พับผ่าสิ!!

วันนี้กลับมามองที่ บทความ การพัฒนาเกม RPG ที่ค้างเอาไว้ ก็คิดว่ายังมีน้องๆ หรือผู้เริ่มศึกษา android อีกหลายต่อหลายคนที่ต้องการ code ในการนำไปเป็นต้นแบบ เพื่อศึกษาหรือต่อยอดต่อไป

เพราะฉะนั้น ^_^ มาต่อกันเลยครับ...

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




มีการควบคุมดังนี้ครับ
  • ถ้าเดินไปด้วยแล้วกดปุ่มสี่ฟ้า หน้าปุ่มสีฟ้าจะเปลี่ยน แล้วตัวละครหญิงจะเดินเร็วขึ้น สังเกตค่าที่ B button:speed ครับ จะเพิ่มหรือลดลง
  • ตรงคำว่า "แม่น้ำนั้น" ผมใช้ test การแสดงผลภาษาไทย อันนี้ได้ 100% และ x กับ y ก็คือ ตำแหน่ง Position x,y ที่ตัวละครเรากำลังอ้างอิงอยู่
  • กดปุ่มสี่แดงจะเหมือนกับเป็นปุ่ม action
  • การเล่นเบื้องต้น ก็ควบคุมตัวละครเดินไปพูดคุยกับ UPC ต่างๆ ดูครับ โดยให้ลองไปคุยกับสองตัวที่อยู่ 2 ตำแหน่งตามรูปด้านบนดู นอกนั้นถ้าไปคุยกับคนอื่น จะมีแค่ ... แสดงออกมา


...ดูไม่มีอะไรมาก แต่ก็น่าจะเป็นการเริ่มต้นที่ดีของใครหลายๆ คนสำหรับ เกม RPG บน android นะครับ ส่วนอันนี้ Source Code ครับ รับรองว่า ไม่มี code ส่วนไหน ส่งข้อมูลอะไรไปที่ไหนแปลกๆ แน่นอน ปลอดภัย 100% ครับ (ให้ load เฉพาะจาก github ของผมนะ อย่าไปเอาจากคนอื่นที่ folked ไป ไม่รับประกัน)

source code ครับ : https://github.com/pilotpol/classicrpg2
* หมายเหตุนิดหน่อยครับ ตัว map นี้ผมได้ดัดแปลงตัว library ของ andengine นิดหน่อย เพื่อให้ทำการอ่านค่า layers ของ map ได้หลากหลายมากขึ้นนะครับ เพราะการสร้างเกม RPG ในแบบของผมจะเน้นให้เขียน event ไว้ที่ map โดยตรงครับ


หลังจาก clone git repo มาลงเครื่องแล้ว ก็จะเห็น source code ทั้งหมด เอาไปสร้าง project ตามที่เคยบอกไว้ในตอนก่อนๆ นะครับ แล้วลองรันดู ปุ่มต่างๆ มีคำอธิบายดังนี้ครับ

ตัว control - ตัวนี้โดยปกติทั่วไปแล้ว จะแยกเป็น 2 ส่วน คือ ส่วนฐาน กับ ส่วนที่เป็นจอยสติ๊ก ใน project ของผม ผมทำส่วนที่เป็นจอยสติ๊กเป็นโปร่งใสไว้ ก็เลยจะไม่เห็น (ส่วนตัวชอบเห็นฐานอย่างเดียว) ซึ่งเพื่อนๆ พี่ๆ น้องๆ ที่ clone repo ไป สามารถไปดัดแปลงรูปตามใจชอบได้เลยที่ assets/gfx/ ครับ

...มาเริ่มกันเลย...^_^
ตอนนี้จะพูดถึงเรื่อง map ก่อนครับ
เนื่องจากเป็นเกม RPG ซึ่งแนวคิดคือ จะเป็นฉากๆ ไปเรื่อยๆ และในฉากจะมีตัวละคร ดังนั้นแนวคิดที่ผมวางไว้สำหรับ Project นี้คือ การเอาพวก event ต่างๆ ที่จะเกิดขึ้นไปใส่ไว้ใน map เพื่อที่ว่าหากมีการเปลี่ยนแปลงแก้ไข ก็ทำได้เลยที่ map ไม่ต้องยุ่งกับ code ทำเสร็จก็ build ข้อดีคือสามารถทำงานเป็นทีมได้ในอนาคตครับ

ก่อนจะแก้ไข map ใน project ทุกคนต้องมี โปรแกรม Tiled ก่อนนะครับ หาโหลดได้ฟรี จากที่นี่ครับ http://www.mapeditor.org/ ต้องขอบคุณทีมงานคุณ Thorbjørn Lindeijer ด้วยครับ ใครมีสตางค์ หรือคิดจะทำเกมขึ้น Play Store จริงๆ จังๆ ก็ Donate ให้เขาหน่อยนะครับ

เปิดโปรแกรม Tilted ขึ้นมาครับ แล้วเปิดไฟล์ desert.tmx ซึ่งอยู่ใน /assets/tmx/ ครับ

เมื่อเปิดแล้วจะมีหน้าตาแบบด้านล่าง
อันนี้ด้านซ้าย

อันนี้ด้านขวา ถ้าใครไม่เป็นแบบนี้ลองดู tab เลือกที่ layers นะครับ

จากรูปจะเห็นว่าที่ด้านซ้ายของจอ มีสี่เหลี่ยมที่เขียนว่า origin อยู่ อันนั้นเป็นตำแหน่งเริ่มต้นของตัวละคร ซึ่งข้อมูลที่อยู่ใน map นี้ก็ต้องสัมพันธ์กับฝั่ง Code ที่เขียนด้วยนะครับ โดยความสัมพันธ์ทั้งหลายจะอยู่ใน function readMapObjects ที่บรรทัด 466 ครับ ซึ่งจะอธิบายต่อทีหลัง

การสร้าง map ก็ง่ายๆ ถ้าใครเคยเล่นตัว rpgmaker มาก่อนแล้ว อันนี้ก็แนวคิดเดียวกันครับ โดยเลือกขนาดแผนที่ เอาเมาส์เลือกรูปที่กรอบด้านขวาล่าง แล้วมาระบายในกรอบใหญ่ด้านซ้าย

ให้คลิกที่ objects ครับ หน้ากรอบด้านขวาบนจะเปลี่ยนเป็นแบบนี้

อธิบายตามแผนที่เลยครับ ในขั้นต้นนี้แผนที่เราจะมีตัวละครอยู่ 2 แบบ คือ 
  1. UPC จะเป็นหุ่นที่อยู่นิ่งๆ (ก็ขยับแบบยืนอยู่กับที่นะครับ แต่ยังไม่ให้เดินไปไหน) และ
  2. Player ตัวละคร ที่เราสามารถบังคับไปไหนมาไหนได้บนแผนที่ครับ
ถ้า ดับเบิ้ลคลิกดูที่ player ตามรูปด้านบน จะเห็นมี property "origin" โผล่ขึ้นมาครับ อันนี้คือ สี่เหลี่ยมที่เรากำหนดไว้ตอนแรกนั้นเอง ใน code จะอ่านค่าพวกนี้แล้วนำไปแสดงผลตามที่ตั้งไว้ครับ

ลองดูที่ upc กันบ้าง เยอะแยะเลยทีเดียว

จะเห็นว่ามี properties หลายตัว มี man1,man2, man3 ... (ต่อไปจากนั้น ผมขี้เกียจเปลี่ยนชื่อครับ ถ้าจะให้ดี ควรเปลี่ยนชื่อให้ตรงกับตัว UPC ที่วางไว้ด้วยนะครับ)

ทีนี้ลองมาดูที่เหลืออีกอันครับ walkable

จะเห็นว่ามีว่างๆ อยู่ ตรงพวกนั้นก็คือ wall ครับ เป็นส่วนที่ไม่ให้ player เราเดินผ่าน ที่ว่างๆ คือ ผมขี้เกียจใส่ชื่ออีกเช่นเดิม จริงๆ ควรใส่นะครับ

ลองไปที่กรอบขวาครับ เลื่อนไปหาตำแหน่งตามรูปด้านล่าง แล้วดับเบิ้ลคลิกดู จะเห็นหน้าต่าง property ขึ้นมา



อันนี้คือ กำหนดชื่อว่า wall โดยมี property 1 ตัว ชื่อ walk มีค่า no ซึ่ง object อย่าง UPC ก็มี property เหมือนกันครับ
*หมายเหตุอีกครั้งนะครับ อันนี้ไม่ใช้มาตรฐานกลางใดๆ เป็นการตั้งมาตรฐานขึ้นมาใช้เองด้วยของผม เพราะฉะนั้นทุกคนจะเปลี่ยนค่าใดๆ ต้องดูให้สัมพันธ์กับ code ด้วยครับ

ลองเลื่อนแผนที่ไปทางขวาจะเห็นกรอบสี่เหลี่ยมที่เป็น object UPC ดังรูป ดับเบิ้ลคลิกตัวที่ยื่นออกมาจากแถวดูครับ


สำหรับตัว UPC ตัวนี้พิเศษกว่าตัวอื่นๆ คือจะมีคำพูดโต้ตอบกับ player เราด้วย ดังตัวอย่าง ใช้ Name ว่า talk นะครับ ลองเปลี่ยนคำพูดเป็นคำอื่น แล้ว save จากนั้นไป build โปรเจ็คใหม่ดู (refresh project ก่อนนะครับ) จะเห็นว่า แอพฯ ที่สร้างขึ้นใหม่ ถ้าผู้หญิงเดินไปพูดกับ UPC คนนี้ คำพูดก็จะเป็นตามที่คุณๆ เปลี่ยนกันไปครับ

ภาษาไทยก็เช่นกัน พิมพ์ลงไปตรงๆ ได้เลย อ่านออก ^_^ แบบนี้ก็ทำเกม RPG ภาษาไทยได้สบายแฮ
ตัว UPC อยู่ตรงขวาล่างครับ

มาดูที่ code กันเล็กน้อยครับ เผื่อว่าใครจบบทความนี้แล้วอยากจะเปลี่ยนอะไรนิดๆ หน่อยๆ แล้วลอง run ใหม่ดู

บรรทัดที่ 472 ของไฟล์ Testgame.java นะครับ จะมี เงื่อนไขอยู่ดังนี้
if (group.getTMXObjectGroupProperties().containsTMXProperty("walk","no"))
ก็คือ ถ้า property walk = no แล้วล่ะก็ ให้ทำตาม code ที่อยู่ใน block ด้านล่างของ if นี้ครับ code ใน block นี้เป็นการ กั้นไม่ให้ตัว player สามารถเดินผ่านได้ โดยใช้ PhysicsFactory ของ 2Dbox เข้าช่วยในการตรวจจับ collision (การปะทะกันของ 2 objects )ครับ

เช่นกันกับ if block อันอื่นครับ ด้านล่างนี้เป็นจุดเริ่มต้นของ player

if (group.getTMXObjectGroupProperties().containsTMXProperty("player", "start"))
ตำแหน่งที่มีชื่อว่า origin นั่นแหละครับ ตัวต่อมาครับ หน้าที่ของ UPC
if (group.getTMXObjectGroupProperties().containsTMXProperty("upc","upc"))
อันนี้จะต้องลงลึกนอกเหนือจากชื่อ layers หน่อย ซึ่งพอมาถึง if ตัวนี้ โปรแกรมจะ loop แล้วตรวจลึกลงไปอีกชั้นว่า ใน TMXProperty ที่ชื่อ upc มี properties ย่อย ทำหน้าที่อะไรอยู่บ้าง และจะให้ทำอะไร อธิบายได้ตาม code ดังนี้ครับ

ใน for loop block จะหาค่า property ที่ชื่อว่า image โดยเทียบดูว่ามีค่าตรงกันกับคำว่า hero หรือเปล่า (ใน if นี่จะคืนค่า true นะครับ

if (object.getTMXObjectProperties().containsTMXProperty("image", "hero"))
ซึ่งก็คือ พวก upc ที่เราใส่ค่าไปใน map นั่นเอง แล้วถ้าใช่ล่ะ ก็ทำสิ่งด้านล่างต่อครับ

Upc hero = new Upc("player.png", object.getX(),
object.getY(), this, scene, this.mPhysicsWorld,
SPEED);
hero.setDirection(2);
hero.setTalk(object.getTMXObjectProperties()
.getValuefromName("talk"));
UPChandle.add(hero); 

  • สร้าง object ใหม่คือ UPC (ตัว object อันนี้คือ ไฟล์ UPC.java ที่มีอยู่ครับ ลองศึกษา code หรือปรับเปลี่ยนเพิ่มเติม เพื่อเพิ่มความสามารถให้กับ UPC ได้)
  • จากนั้นตั้งว่าตัว UPC ตัวนี้จะให้หันไปด้านไหน (ก็เปลี่ยน code เป็น random ไปได้นะครับ)
  • setTalk โดยดึงเอา property ที่มีชื่อว่า talk จาก map มา add เข้าไว้ครับ นั่นคือ ถ้าตัวละครเดินมาแล้วผู้เล่นกด a button (ปุ่มสีแดง) ก็จะแสดง คำพูดที่มุมบนด้านซ้ายของจอ ตามที่ตั้งไว้ใน map ครับ
  • สุดท้ายก็ add ตัวละครนี้ ลงไปใน UPChandle ซึ่งทำหน้าในการ draw UPC ทั้งหมดทั้งปวง เข้าไปวางไว้ในแผนที่ครับ

คงจะพอแค่นี้ก่อน สำหรับบทความนี้นะครับ ดูจะ hardcord มากไปหรือเปล่าเนี่ย code เริ่มเยอะ 

เดี๋ยวผมจะมาต่อในบทความหน้า แต่ยังไงก็ลองแก้ไข และปรับเปลี่ยนทั้ง 2 ฝั่งดูได้ตามใจชอบเลยนะครับ เพื่อศึกษาว่า code ไล่ตรงไหน เป็นไปอย่างไร จะได้เข้าใจ code มากยิ่งขึ้นครับ

จบบทความนี้ ผู้ที่สนใจจะสร้างเกม RPG บน android ทั้งหลาย คงมีไอเดียว่าจะทำยังไงได้มากขึ้นนะครับ แต่ก็ยังเหลืออีกเยอะ ทั้งใส่เสียง ใส่ effect บลา...บลา...บลา... ใครคิดจะทำจริงๆ จังๆ อาจจะต้องหาทีมเพิ่มเติม

...หรือไม่ ค้นหาเอาได้จาก google ครับ ผมเองก็เริ่มจากตรงนั้น จนมาแจก code ให้ทุกท่านได้นี่ก็ยังใช้ google ช่วยในสิ่งที่ติดขัดทุกครั้งครับ

ขอให้สนุกกับการเขียนเกม RPG ครับ...














วันจันทร์ที่ 17 มิถุนายน พ.ศ. 2556

พัฒนาเกม RPG บน android ด้วย AndEngine (2)


ในบทความตอนนี้ เราจะมาสร้างเกมเล็กๆ แบบในรูปข้างบนนี้ด้วย AndEngine กันครับ

ห่างหายไปนานมาก จากตอนที่แล้ว เนื่องด้วยผู้เขียนกำลังอ่อนแรง แต่ในเมื่อยังไม่ตาย ก็ต้องสู้ๆ ต่อไปล่ะนะ

ตอนที่แล้วผมเกริ่นเกี่ยวกับ AndEngine ไว้พอประมาณ และให้ load source code ลองไปศึกษากันดู ถ้ายังไม่มีก็ที่นี้เลยครับ http://pilotpol.blogspot.com/2013/05/rpg-android-andengine-1.html

ส่วนตอนนี้ก็จะอธิบายตามความเข้าใจของตนเอง เกี่ยวกับ Game Engine อันนี้ และการเขียนบน Android Platform แบบ Step by Step ตั้งแต่เริ่มต้นเลยก็แล้วกัน

1. เริ่มแรกก่อน ถ้าจะเขียน app อะไรสักอย่างบน android แบบ native ล่ะก็ ก็ต้องไป download AndroidSDK มาก่อน ถึงตรงนี้ทุกท่านที่ต้องการหา GameEngine สักตัวน่าจะมี และได้ลองเขียน HelloAndroid กันแล้ว ถ้ายังไม่มีก็ตรงนี้ได้ครับ http://pilotpol.blogspot.com/2013/05/android-thai-pilot-pray-2.html

2. หลังจากมี Android Developer Tools แล้ว และพอจะรู้หลักในการเขียน android แบบทั่วไปแล้ว (เรื่องเขียนไม่มีไรมากครับ ไปที่สร้าง project ใหม่ แล้วให้มันสร้างเป็นแนวทางให้ก็ได้) ต่อไปก็เตรียมตัวเรียนรู้ Engine ตัวนี้กันเลย !

บอกไว้ก่อนว่าผมไม่ได้อ่านจาก Cookbook ของ AndEngine โดยตรง เพราะฉะนั้นจึงอาจจะตกหล่นไปบ้าง และไม่ถูกหลักเท่าไร แต่ก็สามารถสร้างเกมตามต้องการได้ล่ะนะ

เริ่มจาก Download Library ของ AndEngine มา ตรงนี้ก็จะมีอยู่ 2 แบบ แล้วแต่ชอบ

  1. Download Source code มาเลยแล้วมาเปิด Project ใน Package Explorer ที่นี้พอเวลาสร้าง game ของเราเอง เราก็ต้องเรียกหาที่อยู่ของบรรดา Project AndEngine ทั้งหลายทุกครั้ง หาได้จากตรงนี้ครับ https://github.com/nicolasgramlich/AndEngine
  2. Download เฉพาะ Library ที่เป็นไฟล์ *.jar ไปวางไว้ที่ folder lib ภายใต้ project อันนี้ผมรวบรวมไว้ให้และมีแก้ไขเล็กน้อยเพื่อใช้สำหรับ project RPG ของผมเอง ตรงนี้ครับ https://docs.google.com/file/d/0B_raxIdscReBRnFMY05tR1daNms/edit?usp=sharing
แบบที่ 1 จะดีตรงที่ว่า เราสามารถแก้ไขไฟล์ต้นฉบับได้ตามใจชอบเลย ตรงไหนไม่มีอะไรก็เขียนแก้ไปเลย แต่ถ้าใครไม่ต้องการจะไปแก้อะไรเขาอยู่แล้ว จะเขียนด้วยความสามารถที่มีของ AndEngine เองก็ใช้แบบที่ 2 ก็ไม่ยุ่งยากดีครับ

ในที่นี้จะเอาง่ายๆ ไว้ก่อน ก็จะอธิบายเฉพาะแบบที่ 2 ก็แล้วกันนะครับ

มาเริ่มโปรเจ็คเล็กๆ กันเลยครับ

1. ไปที่ New > Android Application Project
ตั้งชื่อ app ชื่อ project ตามใจชอบได้เลยครับ แล้วก็ชื่อ package name ใครยังไม่ชำนาญ ก็ตั้งตามตัวอย่างไปก่อนก็ได้ครับ จากนั้นมาเลือก 4 ช่องล่าง ตามใจชอบอีกเช่นกัน สำหรับในตัวอย่าง ผมให้ app รองรับต่ำสุดที่  Android 2.3 เลือกรุ่นเป้าหมายคือ Android 4.0 เลือกตัวที่จะมา Compile Code คือ Android 4.2 และ Theme เป็นค่า default ของมันครับ จากนั้นกด Next > โลด...


 2. ลำดับถัดไปจะขึ้น Dialog หน้านี้ ก็ติ๊กถูกตามที่ Default มีอยู่แล้วอ่ะครับ จะได้ไม่ยุ่งยาก
กด Next > ต่อไปเลยครับ


 3. แล้วจะมาหน้า Auto Generate Icon เราก็ปรับปรุงหน้าตา Icon ของ App เราเสียหน่อยครับ จะได้เป็นเอกลักษณ์ เวลาอยู่ใน App drawer แล้ว จะได้รู้ว่านี่เราเขียนเองนะ
ปรับแต่ง Icon ตามชอบใจได้เลยครับ เสร็จเรียบร้อย กด Next >


 4. จะขึ้น Dialog มาถามเรื่อง Create Activity ใครไม่รู้ว่า Activity คืออะไร ไปอ่านก่อนได้ที่นี่นะครับ http://pilotpol.blogspot.com/2013/05/android-thai-pilot-pray-4.html ส่วนใครชำนาญในการสร้าง Hello Android แล้วก็ไปต่อกันได้เลย
หน้านี้ก็ตาม Default มันเลยครับ เลือก Blank Activity แล้วกด Next >


 5. หน้านี้จะให้ตั้งชื่อ Activity หลักของ App เราครับ พร้อมกับชื่อ Layout หลัก ก็ใส่ตามใจชอบได้เลยครับ แต่ข้อสำคัญคือ ชื่อ Activity Name ขอให้ใส่ตัวใหญ่นำหน้า ส่วนที่ Layout Name ใส่อะไรก็ได้ครับ เพราะเราไม่ได้ใช้อยู่แล้ว
เสร็จแล้วครับ กด Finish ได้เลย


 6. เราก็จะได้ App มาแล้ว 1 App เปล่าๆ ตอนนี้ก็สามารถ Run as ดูผลงานได้แล้วนะครับ แต่ใจเย็นครับ เพราะจุดประสงค์เราคือ จะใช้ AndEngine นั่นเอง


 7. มาถึงพระเอกของเราแล้วครับ ซึ่งอย่างที่บอกไว้ข้างต้นว่า ผมจะแนะนำการใช้งาน AndEngine แบบ Include Library jar มาในตัว Project เลย เพื่อความไม่ยุ่งยากในการอธิบายครับ เริ่มต้นจาก Download Lib ทั้งหลายจาก link นี้ก่อน https://docs.google.com/file/d/0B_raxIdscReBRnFMY05tR1daNms/edit?usp=sharing

จะได้เป็นไฟล์ Zip นะครับ นำไฟล์ Zip ไปวางไว้ใน folder libs ใน Project ครับ แล้วแตกไฟล์ออกที่นั่น (ตอนแตกไฟล์ อาจจะมีซ้ำอันหนึ่งนะครับ เป็น android-support-v4.jar ซึ่ง จะเลือกให้ทับไป หรือไม่ทับก็ได้ครับ)

เสร็จสรรพแล้ว ภายใน folder libs ของ Project เรา ควรจะมีไฟล์หน้าตาประมาณนี้นะครับ
พวกนี้เป็นไฟล์ lib ของ AndEngine ทั้งหมดครับ ซึ่งในตัวอย่างก็ไม่ได้ใช้หมดหรอกครับ ใครจะลบออกให้เหลือเฉพาะที่ใช้ก็ได้นะครับ


 8. ได้ AndEngine กันแล้ว จริงๆ ก็เริ่มเขียน Code กันได้เลย แต่ว่าในตัวอย่างที่จะเขียนให้ดูนี้ ผมจะใช้งานภาษาไทยด้วยครับ ดังนั้นผมก็จะเพิ่มเติมในเรื่อง font หน่อยครับ

เริ่มแรกที่ folder assets ภายใต้ Project ของเรานะครับ (อันนี้ของผมเป็น helloAndEngine) สร้าง folder font ขึ้นมาตามรูปครับ แล้วไปหา font อะไรก็ได้มาวางไว้ครับ นามสกุลเป็น .ttf นะครับ

หรือถ้าจะสนับสนุนของ DroidSans แบบผม ก็ไป Download มาได้เลยครับ ที่นี่ http://www.nuuneoi.com/blog/blog.php?read_id=296 ต้องขอขอบคุณ คุณ NuuNeoI เจ้าของ font มา ณ โอกาสนี้ด้วยครับ (ผมไม่รู้จักเป็นการส่วนตัวกะเขาหรอกนะครับ)
Dowload font มาลงที่ Folder font แล้วก็ยังเหลือ รูปภาพตัวละครของเราครับ ดูข้อต่อไปกันเลย


 9. เรื่องตัวละคร ถ้าใครเคยศึกษาเกี่ยวกับเกมมาบ้างก็จะพอเข้าใจว่า รูปภาพที่เห็นเคลื่อนไหวนั้น สำหรับเกม 2D ก็จะเป็นการสลับรูปวนไปมาเรื่อยๆ นะครับ คล้ายๆ กับภาพ gif นั่นแหละ แต่ในที่นี้เราจะใช้ไฟล์ภาพแบบ package ที่เรียกว่า animation sprite ครับ เป็นภาพใหญ่ๆ ที่มีรูปแบบการเคลื่อนไหวต่างๆ แล้วมาตัดเอาแสดงผลอีกทีในเกม คลิกขวาแล้ว Save as... รูปด้านล่างนี้ได้เลยครับ



สร้าง Folder gfx ภายใต้ assets ตามภาพด้านล่างนี้ครับ จากนั้น Copy ไฟล์ภาพตัวละครด้านบน ไปวางไว้ที่ Folder นั้น โดยตั้งชื่ออะไรก็สุดแล้วแต่ครับ ของผมตั้งเป็น player แต่นามสกุลเป็น png นะครับ
ที่นี่เราก็จะได้หน้าตาของ Project เป็นแบบนี้ครับ ภายใต้ assets มี fonts และ gfx ส่วน libs ก็มี ไฟล์ jar ของ AndEngine อยู่แล้ว



 10. จากนั้นมาดูกันต่อในส่วน Code ครับ จากรูปด้านล่าง ผมแสดงให้เห็นว่า ส่วนประกอบโครงสร้างของการเริ่ม Project ของ AndEngine มีอะไรสำคัญๆ บ้างครับ ตอนนี้เปิดไฟล์ *.java ที่อยู่ภายใต้ src > ชื่อ package ขึ้นมานะครับ อันนี้เป็นไฟล์หลักและในตัวอย่างจะเขียนที่ไฟล์นี้ไฟล์เดียวครับ
ใครที่ตั้งชื่ออื่น ก็จะไม่เหมือนกันนะครับ


11. ใน Code ให้ลบ Activity หลัง extends ออกไปเลยครับ แล้วก็ Code ข้างในด้วย เพราะเราจะเปลี่ยนมาใช้ Code แบบด้านล่างแทน
เราเรียก extends SimpleBaseGameActivity แทนการเรียกใช้ Activity ตามแบบแอพทั่วไปครับ และภายใน Class ก็จะต้องเรียก Method 3 ตัวตามกรอบสีแดงครับ อธิบายได้ดังนี้นะครับ
  1. onCreateEngineOptions() เป็นตัวสร้างสภาพแวดล้อมเริ่มต้นของ AndEngine ให้กับ แอพของเราครับ เดี๋ยว Code ภายในเราจะมาว่ากันอีกที
  2. onCreateResources() เป็นตัวสร้างพวกสิ่งต่างๆ ในตอนเริ่มต้น สำหรับเกมของเราครับ
  3. onCreateScene() ตัวนี้ใช้สร้าง Scene กำหนด Object ต่างๆ ให้กับ scene ที่ใช้แสดงผลออกทางหน้าจอ และทำการ update scene วนรอบไปเรื่อยๆ ภายในนี้เราก็เขียน Code ดักทำโน้นนี้เพื่อใช้ run game เราครับ


จากนี้ไปเป็นตัว Code นะครับ ผมจะทำสีพื้นเป็นสี นี้ ครับ

ในส่วน Attribute สร้างตัวแปรสำหรับ class ดังนี้ครับ

// game engine
private Scene scene;
private static final int CAMERA_WIDTH = 800;
private static final int CAMERA_HEIGHT = 480;
private BoundCamera mBoundChaseCamera;
// resource
private BitmapTextureAtlas mBitmapTextureAtlas;
private TiledTextureRegion mPlayerTextureRegion;
private Font mFont;
// object on scene
private Text hellotxt;
private int countd = 10;

หลักการใน AndEngine นั้นก็คือ เราต้องสร้าง มุมกล้อง และขนาดกว้าง x ยาวของมุมกล้องขึ้นมาก่อนครับ สำหรับขนาดหน้าจอนั้นก็ไม่ต้องกังวลไป เพราะมันจะปรับ ขยาย ใหญ่เล็ก ให้โดยอัตโนมัติ ตามสัดส่วนครับ อย่างเช่น ถ้าหน้าจอมือถือผม 800x480 แต่ผมตั้งค่าไว้ที่ width 320 height 240 ตัว AndEngine ก็จะปรับขยายให้การแสดงผลของแอพ พอดีกับหน้าจอมือถือผมครับ แต่ว่าภาพจะแตก และใหญ่ขึ้นมา ตามมุมมองของขนาด 320x240 ครับ สิ่งที่ต้องให้ความสำคัญก็คือ Ratio หรือ สัดส่วนครับ ถ้าไม่ต้องการให้เห็นขอบดำข้างๆ จอการแสดงผล อธิบายแล้วดูจะเข้าใจยาก ก็ต้องลองทำดูเองเลยครับ โดยการเปลี่ยน CAMERA_WIDTH และ CAMERA_HEIGHT ตามใจชอบ แล้ว rus as ดู เพื่อสังเกตผลลัพธ์ครับ

สร้างตัวแปรกันแล้ว เราก็มาเขียน code ในส่วน onCreateEngineOptions กันครับ ดังนี้

// ตั้งค่ามุมกล้อง
this.mBoundChaseCamera = new BoundCamera(0, 0, CAMERA_WIDTH,CAMERA_HEIGHT);

// ตั้งค่า engine
final EngineOptions engineOptions = new EngineOptions(
true,
ScreenOrientation.LANDSCAPE_FIXED, 
new RatioResolutionPolicy( CAMERA_WIDTH, CAMERA_HEIGHT ), 
this.mBoundChaseCamera);

// ตั้งค่าให้สามารถ multitouch ขณะเล่นเกมได้
engineOptions.getTouchOptions().setNeedsMultiTouch(true);
return engineOptions;

ก็ตรงไปตรงมาครับ เริ่มแรกก็สร้างมุมกล้องขึ้นมาก่อน แล้วก็สร้างตัว Engine ภายใน EngineOptions เราก็สามารถกำหนดได้ว่า จะให้เป็นแนวตั้งหรือแนวนอน ในที่นี้เป็นแบบแนวนอนและ Fixed ไว้เลย
บรรทัดต่อมาก็ตั้งให้สามารถ Touch ได้มากกว่า 1 จุดครับ ตรงนี้สำคัญสำหรับเกมแบบใช้ปุ่มควบคุมเสมือนมากครับ เพราะถ้าไม่ตั้งค่าตรงนี้ เมื่อเรากดบังคับตัวละครค้างไว้ เราจะไม่สามารถกดหน้าจอป้อนคำสั่งใดๆ ได้อีก เพราะตัว engine จะรับค่าเพียง 1 จุดสัมผัสเท่านั้นครับ

แล้วก็ return ค่าออกไปตามที่ method นี้เรียกใช้ เป็นอันจบการสร้าง engine ครับ ที่นี้ก็เหลือ สร้าง Resource เตรียมไว้ แล้วก็เอามันออกมาแสดงครับ

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

onCreateResources() ในนี้ให้เขียน Code ดังนี้ครับ

//player resource
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

mBitmapTextureAtlas = new BitmapTextureAtlas( this.getTextureManager(), 96, 192, TextureOptions.DEFAULT);
mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createTiledFromAsset(
mBitmapTextureAtlas, this,
"player.png", 0, 0, 3, 4);
mBitmapTextureAtlas.load();

//font resource
final ITexture droidFontTexture = new BitmapTextureAtlas(this.getTextureManager(), 256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
FontFactory.setAssetBasePath("font/");
mFont = FontFactory.createFromAsset(this.getFontManager(), droidFontTexture, this.getAssets(), "DroidSans.ttf", 24, true, Color.WHITE );
mFont.load();

ไล่จาก Code ดูเลยนะครับ ส่วน comment แรกเราจะ load ตัวละครก่อนครับ

เริ่มจาก กำหนด path ที่จะ load พวกรูปต่างๆ ให้กับตัว load texture ของ AndEngine ครับ ชื่อยาวๆ ก็คือ BitmapTextureAtlasTextureRegionFactory ครับ
ต่อมาจะต้องทำการสร้างตัว TextureAtlas ขึ้นมาครับ ตัวนี้จะเป็นตัวเก็บรูปภาพเอาไว้ครับ ในที่นี้จะเป็นภาพใหญ่ๆ ก่อนตัด parameter 96,192 คือความกว้างและความสูงของตัวเก็บภาพ ในที่นี้จะสร้างขนาดเท่ากับรูปที่โหลดขึ้นมาครับ ( load 1 ตัวก็ต้องมีตัวเก็บ 1 ตัวนะครับ หรือถ้าจะใช้รูปเดียวกันก็ไม่ต้องโหลดขึ้นมาอีกครับ)

จากนั้นทำการสร้าง TextureRegion (ตัวกำหนดขอบเขตของ texture) แบบ Tiled ขึ้นมาครับ ในนี้จะมี parameter ที่ใส่ชื่อไฟล์ (player.png) และจำนวนรูปแนวกว้างกับจำนวนรูปแนวยาว (3,4 อันหลังสุดครับ) จากนั้นก็ใช้คำสั่ง load(); เข้ามาไว้ในหน่วยความจำของเครื่อง

เตรียมรูปตัวละครเสร็จแล้วครับ ต่อไปมาเตรียมตัวอักษรบ้าง เราจะสร้าง ITexture เพื่อเก็บรูปแบบตัวอักษรเช่นเดียวกับรูปครับ จากนั้น set path ของ FontFactory ให้ไปหาที่ folder asset/font

จากนั้นก็จะไปโหลด font มาเก็บไว้ครับ จะมี parameter ชื่อ font ("DroidSans.ttf") ขนาดตัวอักษรที่จะแสดง (24) และสีของตัวอักษร เป็น int นะครับ (Color.WHITE) แล้วก็ใช้คำสั่ง load() ครับ เท่านี้ก็เรียบร้อย

ตอนนี้ก็จะเหลือส่วนสำคัญที่สุดของเรา นั่นคือ การนำทุกอย่างที่เตรียมไว้แสดงขึ้นหน้าจอครับ ด้วย method onCreateScene() นั่นเอง

ภายในมี Code ดังนี้ครับ

// สร้าง scene ใหม่
scene = new Scene();

// สร้าง text
hellotxt = new Text(10, 10, mFont, 
"สวัสดี แอนเอ็นจิ้น ภาษาไทย!",
"นับเวลาถอยหลังด้วย แอนเอ็นจิ้น = xxxxxxxxxxxxxx".length(),
this.getVertexBufferObjectManager());

// สร้างตัวละคร
final AnimatedSprite player = new AnimatedSprite(
100, 100,
mPlayerTextureRegion, 
this.getVertexBufferObjectManager());

scene.attachChild(player);
scene.attachChild(hellotxt);

// ทำให้ตัวละครเคลื่อนไหว
player.animate( new long[] { 200, 200, 200 }, 6, 8, true);

// ขณะที่ game ทำงานไปเรื่อยๆ
scene.registerUpdateHandler(new TimerHandler(1.0f, true, new ITimerCallback() {
            @Override
            public void onTimePassed(final TimerHandler pTimerHandler) {
            hellotxt.setText("นับเวลาถอยหลังด้วย แอนเอ็นจิ้น = " + countd);
            countd--;    
            if(countd < 0)
            countd=10;
            }         
        }));
return scene;

เริ่มจาก สร้าง Scene ใหม่ขึ้นมาก่อนเลยครับ

ถัดมาเตรียม text เพื่อแสดงข้อความบนหน้าจอ 10,10 คือ ตำแหน่ง x,y ที่จะแสดงใน scene ถัดไปเป็นข้อความเริ่มต้น ถัดไปเป็นความยาวตัวอักษรของข้อความ ตรงนี้สำคัญมากนะครับ ถ้าความยาวตัวอักษรที่เราจะแสดง เกินจากความยาวที่ตั้งค่าไว้ตรงนี้แล้ว มันจะ error และ บังคับปิดครับ (อันนี้สำหรับข้อความแบบ Static นะครับ เหมือนกับ Textview ของ Native android) ที่เห็นเขียนแบบนั้น (ข้อความแล้วตามด้วย.length() ) ในส่วนตั้งค่าความยาว คือ เราก็กำหนดรูปแบบไปเลย มันจะได้ง่ายว่า เกินหรือไม่เกิน แทนที่จะไปนั่งนับทีละตัวอักษรเอาน่ะครับ

จากนั้นก็นำตัวละครมาเตรียม ด้วย AnimatedSprite ตั้งชื่อว่า player ค่าที่เห็น 100,100 นั่นคือ ค่าตำแหน่ง x กับ y ใน scene ครับ ตัวรูปเราก็เอามาจาก TextureRegion ที่สร้างไว้แล้วน่ะครับ

แล้วก็เพิ่มพวกที่สร้างลงไปใน scene ครับ ด้วย attachChild 

ถ้าเราจบตรงนี้ก็ run ได้แล้วครับ แต่ทุกอย่างก็จะนิ่งๆ เพราะฉะนั้น เรามาเพิ่มการเคลื่อนไหวสักเล็กน้อยครับ

กำหนดให้ตัวละครเคลื่อนไหวด้วย animate จะมี parameter ดังนี้ครับ ค่า 3 ตัวแรก new long[] { 200,200,200 } คือความเร็วในการเปลี่ยนภาพจาก เฟรมหนึ่งไปเฟรมหนึ่งครับ อันนี้ต้องไปสัมพันธ์กับตอน load รูปนะครับ ว่า TextureRegion ที่เราสร้างนั้น มีภาพในแนวแนวนอน (หรือภาพการเคลื่อนไหวนั่นเอง) กี่ภาพ สำหรับตัวอย่างนี้มี 3 ภาพครับ ถัดไปจะเป็นลำดับของภาพครับ ให้นับจากซ้ายบนสุดคือ 0 ไล่มาทางขวา ถ้าหมดก็นับใหม่ เพราะฉะนั้นตามข้างต้น ผมให้แสดงภาพที่หันหน้าออกครับ ดังรูป

จากนั้นเราจะใช้ คำสั่ง registerUpdateHandler ของ scene เรียก TimerHandler ขึ้นมา จริงๆ แล้ว registerUpdateHandler นั้น มีอีกหลาย Handler ที่เรียกใช้ได้ครับ เช่น อัพเดตแบบตาม frame rate ก็มี แต่ในตอนนี้ เราจะใช้การวนรอบแบบตามเวลาที่ตั้งไว้ก่อน (ให้คิดเสียว่า การอัพเดต scene ก็คือการเปลี่ยนแปลงหน้าจอครั้งหนึ่งนะครับ)

สำหรับ การ Update แบบ Timer ก็จะมี parameter สำคัญดังนี้ครับ 1.0f คือเวลาที่นับในการวนรอบแล้วทำตามคำสั่งครับ ในที่นี้คือ 1 วินาที ถ้าต้องการครึ่งวินาที ก็ 0.5f แบบนี้นะครับ

Method onTimePassed จะทำงานเมื่อเวลาครบตามที่กำหนดครับ ภายในที่เขียนไว้ก็ไม่มีอะไรมากครับ ก็ให้ setText โดยเอาค่า countd มาแสดง วนไปเรื่อยๆ ครับ

ทีนี้เราก็จะได้การนับถอยหลัง ทุกๆ วินาทีล่ะครับ

เสร็จเรียบร้อยแล้วครับ ที่นี้เราก็ Run As ได้เลยครับ จะได้เห็นตามรูปด้านล่างนี้นะครับ (ตัวละครจะหันหน้ามาแล้วกระดุกกระดิกนะครับ)




ใช้เวลาเขียนบทความนี้ 4 ชั่วโมงกว่าเลยทีเดียว...เหนื่อยเอาเรื่องแฮะ

พบกันบทความหน้าครับ ถ้าไม่ขี้เกียจเสียก่อน เราจะมาสร้าง controller ควบคุมตัวละคร พร้อมกับปุ่ม action สัก 2 ปุ่ม เพื่อให้ตัวละครทำโน้นนี่นั่นกันครับ

มีปัญหาคาใจ ฝากคำถามไว้ได้เลยนะครับ อาจจะตอบช้าหน่อย แต่จะเข้ามาดูเรื่อยๆ จนกว่าจะลงบทความใหม่ครับ

ป.ล. บทความนี้ไม่ลงไฟล์ Source Code นะครับ จะได้ลองใส่ Code ดูเอง หากเกิด Error จะได้รู้ว่าเป็นที่จุดไหนครับ

วันพุธที่ 29 พฤษภาคม พ.ศ. 2556

พัฒนาเกม RPG บน android ด้วย AndEngine (1)




เกมส์ Classic RPG เป็นเกมส์ที่ผมใฝ่ฝันจะทำตั้งแต่ 20 ปีก่อน ตอนเริ่มหัดภาษา C++ ใหม่ๆ 
ทุกวันนี้ยังไม่เป็นชิ้นเป็นอันอะไรเลย พอดีมาสู่ยุค Smart Phone ก็รื้อความฝันเดิมมาทำเสียหน่อย

วันนี้จะมาแนะนำการพัฒนาเกมส์แบบ Classic RPG บน android กันครับ (ผมเรียกว่า classic เพราะเป็นแบบ 2d มุมมองด้านบนที่ไม่ใช่ iso น่ะครับ) ซึ่งโดยทั่วไปแล้ว เราสามารถใช้ library ของ Android SDK ที่มีมาให้ก็ได้เหมือนกัน แต่มันใช้เวลานาน และขั้นตอนยุ่งยากครับ

ก็เลยเป็นจุดเริ่มต้นของการหา Game Engine มาช่วยให้ขั้นตอนต่างๆ ลดลง พัฒนาแอพที่ต้องใช้ความสามารถของ Graphic , OpenGL ได้ง่ายขึ้น ที่ผมหาๆ อยู่ก็มีหลายตัวครับ และมุ่งเน้นไปที่การใช้งานแบบ Open Source เป็นหลักครับ

มีคนรวบรวม Library ของ OpenGL และพัฒนามันขึ้นเป็น Game Engine อยู่หลายเจ้าครับ ต้องขอบคุณคนเหล่านั้นจริงๆ เพราะถ้าไม่มีคนที่อุทิศตัวทำเรื่องแบบนี้แล้ว ความรู้ในโลกจะคืบหน้าได้ช้าจริงๆ ครับ เพราะฉะนั้น ถ้าพัฒนา Software ด้วย Open Source อะไรก็แล้วแต่ มีเงินก็น่าจะบริจาคกลับให้ผู้พัฒนาตามกำลังศรัทธาก็ดีนะครับ

กลับมาที่ Game Engine ที่ผมหามาจะมีอยู่ 2 ประเภท เพื่อสร้างเกมครับ

  • แบบ 2D ผมจะใช้ของ AndEngine ของคุณ Nicolas Gramlich 
  • แบบ 3D ผมจะใช้ของ JPCT ของคุณ Helge Foerster 

ซึ่งในบทความนี้จะพูดคุยเกี่ยวกับ AndEngine กันนะครับ

ที่อยู่ก่อนเลยครับ http://www.andengine.org/

และแน่นอน การเขียนบทความ Tutorial ของผม จะเขียนแบบ Open Workshop คือ พัฒนา Project ตามใจผู้เรียนรู้ ภายในกรอบของตัวอย่างงาน และนี่คือโจทย์ตัวอย่างงานของบทความชุดนี้ครับ





ปุ่มควบคุมเดิมๆ ครับ Control Direction ด้านขวา และ ปุ่มอีก 2 ปุ่มด้านซ้าย (จะเปลี่ยนจะเพิ่มเดี๋ยวบอกรายละเอียดใน Open Workshop ครับ)

ไป Download มา Run กันก่อนได้เลยครับ อันนี้เป็น Project ผมที่อยู่บน GitHub โดย Project นี้ก็จะเป็นการผสม ยำ รวมมิตร tutorial ของหลายๆ ที่ออกมาเป็น project ให้ได้เห็นแนวทางกันครับ

สิ่งที่ต้องมีในการพัฒนานะครับ
  1. Tiled Map Editor ครับ ไป Download กันมาได้เลย http://www.mapeditor.org/ อันนี้จำเป็นมากนะครับ เพื่อต่อยอดงาน RPG ในอนาคต มีหลายส่วนต้องอธิบายเช่นกัน
  2. Eclipse & Android SDK อันนี้คงมีอยู่แล้วใช่มั้ยครับ ถ้าไม่มีก็ download bundle SDK ได้เลยครับ ที่นี่ครับ http://developer.android.com/sdk/index.html
  3. AndEngine ครับ จริงๆ ใน Project จะมีให้อยู่แล้วอ่ะครับ แต่ถ้าใครอยากโหลดตัว Source เลย เพื่อมา modify (Project RPG อันนี้ของผม ก็มีการ Modify source นิดหน่อยเพื่อการใช้งานนะครับ เพราะฉะนั้น ถ้าท่านโหลด source มา lib จะเป็นคนละตัวแล้วครับ เพราะผมเอามา build ใหม่ครับ) ที่นี่ครับ https://github.com/nicolasgramlich/AndEngine
เมื่อโหลดมาแล้ว สิ่งที่ต้องเตรียมต่อไป เพื่อการทำ Open Workshop ในครั้งนี้นะครับ
  1. สร้าง Android Project เปล่าๆ ใหม่ 1 Project ครับ ใครสร้างไม่เป็นทางนี้ครับ http://pilotpol.blogspot.com/2013/05/android-thai-pilot-pray-3.html
  2. สร้าง Project ของ ตัวอย่างงาน RPG จากที่ download ไป Project ชื่อ testgame นะครับ สร้างได้ตามนี้ครับ http://pilotpol.blogspot.com/2013/05/android-thai-pilot-pray-5.html เปลี่ยนชื่อ project และตำแหน่งไฟล์เอา
ก็เท่านี้ก่อนครับ บทความหน้าจะมาเริ่ม Open Workshop กันล่ะ