วิธีที่ดีที่สุดในการจัดเก็บตัวแปรทั่วทั้งเกม


23

ฉันมีหน้าจอตัวเลือกสำหรับสิ่งต่าง ๆ เช่นความยากลำบากความละเอียดเต็มหน้าจอ ฯลฯ แต่ฉันพยายามหาวิธีที่ดีที่สุดในการจัดเก็บ / รับตัวแปรเหล่านี้ในเวลาทำงาน

ขณะนี้ฉันได้ใช้Constantsคลาสที่มีGameOptionenums ทั้งหมดแต่ฉันจะเลือกค่าเริ่มต้นสำหรับตัวเลือกทั้งหมดเหล่านี้ได้อย่างไร นอกจากนี้ฉันจะรับ Enum ที่เลือกในปัจจุบันได้อย่างไร

เกี่ยวกับความละเอียดโดยเฉพาะฉันได้ตัดสินใจที่จะเก็บค่า แต่ฉันไม่แน่ใจว่าจะได้รับค่าเริ่มต้นหรือค่าที่เก็บไว้ในปัจจุบัน ทิศทางใดก็จะดี ขอบคุณ! :)

namespace V1.test.RPG
{
  public class GameOptions
  {
    public enum Difficulty { EASY, MEDIUM, HARD }
    public enum Sound { ON, QUIET, OFF }
    public enum Music { ON, QUIET, OFF }
    public enum ResolutionWidth
    {
        SMALL      = 1280,
        MEDIUM     = 1366,
        LARGE      = 1920,
        WIDESCREEN = 2560
    }
    public enum ResolutionHeight
    {
        SMALL      = 800,
        MEDIUM     = 768,
        LARGE      = 1080,
        WIDESCREEN = 1080
    }
    public Boolean fullScreen = false;
  }
}

NB: ฉันถามไปที่ SOและพวกเขาชี้ให้ฉันไปที่นี่ มีความคิดเห็นอยู่ที่นั่น แต่ฉันต้องการที่จะได้ยินวิธีที่แตกต่างของการทำมัน / วิธีที่ใช้มากที่สุด


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

ฉันเพิ่งอ่านเธรด SO; ฉันชอบคำตอบของ Scott Chamberlin
jhocking

@ จ๊อคกิ้งฉันชี้ให้เขาเห็นอย่างนี้ในกรณีที่มีแง่มุมใดเป็นพิเศษสำหรับการพัฒนาเกมที่อาจแตกต่างจากแอปพลิเคชันทั่วไป ฉันคิดว่าพวกคุณอาจมีคำถามและคำตอบที่ยอมรับได้ในหัวข้อนี้เนื่องจากเป็นเรื่องธรรมดา
Chris Hayes

เป็นไปตามคำถามที่เกิดขึ้นจริงเกี่ยวกับกลมโปรดอย่าสันนิษฐานว่ามีการแก้ปัญหาที่แน่นอน
Lars Viklund

คำตอบ:


32

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

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

หากต้องการแสดงให้เห็นแนวคิดอีกเล็กน้อยรหัสเทียมต่อไปนี้เป็นตัวอย่างง่าย ๆ ของประเภท CVAR ที่ตัดintค่า:

// just some flags to exemplify:
enum CVarFlags {
    CVAR_PERSISTENT, // saved to file once app exits
    CVAR_VOLATILE    // never saved to file
};

class CVar {
public:
    // the constructor registers this variable with the global list of CVars
    CVar(string name, int value, int defaultValue, int flags);

    int getValue();
    void setValue(int v);
    void reset(); // reset to the default value

    // etcetera...

private:
    int flags; // flags like: save-to-file, etc.
    int value; // the actual value
    int defaultValue; // the default value to reset the variable to
};

// global list of all CVars:
map<string, CVar> g_cvars;

การเข้าถึงระดับโลก:
ในตัวอย่างด้านบนฉันได้สมมติว่าตัวสร้างของการCVarลงทะเบียนตัวแปรกับcvarsแผนที่โลกเสมอ สิ่งนี้มีประโยชน์มากเพราะช่วยให้คุณสามารถประกาศตัวแปรดังนี้:

CVar my_var = new CVar("my_var", 0, 42, CVAR_PERSISTENT);

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

CVar v = g_cvars.find("my_var");

ความคงทน:
เมื่อเกมปิดตัวเองให้ทำซ้ำแผนที่และบันทึกตัวแปรทั้งหมดที่ทำเครื่องหมายเป็นCVAR_PERSISTENTไฟล์ ในครั้งต่อไปที่เกมเริ่มต้นให้โหลดซ้ำ

กรณีกฎหมาย:
สำหรับตัวอย่างเพิ่มเติมที่เฉพาะเจาะจงของระบบ CVAR แข็งแกร่งให้ตรวจสอบการดำเนินงานที่โดดเด่นในวาระ 3


4

อย่างแรกออกกำหนด enum สิ่งที่ค่าที่สามารถจะไม่ใช่สิ่งที่ค่าที่มี ดังนั้นคุณยังจำเป็นต้องประกาศตัวแปรอื่นหลังจากที่คุณประกาศ enum ตัวอย่างเช่น:

public enum Sound
{
    ON,
    QUIET,
    OFF
}

public Sound soundValue;

ในตัวอย่างนี้คุณสามารถตั้งค่าsoundValueเป็นเปิด, แบบทดสอบ, หรือปิด


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


1

โซลูชัน glampert นั้นสมบูรณ์มาก แต่ฉันจะเพิ่มประสบการณ์ส่วนตัวของฉัน

ฉันพบปัญหาเดียวกันนี้และวิธีแก้ปัญหาของฉันคือใช้คลาสตัวแปรแบบคงที่

ชั้นตัวแปรภายในเก็บแผนที่จากสตริงไปยังสตริง (จนถึงตัวแปรทั้งหมดของฉันเป็นเพียงสตริง) และเข้าถึงได้ผ่าน getters และ setters

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

เพื่อหลีกเลี่ยงสิ่งนี้ฉันได้กำหนดซีแมนทิกส์ต่อไปนี้: การใช้setเมธอดจะส่งข้อยกเว้นหากตัวแปรที่มีชื่อนั้นมีอยู่แล้วในพจนานุกรมและgetลบตัวแปรออกจากพจนานุกรมก่อนที่จะส่งคืน

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

เพื่อเริ่มต้นพจนานุกรมตัวแปรเริ่มต้นจะถูกเก็บไว้ในไฟล์ json แล้วอ่านเมื่อเกมเริ่ม

น่าเศร้าที่ฉันยังไม่ได้ไกลเกินไปกับเกมของฉันดังนั้นฉันจึงไม่สามารถเป็นพยานถึงความแข็งแกร่งของวิธีการนี้ ถึงกระนั้นก็อาจให้บางสิ่งที่น่าสนใจบน CVARs

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