nooknazha โพสต์ 2018-6-13 13:30:41

[Renpy] 27. ทำร้านค้าแบบ Advanced

แก้ไขครั้งสุดท้ายโดย nooknazha เมื่อ 2018-6-13 13:50

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" กลับไปยังภายนอกแทน      def earn(self, amount):สร้างฟังก์ชั่นชื่อ "earn" เพื่อประกาศตัวแปรคร่าวๆ ชื่อว่า "amount"สำหรับไว้เพิ่มค่า "จำนวนเงินของผู้เล่น"ซึ่งอาจจะได้รับมาด้วยวิธีต่างๆ กันเป็นตัวแปรที่สร้างขึ้นมาเพื่อไว้รับค่าของภายนอกเข้ามา

***เนื่องจากค่าเงินคงเหลือของผู้เล่นในเกมส์เรากำหนดไว้ให้เป็นตัวแปรชนิดInternal Method คือไม่สามารถเพิ่มค่าด้วยคำสั่งภายนอกหรือไม่สามารถเรียกใช้จากภายนอกโดยตรงได้จึงต้องสร้างตัวแปรที่จะมาจัดการมูลค่าเงินคงเหลือของผู้เล่นภายในคลาสแทนและเพื่อให้มันสามารถส่ง "มูลค่าของเงินคงเหลือล่าสุด"กลับไปแจ้งให้ผู้เล่นทราบได้
            self.money += amountกำหนดให้ตัวแปรชื่อ"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เท่านั้น)


หน้า: [1]
ดูในรูปแบบกติ: [Renpy] 27. ทำร้านค้าแบบ Advanced