การเข้ารหัสสถานะต่าง ๆ ในเกมผจญภัย


12

ฉันวางแผนเกมผจญภัยและไม่สามารถเข้าใจได้ว่าอะไรคือวิธีที่เหมาะสมในการใช้พฤติกรรมของระดับขึ้นอยู่กับสถานะของเรื่องราวที่ก้าวหน้า

เกมผู้เล่นเดี่ยวของฉันมีโลกขนาดใหญ่ที่ผู้เล่นต้องโต้ตอบกับผู้คนในเมืองตามจุดต่าง ๆ ในเกม อย่างไรก็ตามขึ้นอยู่กับความก้าวหน้าของเรื่องราวสิ่งต่าง ๆ จะถูกนำเสนอต่อผู้เล่นเช่นหัวหน้ากิลด์จะเปลี่ยนสถานที่จากจัตุรัสกลางเมืองเป็นสถานที่ต่าง ๆ ทั่วเมือง; ประตูจะปลดล็อคในบางช่วงเวลาของวันหลังจากเสร็จสิ้นภารกิจประจำ เหตุการณ์หน้าจอ / ทริกเกอร์ที่แตกต่างกันเกิดขึ้นหลังจากเหตุการณ์สำคัญผ่านไปแล้วเท่านั้น

ฉันคิดอย่างไร้เหตุผลว่าจะใช้คำสั่ง switch {} เพื่อตัดสินใจว่า NPC ควรพูดอะไรหรือควรจะหาคำตอบได้ที่ไหนและทำให้วัตถุประสงค์การสืบเสาะสามารถโต้ตอบได้หลังจากตรวจสอบสภาพของตัวแปร game_state ทั่วโลกแล้ว แต่ฉันรู้ว่าฉันจะวิ่งเข้าสู่สภาวะเกมและสวิทซ์เคสที่แตกต่างกันอย่างรวดเร็วเพื่อเปลี่ยนพฤติกรรมของวัตถุ คำสั่ง switch นั้นยากที่จะดีบั๊กอย่างหนาแน่นและฉันคิดว่ามันอาจยากที่จะใช้ในตัวแก้ไขระดับ

ดังนั้นฉันคิดว่าแทนที่จะมีวัตถุเดียวที่มีหลายสถานะบางทีฉันควรมีหลายอินสแตนซ์ของวัตถุเดียวกันด้วยสถานะเดียว ด้วยวิธีนี้ถ้าฉันใช้บางอย่างเช่นเครื่องมือแก้ไขเลเวลฉันสามารถใส่ตัวอย่างของ NPC ลงในตำแหน่งต่าง ๆ ที่เขาเคยปรากฏมาและเป็นตัวอย่างสำหรับแต่ละสถานะการสนทนาที่เขามี แต่นั่นหมายความว่าจะมีวัตถุเกมที่มองไม่เห็นที่ไม่ได้ใช้งานจำนวนมากลอยอยู่รอบ ๆ ระดับซึ่งอาจเป็นปัญหาสำหรับหน่วยความจำหรือยากที่จะเห็นในเครื่องมือแก้ไขระดับฉันไม่รู้

หรือทำง่ายๆเหมือนกัน แต่แยกระดับสำหรับแต่ละสถานะของเกม นี่เป็นวิธีที่สะอาดและปราศจากข้อผิดพลาดในการทำสิ่งต่าง ๆ แต่มันให้ความรู้สึกเหมือนการทำงานด้วยมือขนาดใหญ่ทำให้แน่ใจว่าแต่ละระดับของรุ่นนั้นเหมือนกันจริง ๆ

วิธีการทั้งหมดของฉันรู้สึกไม่มีประสิทธิภาพดังนั้นเพื่อสรุปคำถามของฉันมีวิธีที่ดีขึ้นหรือเป็นมาตรฐานในการใช้พฤติกรรมของระดับขึ้นอยู่กับสถานะของการดำเนินเรื่อง

PS: ฉันยังไม่มีเครื่องมือแก้ไขเลเวล - คิดจะใช้ JME SDK หรือทำเอง

คำตอบ:


9

ผมคิดว่าสิ่งที่คุณต้องการในกรณีนี้คือการออกแบบรูปแบบของรัฐ แทนที่จะมีหลาย ๆ อินสแตนซ์ของแต่ละออบเจ็กต์เกมสร้างอินสแตนซ์เดียว แต่ห่อหุ้มพฤติกรรมของมันในคลาสที่แยกต่างหาก สร้างคลาสหลายคลาสหนึ่งคลาสสำหรับแต่ละลักษณะการทำงานที่เป็นไปได้ เชื่อมโยงหนึ่งกับวัตถุเกมของคุณ (สถานะเริ่มต้น) และเมื่อเงื่อนไขเปลี่ยนแปลง (ถึงเหตุการณ์สำคัญเวลาของวันที่ผ่านไป ฯลฯ ) คุณสลับสถานะของวัตถุนั้น (เช่นเชื่อมโยงกับวัตถุอื่นขึ้นอยู่กับตรรกะเกมของคุณ) และอัพเดตคุณสมบัติถ้ามี

ตัวอย่างหนึ่งของลักษณะอินเตอร์เฟสของรัฐ (ประกอบขึ้นอย่างสมบูรณ์ - เพียงเพื่อแสดงระดับการควบคุมชุดรูปแบบนี้ให้คุณ):

interface NPCState {
    Scene whereAmI(NPC o);
    String saySomething(NPC o);
}

และการใช้งานสองคลาส:

class Busy implements NPCState {
    Scene whereAmI(NPC o) {
        return o.getWorkScene();
    }
    String saySomething(NPC o) {
        return "Can't talk now, I'm busy!";
    }
}

class Available implements NPCState {
    Scene whereAmI(NPC o) {
        return TAVERN;
    }
    String saySomething(NPC o) {
        String[] choices = o.getRandomChat();
        return choices[RANDOM.getInt(choices.length)];
    }
}

และเปลี่ยนสถานะ:

// The time of day passed from "afternoon" to "evening"
NPCState available = new Available();
for ( NPC o : list ) {
    Scene oldScene = o.state.whereAmI(o);
    o.state = available;
    Scene newScene = o.state.whereAmI(o);
    moveGameObject(o, oldScene, newScene);
    ...

สิ่งสำคัญ NPC อาจมีสถานะที่กำหนดเองตรรกะการเลือกสถานะอาจปรับแต่งได้มากขึ้นและคุณสามารถมีสถานะแตกต่างกันสำหรับแง่มุมต่าง ๆ ของเกม (ในตัวอย่างนี้ฉันใช้คลาสเดียวเพื่อบอกทั้งตำแหน่งและการแชท แต่คุณสามารถแยกได้ พวกเขาและทำหลายชุด)

วิธีนี้ใช้งานได้ดีกับเครื่องมือแก้ไขระดับ: คุณสามารถมีคอมโบบ็อกซ์แบบง่ายๆเพื่อสลับสถานะ "ทั่วโลก" ของระดับจากนั้นเพิ่มและเปลี่ยนตำแหน่งของวัตถุเกมตามที่คุณต้องการให้ปรากฏในสถานะนั้น เอ็นจิ้นเกมจะต้องรับผิดชอบในการ "เพิ่ม" วัตถุนั้นไปยังที่เกิดเหตุเมื่อมีสถานะที่ถูกต้องเท่านั้น แต่พารามิเตอร์ของมันจะยังคงสามารถแก้ไขได้ด้วยวิธีที่ใช้งานง่าย

(ข้อจำกัดความรับผิดชอบ: ฉันมีประสบการณ์ในโลกแห่งความเป็นจริงเล็กน้อยกับผู้แก้ไขเกมดังนั้นฉันสามารถพูดได้อย่างมั่นใจเกี่ยวกับการทำงานของบรรณาธิการมืออาชีพ แต่ประเด็นของฉันเกี่ยวกับรูปแบบของรัฐยังคงอยู่การจัดการรหัสของคุณ ทรัพยากร.)


ใช่คุณสามารถรวมรูปแบบการออกแบบของรัฐนี้กับอาเรย์ที่เชื่อมโยงที่ฉันอธิบายไว้ได้ คุณสามารถเขียนรหัสสถานะวัตถุตามที่อธิบายไว้ที่นี่จากนั้นเลือกระหว่างวัตถุสถานะต่าง ๆ โดยใช้อาร์เรย์เชื่อมโยงตามที่ฉันแนะนำ
jhocking

ฉันยอมรับว่ามันเป็นการดีที่จะแยกเกมออกจากเครื่องยนต์ของมันและตรรกะของเกม hardcoding จะเสริมสร้างความสัมพันธ์ระหว่างพวกเขา (ลดความเป็นไปได้ที่จะนำมาใช้ซ้ำ) มีการถ่วงดุลอำนาจเป็น แต่เนื่องจากขึ้นอยู่กับความซับซ้อนของพฤติกรรมตั้งใจของคุณพยายามที่จะ "รหัสอ่อน" ทุกอย่างที่อาจทำให้เกิดความยุ่งเหยิงที่ไม่จำเป็น ในกรณีนี้วิธีการแบบผสมอาจเป็นที่ต้องการ (เช่นมีตรรกะการเปลี่ยนสถานะ "ทั่วไป" แต่อนุญาตให้มีการรวมรหัสที่กำหนดเองได้เช่นกัน)
mgibsonbr

ดังนั้นเมื่อฉันเข้าใจแล้วมีการแมปแบบหนึ่งต่อหนึ่ง btwn NPCState และ GameState จากนั้นฉันก็วาง NPC ในอาร์เรย์แล้ววนซ้ำมันกำหนด NPCState ใหม่เมื่อสังเกตเห็นการเปลี่ยนแปลงสถานะของเกม NPCState จะต้องมีความสามารถในการรู้วิธีการจัดการทุก NPC ต่าง ๆ ที่ถูกส่งไปดังนั้น NPCState จึงมีพฤติกรรมของ NPC ทั้งหมดสำหรับสถานะที่กำหนด? ฉันชอบที่พฤติกรรมทั้งหมดเก็บอย่างหมดจดใน NPCState เดียวซึ่งแมปอย่างหมดจดกับการใช้งานโปรแกรมแก้ไขเกม แต่มันทำให้ NPCState ค่อนข้างใหญ่
Cardin

โอ้ฉันคิดว่าฉันเข้าใจผิด ฉันเปลี่ยนมันเล็กน้อยเพื่อรวมผู้สังเกตการณ์ ดังนั้นมันจึงเป็น NPCState ที่แตกต่างกันสำหรับทุก NPC ที่ต่างกันยกเว้น Super NPC ทั่วไปอย่าง Crowd NPC ที่สามารถแชร์สถานะได้ สำหรับแต่ละสถานะของเกม NPC จะลงทะเบียนตัวเองและ NPCState กับผู้สังเกตการณ์ ดังนั้นผู้สังเกตการณ์จะรู้ว่า NPC ใดที่ลงทะเบียนไว้เพื่อเปลี่ยนพฤติกรรมที่สถานะเกมและเพียงแค่ทำซ้ำผ่านพวกเขา และในด้านเครื่องมือแก้ไขเกมตัวแก้ไขเกมจะต้องส่งสัญญาณไปยังผู้สังเกตการณ์เพื่อเปลี่ยนสถานะของทั้งระดับ
Cardin

1
ใช่นั่นคือความคิด! NPC ที่สำคัญจะมีหลายรัฐและการเปลี่ยนสถานะจะขึ้นอยู่กับเหตุการณ์สำคัญที่เสร็จสมบูรณ์ Generic NPCs อาจตอบสนองต่อเหตุการณ์สำคัญบางครั้งและยังมีสถานะที่เลือกไว้ขึ้นอยู่กับคุณสมบัติภายใน (สมมติว่า NPCs ทั้งหมดมีสถานะเริ่มต้นเริ่มต้นและเมื่อคุณพูดคุยกับหนึ่งในนั้นเป็นครั้งแรกที่เขาแนะนำตัวเองแล้วป้อน วงจรการเปลี่ยนสถานะปกติ)
mgibsonbr

2

ตัวเลือกที่ฉันจะพิจารณาคือทำให้วัตถุแต่ละชิ้นตอบสนองต่อนักเล่นเกมที่แตกต่างกันหรือให้บริการในระดับที่แตกต่างกันในนักเล่นเกมที่แตกต่างกัน ตัวเลือกระหว่างทั้งสองนั้นจะขึ้นอยู่กับสิ่งที่ฉันพยายามทำในเกม (สิ่งที่แตกต่างกันคืออะไรเกมจะเปลี่ยนแปลงระหว่างรัฐอย่างไร ฯลฯ )

ไม่ว่าอย่างไรก็ตามด้วยวิธีใดฉันจะไม่ทำอย่างนั้นด้วยการเขียนโค้ดลงในรหัสเกม แทนที่จะเป็นคำสั่ง switch ขนาดใหญ่ในวัตถุ NPC ฉันจะแทนที่พฤติกรรมของ NPC ที่โหลดลงในอาเรย์แบบเชื่อมโยงจากไฟล์ข้อมูลจากนั้นใช้อาเรย์แบบเชื่อมโยงนั้นเพื่อเรียกใช้พฤติกรรมที่แตกต่างกันสำหรับสถานะที่เกี่ยวข้องดังนี้

if (state in behaviors) {
  behaviors[state]();
}

ไฟล์ข้อมูลนั้นเป็นภาษาสคริปต์ชนิดหนึ่งหรือไม่ ฉันคิดว่าไฟล์ข้อมูลข้อความธรรมดาอาจไม่เพียงพอที่จะอธิบายพฤติกรรม ไม่ว่าคุณจะถูกโหลดแบบไดนามิกก็ตาม ฉันไม่คิดว่าจะใช้ตัวแก้ไขเกมเพื่อสร้างรหัส Java ที่ถูกต้อง แต่อย่างใดต้องแยกวิเคราะห์อย่างแน่นอน
Cardin

1
นั่นคือความคิดเริ่มต้นของฉัน แต่หลังจากได้เห็นคำตอบของ mgibsonbr ฉันรู้ว่าคุณสามารถเขียนรหัสพฤติกรรมต่าง ๆ เป็นคลาสแยกจากนั้นในไฟล์ข้อมูลเพียงแค่บอกว่าพฤติกรรมพฤติกรรมใดที่เข้ากับสถานะใด โหลดข้อมูลนั้นลงในอาเรย์แบบเชื่อมโยง ณ รันไทม์
jhocking

โอ้ .. แน่นอนว่าง่ายกว่า! : D เปรียบเทียบกับสถานการณ์การฝังบางอย่างเช่น Lua haha ​​..
Cardin

2

สิ่งที่เกี่ยวกับการใช้รูปแบบการสังเกตการณ์เพื่อมองหาการเปลี่ยนแปลงครั้งสำคัญ? หากมีการเปลี่ยนแปลงเกิดขึ้นบางคลาสจะจดจำสิ่งนี้และจัดการกับตัวอย่างการเปลี่ยนแปลงที่ต้องทำกับ npc

แทนที่จะใช้รูปแบบการออกแบบของรัฐที่กล่าวถึงฉันจะใช้รูปแบบกลยุทธ์

หาก npc มี n วิธีในการโต้ตอบกับตัวละครและตำแหน่ง m ซึ่งเป็นไปได้เขาจะมีคลาส +1 (m * n) +1 สูงสุดที่คุณต้องออกแบบ การใช้รูปแบบกลยุทธ์คุณจะจบลงด้วยคลาส n + m + 1 แต่กลยุทธ์เหล่านี้สามารถใช้โดย npcs อื่น ๆ ได้

ดังนั้นอาจมีชั้นเรียนจัดการเหตุการณ์สำคัญและชั้นเรียนที่สังเกตชั้นเรียนนี้และจัดการทั้ง npc หรือศัตรูหรือสิ่งที่ควรมีการเปลี่ยนแปลง หากผู้สังเกตการณ์ได้รับการปรับปรุงพวกเขาจะตัดสินใจว่าพวกเขาจะต้องเปลี่ยนบางสิ่งเป็นกรณีที่พวกเขาปกครองหรือไม่ ตัวอย่างเช่นคลาส NPC ใน Constructor จะแจ้งให้ NPC-Manager ทราบเมื่อเขาต้องได้รับการอัปเดตและสิ่งที่ต้องอัปเดต ...


รูปแบบการสังเกตการณ์ที่น่าสนใจ ฉันคิดว่ามันสามารถทิ้งความรับผิดชอบทั้งหมดไว้กับ NPC อย่างหมดจดเพื่อลงทะเบียนตัวเองกับผู้สังเกตการณ์ของรัฐ รูปแบบกลยุทธ์ให้ความรู้สึกคล้ายกับ Trigger และพฤติกรรม AI ของ Unity Engine ซึ่งใช้เพื่อแชร์พฤติกรรม btwn diff object เกม (ฉันคิดว่า) ฟังดูเป็นไปได้ ฉันไม่แน่ใจว่าสิ่งที่ข้อดี / ข้อเสียในขณะนี้ แต่ Unity ใช้วิธีเดียวกันก็ค่อนข้างมั่นใจฮ่าฮ่า ..
Cardin

ฉันใช้สองรูปแบบเหล่านี้สองสามครั้งดังนั้นฉันไม่สามารถบอกคุณเกี่ยวกับข้อเสีย: - / แต่ฉันคิดว่ามันดีในกรณีที่มีความรับผิดชอบเดียวและความพร้อมในการทดสอบทุกกลยุทธ์ :) อาจทำให้สับสนถ้าคุณ ใช้กลยุทธ์ในคลาสที่แตกต่างกันมากมายและคุณต้องการค้นหาทุกคลาสที่ใช้
TOAOGG

0

วิธีการทั้งหมดที่ให้มานั้นถูกต้อง ขึ้นอยู่กับสถานการณ์ที่คุณอยู่ ณ เวลาใดเวลาหนึ่ง การผจญภัยหรือ MMO จำนวนมากใช้การรวมกันของสิ่งเหล่านี้

เช่นหากเหตุการณ์สำคัญเปลี่ยนเป็นส่วนใหญ่ของระดับ (เช่นนักสะสมหนี้ชำระอพาร์ทเมนต์ของคุณและทุกคนในนั้นถูกจับกุม) มันมักจะง่ายกว่าที่จะแทนที่ห้องทั้งหมดด้วยห้องที่สองที่มีลักษณะคล้ายกัน

OTOH ถ้าตัวละครเดินไปรอบ ๆ แผนที่และทำสิ่งต่าง ๆ ในสถานที่ต่าง ๆ คุณมักจะมีนักแสดงคนเดียวที่หมุนผ่านวัตถุพฤติกรรมต่าง ๆ (เช่นเดินตรงไปข้างหน้า / ไม่มีการสนทนาเทียบกับที่นี่ / สนทนาเกี่ยวกับความตายของมิทช์) "ซ่อน" หากจุดประสงค์ของพวกเขาสำเร็จ

ที่กล่าวว่ามักจะมีรายการที่ซ้ำกันของวัตถุที่คุณสร้างด้วยตนเองไม่ควรทำให้เกิดปัญหาใด ๆ คุณสร้างวัตถุได้กี่ชิ้น หากคุณสามารถสร้างวัตถุได้มากกว่าเกมของคุณสามารถวนซ้ำดูที่คุณสมบัติ "ซ่อน" และข้ามไปเครื่องยนต์ของคุณช้าเกินไป ดังนั้นฉันจะไม่ต้องกังวลเกี่ยวกับเรื่องนั้นมากเกินไป เกมออนไลน์จำนวนมากทำเช่นนี้จริง ตัวละครหรือไอเท็มบางตัวนั้นอยู่ที่นั่นเสมอ แต่จะไม่ปรากฏให้กับตัวละครที่ไม่มีภารกิจที่เกี่ยวข้อง

คุณสามารถรวมวิธีการ: มีสองประตูในอาคารอพาร์ตเมนต์ของคุณ หนึ่งนำไปสู่พาร์ทเมนต์ "ก่อนที่จะเก็บหนี้" หนึ่งไปยังอพาร์ตเมนต์หลังจาก เมื่อคุณเข้าสู่ทางเดินจะแสดงเฉพาะสิ่งที่ตรงกับความก้าวหน้าของคุณในเรื่องเท่านั้น ด้วยวิธีนี้คุณสามารถมีกลไกทั่วไปสำหรับ "ไอเท็มปรากฏที่จุดปัจจุบันในเรื่องราว" และประตูที่มีปลายทางเดียว อีกวิธีหนึ่งคือคุณสามารถสร้างประตูที่ซับซ้อนมากขึ้นซึ่งอาจมีพฤติกรรมที่สามารถสลับออกมาได้และหนึ่งในนั้นคือ "ไปที่อพาร์ตเมนต์เต็ม" อีกห้องหนึ่งไปที่อพาร์ตเมนต์ว่างเปล่า สิ่งนี้อาจดูไร้สาระหากว่าเพียงแค่การเปลี่ยนแปลงปลายทางของประตู แต่ถ้าการเปลี่ยนแปลงนั้นมีลักษณะเช่นกัน (เช่นล็อคขนาดใหญ่ที่ด้านหน้าของประตูที่คุณต้องแตก)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.