[Ren'Py] ระบบต่อสู้จากเกม Guardian Tales - The Behind of Light - dreamknight -  07-07-2014
 
 
;3 
 
สวัสดีครับทุกท่าน พอดีมีผู้สนใจวิธีการทำระบบสู้ในเกม Guardian Tales - The Behind of Light แล้วระบบก็ไม่ได้ยากอะไร ผมก็เลยจะมาอธิบายวิธีเขียนให้ทุกท่านที่สนใจอ่านกันครับ 
 
แปะมู้เกมกันเสียเล็กน้อย http://irpg.in.th/thread-1642.html    
 
ขอออกตัวก่อนว่าอันที่จริงผมไม่ได้คิดเองหมด ผมประยุกต์เอาเสียมากกว่า ทุกท่านที่ได้ศึกษา Renpy มาคงได้เข้าไปศึกษาที่เว็บ thaigraph กันใช่ไหมครับ ผมก็เอามาจากที่นั้นแหละ แหะๆ ยังไงก็ขอขอบคุณท่าน NOOKFUFU2 จาก thaigraph ที่มีบทความดีๆ ให้ผมได้ศึกษาครับ ;w; 
 
ช่วงที่พัฒนาขึ้นมานั้น ผมมีเวลาสร้างเกมจำกัดอาจจะเขียนระบบไว้ไม่ดีนัก ทุกท่านก็ลองเอาไปประยุกต์ให้ดีขึ้นแล้วกันครับ   
 
พูดเยอะไปและ เข้าเรื่องดีกว่า. . . อาโน. . พูดเรื่องไรก่อนดีอ่ะ // โดนถีบ   
 
 
หลอดพลังของตัวละคร 
หลอดพลังของทั้งของตัวเอกและของมอน ผมประยุกต์มาจากบทความนี้ครับ วิธีทำ label Fight RPG  
 
แต่ในเกมผมจะเอาแค่หลอดพลังเท่านั้น ก็เอาแต่ ui.bar มาใช้ครับ 
 
Code: init: 
    python hide: 
        def score_honor(): 
            if show_score: 
                ui.bar(max_score_honor, score_honor, 
                xmaximum=312, 
                ymaximum=35, 
                left_bar=Frame("honorgate_full.png", 0, 0), 
                right_bar=Frame("honorgate_empty.png", 0, 0), 
                thumb=None, 
                thumb_shadow=None) 
        config.overlay_functions.append(score_honor) 
         
        def mon_hp(): 
            if show_mon: 
                ui.bar(mon_max_hp, mon_hp, 
                xmaximum=312, 
                ymaximum=21, 
                left_bar=Frame("mongate_full.png", 0, 0), 
                right_bar=Frame("mongate_empty.png", 0, 0), 
                thumb=None, 
                thumb_shadow=None) 
        config.overlay_functions.append(mon_hp)
  
นำ code ด้านบน วางไว้ในไฟล์ .rpy ไฟล์ใดก็ได้ แต่ต้องไม่อยู่ภายใน label screen หรือ init python ใดๆ ส่วนของผมวางไว้ล่างสุดของไฟล์ options.rpy ส่วนรูปหลอดพลังให้หาหรือสร้างเอาเองนะครับ  
 
ui.bar() เป็นฟังก์ชันสร้าง bar ของ Renpy  รายละเอียด คลิ๊ก  
 
และมีตัวแปรควบคุมการซ่อน/แสดง หลอดพลังด้วย show_score, show_mon 
 
วิธีใช้ 
ที่ไฟล์ script.rpy ประการตัวแปร max_hp และ hp ณ ปัจจุบัน สำหรับใช้ใน ui.bar เอาไว้บนสุดของไฟล์ หรือที่เดียวกับตัวแปรพวกตัวละคร(Character) และตัวแปร show_score, show_mon เป็น false เพื่อซ่อนไว้ ไม่ให้เห็นตั้งแต่เริ่มเกม (เวลาแสดงก็แค่เขียน $ show_score = True เวลาซ่อนก็เขียน $ show_score = False) 
 
Code: $ show_score = False 
$ show_mon = False 
$ max_score_honor = 100 
$ score_honor = 0  
$ mon_max_hp = 100 
$ mon_hp = 0
  
จะลดพลังของมอน ก็เขียน $ mon_hp -= 5 หรือจะเพิ่มพลังก็เขียน $ mon_hp += 5 ลงไป ($ mon_hp -= 5 กับ $ mon_hp = $ mon_hp - 5 มีความหมายเดียวกัน) 
*เกมของผมพระเอกไม่ได้มีหลอดพลัง แต่เป็นแต้มเพิ่มไปเรื่อยๆ จนถึง ค่า max 
 
 
ระบบสู้ 
ตัวอย่าง code ระบบสู้ภายในเกม พร้อมเขียนอธิบายไว้ในบรรทัด 
 
Code: $ show_score = True 
    $ show_mon = True     
    $ mon_max_hp = 100  # เลือดทั้งหมดของมอน 
    $ mon_hp = 100 # เลือด ณ ปัจจุบันของมอน 
    $ actor_attack_point  = 1.0 # พลังโจมตีของตัวเอก 
    $ actor_cri_point  = 2.0 # พลังโจมตีติดคริของตัวเอก 
    $ mon_attack_point  = 5 # พลังโจมตีของมอน 
    $ mon_cri_point  = 9 # พลังโจมตีติดคริของมอน 
    $ hit = False 
    $ miss = False 
     
    speaker "FIGHT !!"  # โชว์ข้อความก่อนเข้าลูปสู้ 
     
    while mon_hp > 0:  # วนลูปไปเรื่อยๆ จนกว่าพลังมอนจะเหลือ 0 
         
        $ show_score = False # ซ่อนหลอดพลังไว้หรือไม่อยากซ่อนก็เอาออกไป 
         
        if miss: # อันนี้เขียนเงื่อนไขดักไว้กรณีเรากดปุ่ม HIT ไม่ทันหรือกดไม่โดน 
                call expression renpy.random.choice(["mon_hit", "mon_cri"]) 
                # call expression เป็นการใช้เรียกใช้เหตุการณ์ ซึ่งจะไม่เหมือน jump ตรงที่หลังจากจบเหตุการณ์ที่เรียกมาใช้แล้ว จะกลับมารันเหตุการณ์เดิมต่อไป ซึ่งถ้าเป็น jump พอไปอีกเหตุการณ์หนึ่ง ก็จะจบเกมทันที  
                # renpy.random.choice() ฟังก์ชั่นแรนดอมของ Renpy 
                $ miss = False 
         
        $ hit = False 
        show screen btnHit(renpy.random.randint(1, 10)) 
        # เข้า screen btnHit() 
        # renpy.random.randint() เป็นฟังก์ชั่นแรนดอมตัวเลขของ Renpy ในที่นี้แรนดอมเลข 1 ถึง 10 
         
        show wyvern_pic at center 
        with Pause(1.0) # หยุดรอให้เวลาเรากดปุ่ม Hit ที่นี่  
         
        hide screen btnHit 
         
        if hit == False: # เข้าเงื่อนไขถ้าผู้เล่นกด Hit ไม่ทันหรือกดไม่โดน 
            play sound "sound/dragonsnarl.mp3" 
            $ show_score = True 
            wyvern "! ! ! ! ! ! ! !" 
            stop sound fadeout 0.5             
            $ miss = True 
     
    # End while      
    $ show_score = True    
    wyvern ". . . . . . . . . . . . . . ."
  
 
การทำปุ่ม Hit 
ปุ่ม Hit หรือ Critical ผมเขียนคล้ายฟังก์ชั่นเอาไว้ ให้ง่ายต่อการใช้  
 
Code: screen btnHit(damage):     
    if damage <= 7: # เงื่อนไขถ้าน้อยกว่าหรือเท่ากับ 7 ให้โชว์ปุ่ม Hit 
        hbox: 
            area (renpy.random.randint(10, 650), renpy.random.randint(10, 300), 1.0, 75) 
            imagebutton: 
                    idle "hit_damage.png" 
                    hover "hit_damage_hover.png" 
                    action ui.callsinnewcontext("actor_hit") 
    else: 
        hbox: 
            area (renpy.random.randint(15, 650), renpy.random.randint(10, 300), 1.0, 75) 
            imagebutton: 
                    idle "menu/cri_damage.png" 
                    hover "menu/cri_damage_hover.png"              
                    action ui.callsinnewcontext("actor_cri")   
                 
label actor_hit:     
    show bg_blank with wflash 
    with sshake 
    play sound "sound/attack3.ogg" 
    $ mon_hp = mon_hp - actor_attack_point 
    $ score_honor += actor_attack_point 
    $ hit = True 
    return 
 
label actor_cri: 
    show bg_blank with wflash 
    with sshake 
    play sound "sound/battle3.ogg" 
    $ mon_hp = mon_hp - actor_cri_point 
    $ score_honor += actor_cri_point 
    $ hit = True 
    return
  
ui.callsinnewcontext() เอาไว้เรียกใช้ฟังก์ชั่น(เป็น Label) อีกทีหนึ่ง รายละเอียด คลิ๊ก 
 
ส่วน code การโจมตีของมอน ก็เขียนเป็น label แยกไว้แบบตีธรรมดากับตีคริ ตรงนี้ผมไม่อธิบายแล้วกันฮะ เพราะน่าจะเข้าใจกัน 
 
Code: label mon_hit: 
    show bg_blank with rflash 
    with sshake 
    play sound "sound/damage4.ogg" 
    if score_honor >= 1: 
        $ score_honor = score_honor - mon_attack_point   
    else: 
        $ score_honor = 1   
    $ hit = True 
    return 
  
label mon_cri:  
    show bg_blank with rflash 
    with sshake 
    play sound "sound/battle1.ogg" 
    if score_honor >= 1: 
        $ score_honor = score_honor - mon_cri_point 
    else: 
        $ score_honor = 1  
    $ hit = True 
    return
  
การเขียนระบบสู้ของผมก็มีเพียงเท่านี้ครับ ลองประยุกต์กันดูนะครับ  . .
 
 
 
RE: ระบบต่อสู้จากเกม Guardian Tales - The Behind of Light - jin -  07-07-2014
 
 
ขอบคุณมากครับท่านฝัน
 
 
 
 |