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

วันศุกร์ที่ 15 ธันวาคม พ.ศ. 2560

แก้สมการคณิตศาสตร์ ด้วย construct 2

มีคำถามที่น่าสนใจมากเกี่ยวกับการทำแบบทดสอบในการเขียนประโยคสัญลักษณ์ทางคณิตศาสตร์ แล้วให้โปรแกรม construct2 แยกลำดับการคำนวณออกมา หลักการทำงานในลักษณะนี้ จะต้องพิจารณาความสำคัญของตัวดำเนินการทางคณิตศาสตร์ คือ ลำดับความสำคัญ เช่น () มีความสำคัญมากกว่า * หรือ / และ + หรือ - ตามลำดับ


ลักษณะหน้าจอของโปรแกรม คือ มีช่องสำหรับกรอกสมการ มีปุ่มสำหรับกด เมื่อต้องการคำนวณคำตอบ และช่องสำหรับแสดงวิธีหาคำตอบ เป็นดังนี้ครับ (สามารถ download ไฟล์โปรแกรมได้จาก link นี้)

กำหนดชื่อของ Textbox ตามตัวอักษรสีแดง

เพิ่ม Array จำนวน 3 ตัว ดังนี้ str_arr , digit_arr และ operator_arr

กำหนดคำสั่งในการประมวลผล โดยกำหนดค่าตัวแปรที่ใช้ในโปรแกรม construct2 ก่อน ดังภาพ


eq_str  เก็บข้อความสมการ
eq_txt1  เก็บตัวเลขตัวที่ 1
eq_txt2  เก็บตัวเลขตัวที่ 2
eq_txt3  เก็บตัวเลขตัวที่ 3
operator1 เก็บเครื่องหมายตัวดำเนินการที่ 1
operator2 เก็บเครื่องหมายตัวดำเนินการที่ 2
cstr  เก็บตัวอักษรในสมการ
arr_len เก็บความยาวของ array สมการ
bracket_ind เก็บตำแหน่งของ (

สร้าง Array สำหรับรายการตัวเลข และเครื่องหมาย สำหรับใช้เทียบกับสมการ ชื่อ digit_arr  และ operator_arr



ผมขออธิบายลักษณะสมการที่จะเป็นไปได้สำหรับโปรแกรมที่สร้างขึ้น มีอยู่ 3 ลักษณะ คือ
1. สมการที่เขียนต่อเนื่อง ไม่มีวงเล็บ  เช่น 150+40-30  สมการลักษณะนี้ จะอาศัยการพิจารณาลำดับความสำคัญของเครื่องหมายตัวดำเนินการทางคณิตศาสตร์
2. สมการที่มีวงเล็บเป็นกลุ่มแรก เช่น (150+40)-30  สมการลักษณะนี้ จะทำการคำนวณในวงเล็บเพื่อให้ได้คำตอบก่อนแล้วค่อยนำคำตอบมาคำนวณกับเลขตัวที่ 3
3. สมการที่มีวงเล็บเป็นกลุ่มหลัง เช่น 150+(40-30) สมการลักษณะนี้จะคำนวณกลุ่มหลังก่อน แล้วค่อยเอาคำตอบมาคำนวณกับเลขตัวที่ 1


หลังจากนั้น สร้างเหตุการณ์ เมื่อมีการกดปุ่ม Calculate เพื่อแสดงการคำนวณสมการที่พิมพ์ไว้แล้ว



1. อ่านค่าสมการจาก eq_txt ซึ่งเป็น textbox ที่เราพิมพ์สมการ มาเก็บไว้ที่ตัวแปร eq_str
2. กำหนดขนาดของ Array ชื่อ str_arr ให้เท่ากับความยาวของสมการ
3. เปลี่ยนข้อความสมการ ให้เป็นรูปแบบ Array เก็บไว้ที่ str_arr



โดยจะไม่เก็บค่าช่องว่างในสมการ และเครื่องหมาย () เข้าไปใน Array และเก็บตำแหน่งที่เจอ ( ด้วย เพื่อใช้เทียบลักษณะของสมการ ถ้าไม่เจอ ( ตำแหน่งของ ( จะมีค่าเป็น -1
เก็บความยาวของ array ไว้ที่ตัวแปร arr_len

4. แยกสมการไปเก็บไว้ที่ตัวแปรสำหรับเก็บค่าตัวเลขและเครื่องหมาย



บรรทัดที่ 7 จะวนซ้ำเรื่อยๆ ถ้าค่าใน array str_arr เป็นตัวเลข 0-9 โดยเทียบกับ digit_arr แล้วเก็บเลขแต่ละตัวไว้ที่ nstr แต่ถ้าไม่ใช่ตัวเลข ให้หยุดการวนซ้ำ
บรรทัดที่ 11 จะเก็บค่าเครื่องหมายทางคณิตศาสตร์ตัวที่ 1 ที่อยู่ถัดจากตัวเลขตัวที่ 1

ดำเนินการเช่นเดียวกันสำหรับการเก็บค่าตัวเลขตัวที่ 2 และ 3



5. สร้างฟังก์ชัน สำหรับหาค่าลำดับความสำคัญของเครื่องหมาย ดังนี้



โดย * และ /  จะมีความสำคัญมากกว่า + และ -

6. สร้างฟังก์ชันสำหรับใช้คำนวณคำตอบ โดยการส่งค่าเครื่องหมายและตัวเลขมาให้ฟังก์ชัน ชื่อ Calc



7. เปรียบเทียบตำแหน่งของวงเล็บ เพื่อหารูปแบบสมการ
ถ้าตำแหน่งวงเล็บ เท่ากับ -1 แสดงว่าไม่มีวงเล็บในสมการ ต้องคำนวณจากลำดับความสำคัญ



การเรียกใช้ function ในโปรแกรม construct2 จะใช้คำสั่ง Call ชื่อฟังก์ชัน (ค่าพารามิเตอร์)
จากบรรทัดที่ 22 จะเป็นการเรียกฟังก์ชัน priority แล้วส่งค่าเครื่องหมายไปให้ ฟังก์ชันจะคืนค่าลำดับความสำคัญมาเก็บไว้ที่ตัวแปร priority1 และ priority2



บรรทัดที่ 23 เปรียบเทียบถ้า priority2 มากกว่า priority1 ให้คำนวณจากกลุ่มด้านหลังก่อน จึงกำหนดค่าในช่อง Textbox ให้เอาตัวเลขที่ 2 และ 3 มาคำนวณ แล้วจึงไปคำนวณกับตัวเลขที่ 1 โดยการเรียกฟังก์ชัน Calc โดยส่งค่า operator และค่าตัวเลขจาก  operand_1.text และ operand_2.txt นำคำตอบที่ได้ไปเก็บไว้ที่ textbox ชื่อ answer_1 และ operand_4 แล้วเรียกฟังก์ชัน Calc เพื่อคำนวณอีกครั้ง



บรรทัดที่ 24 เปรียบเทียบถ้า priority1 น้อยกว่าหรือเท่ากับ priority2 ให้คำนวณจากซ้ายไปขวา จึงกำหนดค่าในช่อง Textbox ให้เอาตัวเลขที่ 1 และ 2 มาคำนวณ แล้วจึงไปคำนวณกับตัวเลขที่ 3 โดยการเรียกฟังก์ชัน Calc โดยส่งค่า operator และค่าตัวเลขจาก  operand_1.text และ operand_2.txt นำคำตอบที่ได้ไปเก็บไว้ที่ textbox ชื่อ answer_1 และ operand_3 แล้วเรียกฟังก์ชัน Calc เพื่อคำนวณอีกครั้ง

ถ้าตำแหน่งวงเล็บ อยู่ตำแหน่งแรก ให้คำนวณค่าตามลำดับจากซ้ายไปขวา



ถ้าตำแหน่งวงเล็บ อยู่ในกลุ่มหลัง ให้คำนวณค่าในวงเล็บหลังก่อน ค่อยนำค่าตัวเลขที่ 1 ไปคำนวณกับคำตอบที่ได้




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

สมการ 150 - 8 * 5



สมการ (150 - 8) * 5



สมการ 150 - (8 * 5)



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



วันอังคารที่ 21 มิถุนายน พ.ศ. 2559

construct 2 : local storage

บันทึกข้อมูลด้วย local storage

local storage เป็นส่วนเสริม ที่ช่วยให้โปรแกมบันทึกข้อมูลลงในอุปกรณ์ของผู้เล่นได้ เช่น เก็บคะแนนสูงสุดของผู้เล่น เก็บระดับการเล่น เป็นต้น การเก็บข้อมูลของ local storage จะเป็นลักษณะของการทำงานออฟไลน์ การจัดเก็บจะแยกเป็นอิสระของอุปกรณ์แต่ละตัว  และการเปิดใช้งานโปรแกรมจาก Browser ที่ต่างกัน ก็จะจัดเก็บข้อมูลที่แตกต่างกันด้วย ข้อมูลที่จัดเก็บไม่สามารถใช้งานร่วมกันได้ แม้ว่าจะอยู่บนคอมพิวเตอร์เครื่องเดียวกันก็ตาม ข้อมูลจะคงอยู่จนกระทั่งผู้ใช้ทำการล้างข้อมูล และการจัดเก็บข้อมูลจะแยกย่อยให้มีความจำเพาะเจาะจงกับโปรแกรมแต่ละโปรแกรมที่ทำงาน เช่น game1 และ game2 มีการบันทึกข้อมูลลง local storage บนเครื่องคอมพิวเตอร์เดียวกัน แต่ทั้ง game1 และ game2 จะไม่สามารถใช้งานข้อมูลร่วมกันได้ ซึ่งเป็นการรักษาความปลอดภัยของข้อมูลในระดับหนึ่งด้วย

รูปแบบการบันทึก local storage

การบันทึกข้อมูลใน local storage จะมีรูปแบบคล้ายกับการบันทึกข้อมูลลงในตาราง ที่มีสองคอลัมน์ คือ Key และ Value

ค่าในคอลัมน์ Key  เป็นค่าที่ใช้จำแนกความแตกต่างของข้อมูลที่บันทึกไว้ใน local storage ที่สำคัญค่าที่กำหนดให้เป็น key จะต้องไม่ซ้ำกัน เป็นค่าที่มีความจำเพาะ  เช่น HighScore Level เป็นต้น ค่าเหล่านี้จะใช้ในการอ้างอิงถึงข้อมูลที่เก็บอยู่ภายใน

ค่าในคอลัมน์ Value  เป็นค่าข้อมูลที่สัมพันธ์กับ key จะเป็นตัวเลข ข้อความ หรือค่าใน array ก็ได้ ทำให้สามารถจัดเก็บข้อมูลขนาดใหญ่ ลงใน key เพียงตัวเดียวได้

Local Storage is asynchronous.

การอ่านและบันทึกข้อมูลงใน local storage จะเป็นการทำงานแบบไม่ต่อเนื่อง คือ ไม่ได้ทำงานจนเสร็จแบบทันที เมื่อมีคำสั่งในการอ่านหรือเขียนข้อมูลลงใน local storage โปรแกรมจะไม่หยุดรอให้การอ่านหรือเขียนเสร็จก่อน  แต่จะทำงานอื่นต่อไป  ทำให้ลดปัญหาการรอ ที่เกิดจากความล้าช้าของการอ่านข้อมูล โปรแกรมจึงมีประสิทธิภาพในการทำงานอย่างเต็มที่ การอ่านและเขียนข้อมูลใน local storage จะมีทริกเกอร์ ที่คอยตรวจสอบสถานะของการอ่านและเขียนข้อมูล ซึ่งผู้พัฒนาโปรแกรมจะใช้คำสั่งควบคุมการใช้ข้อมูลผ่านทริกเกอร์เหล่านี้

ยกตัวอย่าง การอ่านข้อมูล score จาก local storage จะมีขั้นตอนดังนี้
1. ใช้คำสั่ง action Get เพื่อขออ่านจาก key "score"
2. สร้างเหตุการณ์ on item "score" get
3. สร้างคำสั่งเพื่อรับค่า จาก ItemValue


Local Storage conditions

On any item get  จะทำงานเหตุการณ์นี้ เมื่อการอ่านข้อมูลทั้งหมดเสร็จสิ้น

On any item removed  จะทำงานเหตุการณ์นี้ หลังจากที่ลบข้อมูลเสร็จสิ้น

On any item set  จะทำงานเหตุการณ์นี้ หลังจากที่บันทึกข้อมูลเสร็จสิ้น

On item exists  จะทำงานเหตุการณ์นี้ หลังจากการตรวจสอบค่า key ที่เก็บใน local storage เสร็จสิ้น ถ้าไม่พบ key ที่ค้นหา จะไม่มีการทำงานใดๆ แต่ถ้าพบ key ต้องใช้คำสั่ง Get เพื่ออ่านข้อมูลมาเก็บที่ItemValue

On item get  จะทำงานเหตุการณ์นี้ หลังจากที่อ่านข้อมูลจาก key ที่กำหนดสำเร็จ ข้อมูลของ key จะถูกมาเก็บที่ ItemValue

On item missing  จะทำงานเหตุการณ์นี้ หลังจากการตรวจสอบค่า key ที่เก็บใน local storage เสร็จสิ้น แล้วไม่พบ key ที่ค้นหา

On item removed  จะทำงานเหตุการณ์นี้ หลังจากลบค่า key ที่เก็บใน local storage เสร็จสิ้น

On item set  จะทำงานเหตุการณ์นี้ หลังจากที่บันทึกข้อมูลสำหรับ key ที่กำหนดสำเร็จ ข้อมูลใหม่จะถูกบันทึกลงหน่วยความจำ

Compare key  ใช้สำหรับเปรียบเทียบค่าที่เก็บไว้ใน Key กับค่า key ปัจจุบัน

Compare value  ใช้สำหรับเปรียบเทียบค่าปัจจุบันของ ItemValue ที่ได้จากการอ่านค่าข้อมูล

On all key names loaded  จะทำงานเหตุการณ์นี้ หลังจากที่อ่านข้อมูลจาก key ที่กำหนดสำเร็จ โดยจะได้ชื่อ key ในรูปแบบของแถวลำดับ อ้างอิงด้วย KeyCount และ KeyAt

On error จะทำงานเหตุการณ์นี้ เมื่อเกิดข้อผิดพลาดในการใช้ local storage เช่น เขียนข้อมูลไม่สำเร็จ หรือ พื้นที่ในการจัดเก็บข้อมูลเต็ม โดยข้อผิดพลาดจะถูกเก็บไว้ที่ ErrorMessage

On storage cleared  จะทำงานเหตุการณ์นี้ หลังจากที่ล้างข้อมูลในหน่วยความจำ และหน่วยความจำว่าง

Is processing gets  คืนค่าสถานะของการอ่านข้อมูลเป็น True  เมื่ออยู่ในระหว่างการอ่านข้อมูล

Is processing sets  คืนค่าสถานะของการบันทึกข้อมูลเป็น True  เมื่ออยู่ในระหว่างการบันทึกข้อมูล

On all gets complete  จะทำงานเหตุการณ์นี้ เมื่อการอ่านข้อมูลทั้งหมดเสร็จสิ้น เช่น มีการอ่านข้อมูล 10 ตัว ที่เกิดขึ้นในขณะเดียวกัน เหตุการณ์นี้จะทำงาน เมื่อการอ่านข้อมูลทั้ง 10 ตัว เสร็จสิ้น

On all sets complete  จะทำงานเหตุการณ์นี้ เมื่อการบันทึกข้อมูลทั้งหมดเสร็จสิ้น เช่น มีการบันทึกข้อมูล 10 ตัว ที่เกิดขึ้นในขณะเดียวกัน เหตุการณ์นี้จะทำงาน เมื่อการบันทึกข้อมูลทั้ง 10 ตัว เสร็จสิ้น


Local Storage actions

Check item exists เป็นคำสั่งสำหรับตรวจสอบ Key ที่ถูกเก็บอยู่ใน local storage ถ้าพบ key ที่ต้องการ จะตอบสนองต่อเหตุการณ์ On item exists  แต่ถ้าไม่พบ จะตอบสนองกับเหตุการณ์ On item missing

Get item  เป็นคำสั่งอ่านค่าข้อมูลของ key จากหน่วยความจำ จะตอบสนองกับเหตุการณ์ On item get และค่าที่ได้จะถูกเก็บไว้ที่ ItemValue

Remove item  เป็นคำสั่งในการลบ key ออกจากหน่วยความจำ จะตอบสนองกับเหตุการณ์ On item removed

Set item เป็นคำสั่งบันทึกข้อมูลลงใน local storage จะตอบสนองกับเหตุการณ์ On item set

Clear storage  เป็นคำสั่งล้างข้อมูลจาก local storage ให้เป็นค่าว่าง จะตอบสนองกับเหตุการณ์ On storage cleared

Get all key names  เป็นคำสั่งอ่านค่า key ทั้งหมดที่เก็บใน local storage โดยจะทำงานกับเหตุการณ์ On all key names loaded ผลการทำงานจะได้แถวลำดับของชื่อ key และอ้างถึงด้วย KeyCount และ KeyAt


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




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

Random ค่าใน array ไม่ให้ซ้ำกัน


มีเพื่อนๆ น้องๆ หลายคนมาก สอบถามเรื่องของการอ่านค่าที่เก็บไว้ใน array ของโปรแกรม construct 2 ออกมาใช้งาน หรือมาแสดง ให้เปลี่ยนลำดับไปทุกครั้งที่ทำงาน แรกๆ ก็พอตอบคำถามได้ แต่หลังๆ มา เริ่มมีมากขึ้น ผมก็งานเยอะ ไม่ค่อยได้ตอบ วันนี้เลยพักงานตัวเอง มาเขียนเนื้อหาเกี่ยวกับ array เอาไว้ ให้ได้อ่านศึกษากันก่อน
การสุ่ม (Random) ตำแหน่งที่จะแสดงค่าใน array นั้น มีการนำไปใช้ประโยชน์อย่างกว้างขวาง ในการสร้างเกม การเปลี่ยนตำแหน่ง Sprite หรือประยุกต์ใช้กับการสร้างสื่อการสอน การทำแบบทดสอบที่มีการสลับตัวเลือก
ผมไม่กล่าวถึงการสร้าง array นะครับ ถ้ายังไม่เข้าใจ อ่านเพิ่มเติมตรงนี้ก่อน (construct 2 : array)

ในบทความนี้ ผมมี array ชื่อ myArray ที่เก็บชื่อผลไม้ 5 ชนิด ดังนี้



หลักการสุ่มค่าใน array แบบไม่ให้ซ้ำ มีหลักการง่ายๆ คือ ถ้าสุ่มได้แล้วลบทิ้ง จึงไม่มีโอกาสจะสุ่มได้ค่าเดิมอีกครั้ง
ขั้นตอนการทำงาน
1. ทำซ้ำตามจำนวนรอบที่ต้องการ แต่ต้องไม่เกินขนาดของ array ที่มี
2.  สุ่มค่าตำแหน่ง array  ระหว่าง 0 ถึง ขนาดของ array เก็บที่ตัวแปร pos_x
3.  แสดงค่าหรือนำค่าที่เก็บใน array ที่ตำแหน่ง pos_x ไปใช้งาน
4.  ลบค่าจาก array ในตำแหน่ง pos_x

ตัวอย่างคำสั่งใน event sheet



ผลการทำงาน จะได้ ชื่อผลไม้ที่แสดงสลับตำแหน่ง ไม่ซ้ำกัน



จากเนื้อหาที่กล่าวไปข้างต้น สามารถนำไปประยุกต์ให้เข้ากับงานที่ต้องการได้ เช่น สลับตำแหน่งของ sprite ที่สร้างขึ้น โดยการเก็บตำแหน่งไว้ใน array ก่อน แล้วสุ่มตำแหน่งที่จะ create object จาก array มาใช้ในขั้นตอนการ create object เป็นต้น  ขอให้สนุกกับการใช้งาน array นะครับ

วันอังคารที่ 23 กุมภาพันธ์ พ.ศ. 2559

construct 2 : Random ไม่ซ้ำ


บทความนี้จะขอนำเสนอวิธีการสุ่มตัวเลข หรือ random แบบไม่ให้ตัวเลขที่ได้ซ้ำกัน โดยอาศัยคุณสมบัติของ array ซึ่งวิธีการนี้รับรองผลได้ 100% ว่าข้อมูลที่ได้ไม่มีทางที่จะซ้ำกันอย่างแน่นอน
กรณีตัวอย่างของปัญหา สมมุติว่า ต้องการสุ่มตัวเลขตั้งแต่ 1 - 100 ที่ไม่ซ้ำกัน จำนวน 10 ตัวเลข
วิธีการ 
1. สร้าง array แบบ 1 มิติ ที่มีขนาด width = 10 เพื่อให้เก็บข้อมูลที่ได้จากการสุ่ม
2. วนซ้ำจำนวน 10 รอบ
2.1 สุ่มตัวเลขมา 1 ตัวเลข ตรวจสอบว่า ตัวเลขที่สุ่มได้ อยู่ใน array หรือไม่
2.2  ถ้าตัวเลขอยู่ใน array แล้ว ย้อนกลับไปทำข้อ 2.1
2.3 ถ้าตัวเลข ไม่อยู่ใน array ให้เพิ่มตัวเลขลงใน array แล้ววนซ้ำรอบต่อไป
3. เมื่อครบ 10 รอบ แล้ว ข้อมูลตัวเลขที่อยู่ใน array  คือ ตัวเลขที่สุ่มได้ โดยไม่ซ้ำกัน

ลงมือสร้างโปรแกรม
เปิดโปรแกรม construct 2 ขึ้นมา สร้าง Project ใหม่
เพิ่มวัตถุ array เข้ามาในโปรแกรม ตั้งชื่อว่า rand_arr กำหนดค่า width = 10



เพิ่มตัวแปร Global  ชื่อ rand_num เพื่อใช้เก็บค่าตัวเลขที่ได้จากการสุ่ม
เพิ่มเหตุการณ์เพื่อให้เกิดการ random ข้อมูล ผมกำหนดให้สุ่มข้อมูลเมื่อมีการใช้งาน layout
Add event --> System --> On start of Layout
Add action --> array rand_arr --> Clear (ลบข้อมูลใน array)
Add sub event --> System --> repeat 10 time
เพิ่มการสุ่มข้อมูลมาเก็บไว้ที่ตัวแปร rand_num โดย Add action --> System --> Set value เลือกตัวแปร rand_num และกำหนดค่าเป็น floor(rand(1,100)) คือ สุ่มค่าตัวเลขจำนวนเต็ม 1- 100



เพิ่มการตรวจสอบ ให้วนสุ่มค่าตัวเลขไปเรื่อยๆ ถ้าตัวเลขที่สุ่มได้ เป็นค่าที่ซ้ำใน array
Add sub event --> System --> while
Add another condition --> array rand_arr --> contains value --> rand_num
Add action --> System --> Set value เลือกตัวแปร rand_num
โปรแกรมจะทำการสุ่มตัวเลขใหม่เรื่อยๆ จนไม่ซ้ำกับตัวเลขที่อยู่ใน array ก็จะหลุดออกมาจาก การวนซ้ำ while

ถ้าตัวเลขที่สุ่มได้ ไม่ซ้ำ กับข้อมูลใน array ให้เพิ่มข้อมูลลงใน array
Add blank sub-event
Add action --> array rand_arr --> set at x --> กำหนด x = loopindex และ value = rand_num

คำสั่งทั้งหมด เป็นดังนี้



เมื่อทดสอบการทำงานใน debug mode จะพบว่า ค่าที่ได้จากการ random ตัวเลขจำนวน 10 ตัว จะไม่ซ้ำกันเลย


จากหลักการที่ใช้ สามารถนำไปประยุกต์กับการสร้างเกมได้หลากหลายมากนะครับ เกมนอกจากจะต้องมีภาพสวยแล้ว algorithm ทีดี ก็ทำให้เกมสนุกและฉลาดมากยิ่งขึ้นครับ ขอให้สนุกกับการสร้างเกม

วันศุกร์ที่ 19 กุมภาพันธ์ พ.ศ. 2559

construct 2 : Mysql to array

บทความนี้ ผมจะขอนำเสนอการอ่านข้อมูลจากฐานข้อมูล mysql มาเก็บไว้ที่ตัวแปรแบบ  array เพื่อนำไปใช้ประโยชน์ในการทำงานของเกมต่อไป  โดยเฉพาะการอ่านข้อมูลของผู้เล่นที่มีการบันทึกเอาไว้ในฐานข้อมูล  เมื่อมีการเข้าเล่นเกม โดยปกติจะต้องอ่านข้อมูลของผู้เล่นขึ้นมา เพื่อบอกว่าผู้เล่นมีชื่อว่าอะไร เล่นผ่านด่านอะไรแล้ว ได้คะแนนเท่าไรในแต่ละด่าน หรือการเก็บทักษะในการเล่นต่าง ๆ
การเชื่อมต่อกับฐานข้อมูล mysql ผมได้นำเสนอไว้ที่บทความ การเชื่อมต่อฐานข้อมูล  สามารถย้อนไปศึกษาเพิ่มเติมได้ ผมจะไม่ขอกล่าวย้อนอีกครั้งนะครับ ในบทความนี้ขอสมมุติว่า เข้าใจเรื่องการเชื่อมต่อฐานข้อมูลแล้ว และการอ่านฐานข้อมูลด้วย AJAX แล้วนะครับ  ฐานข้อมูลที่ผมจะใช้ในการนำเสนอวันนี้ คือ ตารางคะแนนเกม ชื่อ game สร้างตารางข้อมูล และใส่ข้อมูลเบื้องต้นไว้เล็กน้อยนะครับ มีรายละเอียดตาราง ดังนี้



สร้างไฟล์สำหรับอ่านข้อมูลจากฐานข้อมูล mysql เป็นไฟล์ชื่อ getuser.php ด้วยคำสั่ง ดังนี้
header('Access-Control-Allow-Origin: *');
header("Content-Type: text/html; charset=UTF-8");

$host = "localhost"; //database location
$user = "root"; //database username
$pass = "mypassword"; //database password
$db_name = "mydatabase"; //database name

//database connection
$link = mysql_connect($host, $user, $pass);
mysql_select_db($db_name);

// Retrieve data from database
$sql="SELECT gID,userID, level, score FROM game";
$result=mysql_query($sql);
while($rows=mysql_fetch_array($result)){
echo $rows['gID'] . "|" .$rows['userID'] . "|" . $rows['level']."|" . $rows['score']. ",";
}
mysql_close();
?>

อย่าลืมเปลี่ยนชื่อฐานข้อมูล ชื่อผู้ใช้และรหัสผ่าน เป็นของตัวเองนะครับ ขึ้นอยู่กับว่ากำหนดไว้ตอนติดตั้ง appserv เป็นอะไร แต่ละคนก็ไม่เหมือนกัน แล้วนำไปเก็บไว้ในตำแหน่งของ www ที่ได้ติดตั้งไว้แล้ว  กรณีของผม ผมสร้างไว้ใน /www/construct/  ทดสอบเรียนใช้งาน ดูว่ามีข้อมูลอะไรเขียนออกมาหรือเปล่า  ผมทดสอบโดยพิมพ์ http://localhost/construct/getuser.php ก็จะมีข้อมูลจากฐานข้อมูลแสดงออกมา



ข้อมูลแต่ละตัวจะคั่นด้วย |  และแต่ละชุดข้อมูลจะคั่นด้วย ,  ซึ่งอาจจะกำหนดเป็นอย่างอื่นได้ในไฟล์ getuser.php ตามที่ผู้เขียนเกมเห็นเหมาะสมนะครับ เพราะเราจะใช้เป็นตัวอ้างอิงในการตัดแบ่งข้อมูล

ต่อไปมาเริ่มงานที่โปรแกรม construct 2 สร้างโปรเจคใหม่ หรือจะใช้โปรแกรมเดิมก็ได้ครับ
เพิ่มวัตถุแบบ array เข้ามาที่เกมของเรา ตั้งชื่อเป็น datagame



แล้วแทรกวัตถุ AJAX เข้ามาในเกมของเรา



เพิ่มเหตุการณ์ เมื่อมีการทำงานกับ layout ใหม่
Add event --> System --> On start of layout
เพิ่มคำสั่งในการเชื่อมต่อฐานข้อมูลด้วย AJAX  ดังนี้
Add action --> AJAX --> Request URL
แล้วกำหนดค่า ดังนี้
Tag  = "getuser"   คือการกำหนดชื่อให้กับการทำงานของ AJAX
URL = "http://localhost/construct/getuser.php" คือ การอ่านข้อมูลจากไฟล์ php ที่เราได้สร้างไว้แล้ว



ขั้นต่อไป นำข้อมูลที่ได้จากการอ่านฐานข้อมูล mysql มาลงใน array ที่เราได้สร้างเอาไว้แล้ว
Add event --> AJAX --> on completed --> "getuser"
คือ เหตุการณ์ที่จะทำงานเมื่ออ่านข้อมูล AJAX จาก tag "getuser" สำเร็จแล้ว
กำหนดขนาดของ array ให้มีขนาดเท่ากับชุดข้อมูลที่อ่านมา
Add action --> Array datagame --> Set size
กำหนด width เท่ากับ จำนวนชุดข้อมูลจากการตัดข้อความด้วยเครื่องหมาย ,  ด้วยคำสั่งtokencount(AJAX.LastData,",")-1
Height เท่ากับ 4 คือ ให้มี 4 คอลัมน์ ตามข้อมูลที่มีในแต่ละชุด


วน loop เพื่อนำข้อมูลไปเก็บยัง array ที่สร้างไว้ ด้วยคำสั่ง ดังนี้


การกำหนดตำแหน่งของข้อมูลใน array กำหนดดังนี้


หลักการทำงานของคำสั่ง token
    คำสั่ง token จะใช้ในการตัดกลุ่มคำออกเป็นกลุ่มย่อยๆ ตามเงื่อนไขของตัวแบ่งที่กำหนด คำสั่งที่สำคัญที่ใช้บ่อย ๆ คือ
        tokencount  เป็น คำสั่งที่ใช้ในการนำจำนวนกลุ่มย่อยของคำที่แบ่งออกมาได้ เช่น tokencount("abxacxayxaz","x") คือนับจำนวนกลุ่มย่อยที่แบ่งด้วยตัว x  จะได้ค่า 4
        tokenat  เป็นคำสั่งที่อ้างถึงกลุ่มคำย่อยที่ถูกแบ่งด้วยตัวแบ่งคำ  เช่น tokenat("abxacxayxaz",0,"x")  คือ กลุ่มย่อยที่ 0 จากการแบ่งคำด้วยตัว x จะได้ข้อความ ab  ออกมา

หลักการคือ แบ่งชุดข้อมูลด้วยตัวอักษร ,  จะได้ชุดข้อมูลของผู้เล่นแต่ละคน  แล้วทำการวนซ้ำในแต่ละชุดข้อมูลด้วยการแยกข้อมูลจากตัวอักษร | จะได้ 4 ข้อมูล แล้วจัดเก็บลงใน array แต่ละตำแหน่ง
เมื่อทดสอบการทำงานของโปรแกรม จะพบข้อมูลใน array ตามข้อมูลที่ได้อ่านมาจากฐานข้อมูล



วันเสาร์ที่ 30 มกราคม พ.ศ. 2559

construct 2 : เกมจับคู่ภาพ ตอนที่ 4

ขั้นที่ 5 จับเวลาในการเล่นเกม
ในการเล่นเกมจะต้องมีการจับเวลา เพื่อใช้เป็นคะแนน นอกจากจะมีความจำดีแล้ว ยังต้องมีความรวดเร็วในการจดจำด้วย โดยเพิ่มวัตถุแบบ Text เข้ามาในหน้าเกม


และใช้คำสั่งในการจับเวลา ดังนี้


เมื่อทดสอบการทำงานของเกม จะได้เวลาในการเล่นแสดง ดังภาพ



ขั้นที่ 6 ตรวจสอบการจบเกม
เงื่อนไขของการจบเกม คือ การที่ผู้เล่นสามารถจับคู่ภาพครบทั้ง 9 คู่ หรือ 18 ภาพ ใช้คำสั่งในการตรวจสอบ ดังนี้

เมื่อจับคู่ภาพได้ทั้งหมด จะเปลี่ยนหน้าเกม ไปยัง layout endgame

การทำงานของ Layout endgame
การทำงานในส่วนนี้จะใช้สำหรับสรุปผลการเล่นเกม และยังสามารถย้อนกลับไปเล่นเกมใหม่อีกครั้งได้ โดยการแทรกพื้นหลัง ข้อความแสดงเวลาที่ใช้ และปุ่มสำหรับเริ่มเกมใหม่ ดังนี้


เพิ่มคำสั่งใน event sheet3 ดังนี้


สำเร็จตามความต้องการ สามารถนำหลักการในการสร้างเกมจับคู่ลักษณะนี้ ไปใช้ในการสร้างเกมในลักษณะคล้ายกัน แต่เปลี่ยนภาพเป็นภาพอื่น เช่น ผลไม้ หรือ ภาพคู่กับคำ ขอให้สนุกกับการสร้างเกมนะครับ


construct 2 : เกมจับคู่ภาพ ตอนที่ 3

ขั้นที่ 3 การกำหนดคำสั่ง สำหรับการทำงานของเกม
การทำงานของเกม จะเปิดบัตรภาพ ทีละคู่ เพื่อหาภาพที่เหมือนกันจนครบทุกคู่
เพิ่มตัวแปร แบบ Global จำนวน 5 ตัว ดังภาพ


กำหนดเหตุการณ์สำหรับการคลิกเมาส์บนบัตรภาพ ดังนี้


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


อธิบายคำสั่ง จากภาพ โดยเพิ่มตัวแปร ชื่อ imageNumber เป็น Number มีค่าเริ่มต้นเป็น 0
ตรวจสอบเมื่อแสดง animation “Untap” จบ จะทำการสร้าง วัตถุ Sprite2 ขึ้นมาในตำแหน่งเดียวกับบัตรภาพ Sprite ที่ถูกคลิก
กำหนดหมายเลขบัตรภาพที่ถูกคลิก ให้กับตัวแปร imageNumber โดยคำนวณจากตำแหน่งของภาพที่ถูกคลิก
เล่นภาพเคลื่อนไหวของบัตรภาพหมายเลขที่ตรงกับค่าของภาพใน array Images
เพิ่มค่า cardsTapped (บอกจำนวนบัตรภาพที่ถูกเปิด) แล้วลบพื้นหลังบัตรภาพทิ้ง
ถ้า cardsTapped = 1 เก็บหมายเลขภาพไว้ที่ตัวแปร firstCard
ถ้า cardsTapped = 2 เก็บหมายเลขภาพไว้ที่ตัวแปร secondCard

เมื่อทดลองเล่นเกม จะสามารถเปิดบัตรภาพได้สองบัตร ดังนี้



ขั้นที่ 4 ตรวจสอบความถูกต้องของบัตรภาพที่เปิด
เมื่อเปิดภาพครบ 2 ภาพ จะต้องตรวจสอบว่าภาพทั้งสองที่เปิดมาเหมือนกันหรือไม่ โดยตรวจสอบเงื่อนไข ดังนี้


จากภาพ ตรวจสอบเมื่อ การเล่นภาพเคลื่อนไหวของ Sprite2 สิ้นสุดลง
ถ้าสถานะของตัวแปร destroy เป็น false
ตรวจสอบว่า ถ้า cardsTapped = 2 ให้ กำหนด cardsTapped = 0
ถ้าภาพที่เปิดเหมือนกัน firstCard = secondCard ให้ ทำลาย Sprite2 ทั้งหมด และเพิ่มค่าบัตรภาพที่ถูกทำลายลงในตัวแปร cardsDestroyed
ถ้าภาพที่เปิดไม่เหมือนกัน firstCard != secondCard ให้ ปิดบัตรภาพ Sprite2 ทั้งหมด และกำหนดค่า destroy เป็น True

ถ้าสถานะของตัวแปร destroy เป็น true ให้สร้างภาพฉากหลังของบัตรภาพขึ้นมาแทนภาพเดิม และทำลายบัตรภาพ และเล่นภาพเคลื่อนไหวในการพลิกบัตรภาพกลับคืน


construct 2 : เกมจับคู่ภาพ ตอนที่ 2


ขั้นที่ 2 การสร้างแผ่นบัตรภาพ
ที่ layout playgame สร้างบัตรภาพ ขนาด 77 x 102 pixel กำหนดชื่อเป็น Sprite


และสร้าง animation ขึ้นมา 2 ตัว สำหรับเปิดบัตรภาพ ชื่อ Untap และปิดบัตรภาพ ชื่อ Tap



กำหนดค่าการเคลื่อนไหวเป็น ดังนี้



กำหนดค่า Instance variables ของบัตรภาพ คือ selected เป็น Boolean มีค่าเริ่มต้นเป็น false


คัดลอกและวางบัตรภาพให้ครบทั้ง 18 แผ่น โดยกำหนด position ของแผ่นแรกเป็น 150 x 175 และแผ่นต่อไปในแถวแรก เพิ่มค่าแกน x ทีละ 100 เช่น แผ่นที่สอง จะได้  250 x 175  และเมื่อเพิ่มแถวใหม่ จะเพิ่มค่าแกน y ทีละ 125  เช่น บัตรภาพที่  3 แถวที่ 2 จะมีค่า position เป็น 350 x 300


สร้างชุดภาพ สำหรับใช้เมื่อมีการเปิดบัตรภาพ กำหนดชื่อเป็น Sprite2 กำหนดชุดภาพที่ใช้ในการจับคู่ในชุด Default ของ animations Sprite2 และสร้างชุด animations ชื่อ Untap จำนวน 9 ชุด 0 – 8 และ Tap จำนวน 9 ชุด 0 – 8 ดังภาพ


ชุดภาพใน Default เป็นภาพที่แสดงเวลาเปิดบัตรภาพออกมา


ภาพในชุด Untap0


ภาพในชุด Untap2 และชุดอื่นๆ จะเป็นลักษณะของการเปิดบัตรภาพ


ภาพในชุด Tap0


ภาพในชุด Tap2 และชุดอื่นๆ จะเป็นลักษณะของการปิดบัตรภาพ


เพิ่มวัตถุแบบ Mouse เข้ามาในเกม