แก้ไขครั้งสุดท้ายโดย nooknazha เมื่อ 2018-6-13 13:50
[Renpy] 27. ทำร้านค้าแบบ Advanced
จากที่มีสมาชิกท่านนึงขอให้ช่วยแปลหน้า http://www.renpy.org/wiki/renpy/... ry_and_Money_System เป็นภาษาไทยนะคะ
เอาล่ะ มาดูโค๊ดแบบที่ 2 กันบ้างข้าพเจ้าแก้โค๊ดบางตัวนิดหน่อย เพราะรองเทสดูแล้วปรากฏว่าค่าเงินถูกหักไป 2รอบเวลาซื้อสินค้า เลยทำให้ยอดเงินคงเหลือแสดงค่าผิดออกมา
นอกจากนี้ข้าพเจ้าก็จัดการแปลบางส่วนแบบคิดเอาเองไปเลยจะได้ดูเป็นไทยเข้าใจง่ายมากขึ้นมาดูโค๊ดตัวอย่างกันดีกว่าค่ะ
- <font size="4">
- define b = Character('คิมหันต์', color="#f8f092")
- init python:
- class Item:
- def __init__(self, name, cost):
- self.name = name
- self.cost = cost
- class Inventory:
- def __init__(self, money=100):
- self.money = money
- self.items = []
- def buy(self, item):
- if self.money >= item.cost:
- self.money -= item.cost
- self.items.append(item)
- return True
- else:
- return False
- def earn(self, amount):
- self.money += amount
- def has_item(self, item):
- if item in self.items:
- return True
- else:
- return False
- label start:
- python:
- inventory = Inventory()
- somtum = Item("ส้มตำถาด", 80)
- fried_rice = Item("ข้าวผัดกุ้ง", 40)
- chocolate = Item("ช็อคกาแล๊ต", 110)
- b "อุ้ย! เจอเงิน 100 บาท"
- $ inventory.earn(100) #เพิ่มเงินเข้าไปอีก 100 บาท
- #บอกให้ผู้เล่นรับรู้ว่าได้รับเงินมาอีก 100 "เงิน" ในขณะเดียวกันโปรแกรมก็ได้ส่งค่า 100 ไปยังคราลของ "inventory" ที่ฟังก์ชั่นชื่อ "earn" เพื่อไปคำนวณและส่งค่าผลลัพธ์ให้กับฟังก์ชั่นชื่อ "money" อีกทอด
- $ current_money = inventory.money #ตรงนี้จะมีเงินรวมอยู่เท่ากับ 200 บาท
- b "ตอนนี้ฉันมีเงินอยู่ %(current_money)d บาท"
- b "ท้องร้องแล้วซิ"
- b "หิวจังเลย.... T T "
-
- if inventory.has_item(chocolate):
- b "ดีนะที่ซื้อช๊อคกาแล๊ตเก็บไว้"
- else:
- b "แย่จังไม่ได้ซื้ออะไรไว้กินเลย"
- jump preshop
- jump shop2
- label preshop:
- $ somtumcost = somtum.cost
- $ fried_ricecost = fried_rice.cost
- $ chocolatecost = chocolate.cost
- label shop2:
- b "ฉันเดินตรงไปที่ร้านอาหารทันที"
- menu shop:
- b "ซื้ออะไรกินดีนะ"
- "ซื้อส้มตำถาด ราคา %(somtumcost)d บาท.":
- if inventory.buy(somtum):
- b "กินกับเส้นหมี่นุ่มๆ ไก่ย่างร้อนๆ โอ้ยอร่อยเหาะ!"
- jump game_continues
- "ซื้อข้าวผัดกุ้ง ราคา %(fried_ricecost)d บาท.":
- if inventory.buy(fried_rice):
- b "อันนี้แหล่ะอิ่มท้องดี"
- jump game_continues
- "ซื้อช็อคกาแล๊ต ราคา %(chocolatecost)d บาท.":
- if inventory.buy(chocolate):
- b "รองท้องไปก่อนละกัน!"
- jump game_continues
- "ไม่ซื้ออะไรเลย":
- jump game_continues
- label fallthrough:
- b "แย่จัง เงินไม่พอซื้อ"
- jump shop2
- label game_continues:
- b "(และฉันก็เดินออกจากร้าน)"
- $ current_money = inventory.money
- b "ฉันเหลือเงิน %(current_money)d บาท"
- </font>
คัดลอกไปที่คลิปบอร์ด อธิบาย:
- <font size="4"> class Item:</font>
คัดลอกไปที่คลิปบอร์ดคลาส Items : บรรทัดนี้เราทำไว้เพื่อให้ren'py รู้ว่ากำลังจะทำการประกาศตัวแปรหลายตัวพร้อมกันโดยตั้งชื่อให้กับคลาสนี้ว่า "Items" แต่ละตัวแปรก็จะมีหน้าที่และคุณสมับัติเฉพาะแตกต่างกันโดยจะมีตัวแปรที่ทำหน้าเชื่อมกัน เช่น ตัวแปรที่ใช้รับค่า เก็บข้อมูล คำนวณและส่งข้อมูลคำตอบออกไปข้างนอก เป็นต้นค่ะ - <font size="4"> def __init__(self, name, cost):</font>
คัดลอกไปที่คลิปบอร์ดภายในคลาส "Item" เราได้กำหนดคร่าวๆว่าโมดูลกลุ่มนี้มีตัวแปรชื่อ "name" และ"cost" เพื่อใช้แทนค่า"ชื่อของสินค้า" และ"ราคาของสินค้า"
(สัญลักษณ์ __init__ เป็นรูปแบบการเขียนภาษาไพธอนที่มีลักษณะของ"ตัวแปร" เป็นชนิด Internal Methon คือใช้ทำงานแค่เฉพาะภายในและไม่สามารถถูกเรียกใช้จากภายนอกได้) - <font size="4">
- self.name = name
- self.cost = cost
- </font>
คัดลอกไปที่คลิปบอร์ด "self" ในที่นี้จะหมายถึง "ในตัวมันเอง"ทำหน้าที่เป็นเหมือน "ชื่อนำหน้า" ที่จะบอกกับตัวแปรอื่นให้รับรู้ว่า"ตัวแปรชื่อนี้อยู่คลาสเดียวกับมัน" นั่นเอง (คลาสชื่อ "Item")
"self.name" เป็นการประกาศตัวแปร"ชนิดตัวอักษร" ชื่อ "name" ภายในคลาสชื่อ"Item" เพื่อมาใช้แทนค่า"ชื่อของสินค้า" และกำหนดให้มีค่าเท่ากับ "name"
"self.cost" เป็นการประกาศตัวแปร "ชนิดตัวเลข" ชื่อ "cost" ภายในคลาสชื่อ "Item"เพื่อมาใช้แทนค่า"ราคาของสินค้า" และกำหนดให้มีค่าเท่ากับ"cost" - <font size="4"> class Inventory:</font>
คัดลอกไปที่คลิปบอร์ด สร้างคลาส Inventoryขึ้นมา โดยตั้งชื่อให้กับคลาสนี้ว่า "Inventory" - def __init__(self, money=100):
คัดลอกไปที่คลิปบอร์ด ภายในคลาส "Inventory" เราได้กำหนดคร่าวๆว่าโมดูลกลุ่มนี้มีตัวแปรชื่อ "money" เป็นชนิด InternalMethod และกำหนดค่าเริ่มต้นให้ = 100 เพื่อมาใช้แทนค่า"จำนวนเงินคงเหลือ" ในเกมส์
- <font size="4"> self.money = money</font>
คัดลอกไปที่คลิปบอร์ด ก่อนหน้าเราได้ประกาศตัวแปรชื่อ "money" ภายในคลาสชื่อ "Inventory"ไปแล้ว โดยในบรรทัดนี้เราได้ระบุว่าตัวแปรชื่อ "self.money"ในคลาสชื่อ "Inventory" มีค่าเท่ากับ"money"
- <font size="4"> self.items = []</font>
คัดลอกไปที่คลิปบอร์ดสร้างตัวแปรชื่อ "items" โดยให้ปัจจุบันกำหนดให้เป็นค่า"ว่าง" ไว้ก่อน ภายในคลาสชื่อ Inventory เพื่อให้มารองรับปริมาณของ"ชื่อสินค้า" และ "ราคาของสินค้า" ที่จะถูกเพิ่มเข้ามาเรื่อยๆในอนาคต - <font size="4"> def buy(self, item):</font>
คัดลอกไปที่คลิปบอร์ด สร้างฟังก์ชั่นสำหรับใช้คำนวณภายในคลาสชื่อ "buy" โดยมีตัวแปรชื่อ"item" ไว้แทนค่าที่รับค่าเข้ามาจากภายนอก
- <font size="4"> if self.money >= item.cost:</font>
คัดลอกไปที่คลิปบอร์ด กำหนดให้ถ้า "money"(จำนวนเงินของผู้เล่น) มากกว่า หรือเท่ากับ "cost"(ราคาสินค้า) จริง
- <font size="4"> self.money -= item.cost</font>
คัดลอกไปที่คลิปบอร์ดให้นำ "money"(จำนวนเงินของผู้เล่น)หักกับ "cost" (ราคาสินค้า)(ก็คือถ้าผู้เล่นคลิกซื้อสินค้าไปแล้ว ให้หักเงินของผู้เล่นออกไปตามราคาของสินค้า)
- <font size="4"> self.items.append(item)</font>
คัดลอกไปที่คลิปบอร์ด จากนั้นให้นำค่า "item" ที่ได้มา ไปเพิ่มให้กับตัวแปรชื่อ "items" (ที่ตอนแรกเรากำหนดให้เป็นค่า "ว่าง" )
- <font size="4"> return True</font>
คัดลอกไปที่คลิปบอร์ด หลังจากผู้เล่นซื้อสินค้าไปแล้วให้ส่งคำตอบว่า "True" กลับไปยังภายนอก
- <font size="4">
- else:
- return False
- </font>
คัดลอกไปที่คลิปบอร์ด แต่ถ้าเงินของผู้เล่นไม่พอซื้อสินค้า (ซื้อไม่ได้หรือไม่ยอมซื้อ)ไปแล้วให้ส่งคำตอบว่า "False" กลับไปยังภายนอกแทนสร้างฟังก์ชั่นชื่อ "earn" เพื่อประกาศตัวแปรคร่าวๆ ชื่อว่า "amount"สำหรับไว้เพิ่มค่า "จำนวนเงินของผู้เล่น"ซึ่งอาจจะได้รับมาด้วยวิธีต่างๆ กันเป็นตัวแปรที่สร้างขึ้นมาเพื่อไว้รับค่าของภายนอกเข้ามา
***เนื่องจากค่าเงินคงเหลือของผู้เล่นในเกมส์เรากำหนดไว้ให้เป็นตัวแปรชนิด Internal Method คือไม่สามารถเพิ่มค่าด้วยคำสั่งภายนอกหรือไม่สามารถเรียกใช้จากภายนอกโดยตรงได้จึงต้องสร้างตัวแปรที่จะมาจัดการมูลค่าเงินคงเหลือของผู้เล่นภายในคลาสแทน และเพื่อให้มันสามารถส่ง "มูลค่าของเงินคงเหลือล่าสุด"กลับไปแจ้งให้ผู้เล่นทราบได้
กำหนดให้ตัวแปรชื่อ"money" (ภายในคลาส Inventory เหมือนกัน ) มีค่าเท่ากับตัวมันเองบวกกับ "amount" (คือถ้ามีเงินเพิ่มเข้ามาด้วยสาเหตุต่างๆกันค่าเงินคงเหลือของผูู้เล่นก็จะอัพเดทเพิ่มขึ้นตาม)
***ตรงนี้เราอาจจะสร้างฟังก์ชั่นอีกตัวเอาไว้สำหรับลดค่าเงินคงเหลือของผู้เล่นเกมส์อีกตัวก็ได้เช่นไว้ในกรณีที่ผู้เล่นนำเงินไปจ่ายค่าบริการ ถูกขโมยที่ไม่เกี่ยวข้องกับการลดลงเพราะนำไปซื้อสินค้า - def has_item(self, item):
คัดลอกไปที่คลิปบอร์ดสร้างฟังก์ชั่นชื่อ"has_item" ไว้สำหรับเช็คดูว่า มีรายชื่อสินค้าที่ซื้อไป ปรากฏอยู่ในตัวแปรชื่อ"items" แล้วหรือยัง
- if item in self.items:
- return True
- else:
- return False
คัดลอกไปที่คลิปบอร์ดให้เช็คดูว่าถ้ามีชื่อสินค้าอยู่ในตัวแปรชื่อ"items" อยู่ "จริง" ให้ส่งคำตอบกลับไปภายนอกว่า "True"แต่ถ้าไม่มีให้ส่งคำตอบกลับไปภายนอกว่า "False" - <font size="4">label start:</font>
คัดลอกไปที่คลิปบอร์ดเริ่นต้มเกมส์ - <font size="4"> python:</font>
คัดลอกไปที่คลิปบอร์ดประกาศตัวแปรรองรับที่จะถูกนำมาใช้นับจากนี้ไป - <font size="4"> inventory = Inventory()
- </font>
คัดลอกไปที่คลิปบอร์ด สร้างตัวแปร "inventory" เพื่อใช้อ้างอิงค่ากับคลาสชื่อ "Inventory" สัญลักษณ์ ()ต่อท้ายหมายถึงฟังก์โมดูลต่างๆที่อยู่ภายในคลาส- <font size="4">
- somtum = Item("ส้มตำถาด", 80)</font>
คัดลอกไปที่คลิปบอร์ดสร้างตัวแปร "inventory" เพื่อใช้อ้างอิงค่ากับคลาสชื่อ "Inventory" สัญลักษณ์ ()ต่อท้ายหมายถึงฟังก์โมดูลต่างๆที่อยู่ภายในคลาส - <font size="4">
- ried_rice = Item("ข้าวผัดกุ้ง", 40)
- chocolate = Item("ช็อคกาแล๊ต", 110)
- </font>
คัดลอกไปที่คลิปบอร์ดสร้างตัวแปรอื่นๆขึ้นมาอีกแบบเดียวกับตัวแปร somtumเพื่อให้เป็นทางเลือกให้กับผู้เล่น - <font size="4">
- b "อุ้ย! เจอเงิน 100 บาท"
- $ inventory.earn(100)
- </font>
คัดลอกไปที่คลิปบอร์ด เขียนประโยคเพื่อบอกให้ผู้เล่นรู้ว่าเกิดเหตุการณ์อะไรขึ้นพร้อมกับเพิ่มเงินคงเหลือของผู้เล่นเข้าไปอีก 100 บาท (ren'py จะดึงฟังก์ชั่นinventory.earn มาใช้และช่วยเพิ่มมูลค่าให้กับตัวแปร "money" )- <font size="4">
- $ current_money = inventory.money
- </font>
คัดลอกไปที่คลิปบอร์ดสร้างตัวแปรชื่อ current_money เพื่อให้อ้างอิงค่าเงินคงเหลือล่าสุดที่ถูกเก็บไว้อยู่ในคลาส"Inventory" ชื่อตัวแปร "money"
- <font size="4">
- b "ตอนนี้ฉันมีเงินอยู่ %(current_money)d บาท"
- b "ท้องร้องแล้วซิ"
- b "หิวจังเลย.... T T "
- if inventory.has_item(chocolate):
- b "ดีนะที่ซื้อช๊อคกาแล๊ตเก็บไว้"
- else:
- b "แย่จังไม่ได้ซื้ออะไรไว้กินเลย"
- </font>
คัดลอกไปที่คลิปบอร์ดสร้างเงื่อนไขไว้ตรวจสอบว่าขณะนี้มี"ชื่อสินค้าที่(chocolate)" ซื้อมาเก็บไว้อยู่ก่อนแล้วหรือไม่ - <font size="4">
- jump preshop
- jump shop2
- </font>
คัดลอกไปที่คลิปบอร์ดให้ข้ามไปยัง label โดยไม่ต้อง return.ดูข้างล่างสำหรับส่วนต่อไป - <font size="4">
- label preshop:
- $ somtumcost = somtum.cost
- $ fried_ricecost = fried_rice.cost
- $ chocolatecost = chocolate.cost
- </font>
คัดลอกไปที่คลิปบอร์ดสร้างตัวแปรเสริมสำหรับไว้แสดงผลโดยค่าของตัวแปรนี้จะเชื่อมกับตัวแปรชื่อ "name" และ "cost" ในคลาสชื่อ "Item" โดยตรง(อย่างที่บอกไว้ข้างต้นว่าคลาสชื่อ "Item" ได้ประกาศตัวแปรชื่อ "name"และ "cost" ไว้เป็นแบบ InternalMethod คือไม่สามารถดึงค่าออกมาแสดงภายนอกโดยตรงได้จำเป็นต้องสร้างตัวแปรภายนอก มาเชื่อมกับเพื่อให้สามารถดึงค่าภายในออกมาแสดงได้ )
- <font size="4">
- label shop2:
- b "ฉันเดินตรงไปที่ร้านอาหารทันที"
- menu shop:
- b "ซื้ออะไรกินดีนะ"
- "ซื้อส้มตำถาด ราคา %(somtumcost)d บาท.":
- </font>
คัดลอกไปที่คลิปบอร์ด สร้าง label ทางเลือกสินค้าให้กับผู้เล่นโดยแต่ละช้อยทางเลือกจะมีการดึงค่าข้อมูลภายในคลาส Item ตัวแปรชื่อcost ผ่านตัวแปรนอกที่ประกาศไว้ข้างต้นขึ้นมาแสดง
- if inventory.buy(somtum):
- b "กินกับเส้นหมี่นุ่มๆ ไก่ย่างร้อนๆ โอ้ยอร่อยเหาะ!"
- jump game_continues
คัดลอกไปที่คลิปบอร์ดสร้างเงื่อนไขถ้าผู้เล่นคลิกซื้อ"somtum" หรือ Item("ส้มตำถาด", 80) "จริง" ให้ทำตามคำสั่งต่อไปดังนี้
แสดงคำว่า "กินกับเส้นหมี่นุ่มๆ ไก่ย่างร้อนๆโอ้ยอร่อยเหาะ!" และให้ข้ามไปยัง label game_continues - <font size="4">
- "ซื้อข้าวผัดกุ้ง ราคา %(fried_ricecost)d บาท.":
- if inventory.buy(fried_rice):
- b "อันนี้แหล่ะอิ่มท้องดี"
- jump game_continues
- "ซื้อช็อคกาแล๊ต ราคา %(chocolatecost)d บาท.":
- if inventory.buy(chocolate):
- b "รองท้องไปก่อนละกัน!"
- jump game_continues
- "ไม่ซื้ออะไรเลย":
- jump game_continues
- </font>
คัดลอกไปที่คลิปบอร์ดทุกครั้งที่มีการซื้อสินค้าควรมีทางเลือกสำหรับยกเลิกการซื้อให้กับผู้เล่นด้วย - <font size="4">
- label fallthrough:
- b "แย่จัง เงินไม่พอซื้อ"
- jump shop2
- </font>
คัดลอกไปที่คลิปบอร์ดเมื่อผู้เล่นมีเงินไม่พอซื้อค่าที่ได้รับจากเงื่อนไขทางเลือกจะกลายเป็น False และวิ่งมาที่ label นี้เพื่อแสดงคำว่า"แย่จัง เงินไม่พอซื้อ"ก่อนที่จะวิ่งกลับไปแสดงหน้าทางเลือกเดิมอีกครั้ง - <font size="4">
- label game_continues:
- b "(และฉันก็เดินออกจากร้าน)"
- $ current_money = inventory.money
- b "ฉันเหลือเงิน %(current_money)d บาท"
- </font>
คัดลอกไปที่คลิปบอร์ด ใน label สุดท้ายนี้จะมีการอัพเดทยอดเงินคงเหลือล่าสุดอีกครั้งก่อนที่จะสั่งให้แสดงออกมาให้ผู้เล่นรับทราบ ทดสอบโค๊ด:
***************************************
บทความโดย นุ้ก
ขอจบบทความแค่เพียงเท่านี้ แล้วพบกันใหม่บทความหน้าค่ะ ^^
(ขอสงวนสิทธิ์อนุญาตให้เผยแพร่เฉพาะในเว็บ www.graphicfufu.comเท่านั้น)
|