Cách tốt nhất để lưu trữ các biến toàn trò chơi


23

Tôi có một màn hình tùy chọn cho những thứ như độ khó, độ phân giải, toàn màn hình, v.v., nhưng tôi đang loay hoay tìm cách "tốt nhất" để lưu trữ / thu được các biến này trong thời gian chạy.

Hiện tại, tôi đã triển khai một Constantslớp có chứa tất cả các GameOptionenum, nhưng làm cách nào để chọn mặc định cho tất cả các tùy chọn này? Ngoài ra, làm thế nào để tôi có được enum hiện được chọn?

Về độ phân giải, cụ thể, tôi đã quyết định lưu trữ các giá trị, nhưng tôi không chắc chắn làm thế nào để có được các giá trị mặc định hoặc hiện được lưu trữ. Bất kỳ hướng nào sẽ là tuyệt vời; cảm ơn! :)

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: Tôi đã hỏi tại SO và họ chỉ tôi đến nơi này. Có một nhận xét ở đó nhưng tôi muốn nghe những cách khác nhau để làm điều đó / những cách được sử dụng nhiều nhất.


1
Bạn hỏi đúng chỗ; bất cứ ai gửi bạn qua đây đều bị nhầm lẫn. Dù sao tôi cũng đã trả lời câu hỏi để giúp bạn, nhưng đây không phải là câu hỏi cụ thể về phát triển trò chơi, đây là câu hỏi lập trình chung.
jhocking

Tôi chỉ đọc chủ đề SO; Tôi thích câu trả lời của Scott Chamberlin.
jhocking

@jhocking Tôi đã chỉ cho anh ấy theo cách này trong trường hợp có bất kỳ khía cạnh nào đặc biệt cho phát triển trò chơi có thể khác với một ứng dụng thông thường. Tôi cũng hình dung các bạn có thể đã có một câu hỏi và trả lời kinh điển về chủ đề này vì nó rất phổ biến.
Chris Hayes

Tiếp theo câu hỏi thực tế về toàn cầu, xin đừng cho rằng có một bộ nghị quyết cố định ngoài kia.
Lars Viklund

Câu trả lời:


32

Lập kế hoạch để phát triển:
Các hằng số được mã hóa tốt là tốt cho các dự án nhỏ, nhưng cuối cùng, khi phần mềm của bạn tăng kích thước, bạn sẽ ước mình có thể thay đổi các cài đặt đó mà không phải biên dịch lại mọi thứ. Có nhiều lần bạn sẽ muốn thay đổi cài đặt trong khi trò chơi đang chạy và bạn không thể làm điều đó với các hằng số được mã hóa cứng.

CVars:
Khi dự án của bạn phát triển, bạn có thể muốn xem CVAR . CVAR là một "biến thông minh", có thể nói, bạn có thể sửa đổi trong thời gian chạy thông qua bảng điều khiển, thiết bị đầu cuối hoặc giao diện người dùng. CVAR thường được triển khai dưới dạng đối tượng bao bọc một giá trị cơ bản. Sau đó, đối tượng có thể theo dõi giá trị cũng như lưu / tải nó vào / từ tệp. Bạn có thể lưu trữ các đối tượng CVAR vào bản đồ để truy cập chúng bằng tên hoặc mã định danh duy nhất khác.

Để minh họa khái niệm xa hơn một chút, mã giả sau đây là một ví dụ đơn giản về loại CVAR bao bọc một intgiá trị:

// 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;

Truy cập toàn cầu:
Trong ví dụ trên, tôi đã giả định rằng nhà xây dựng CVarluôn đăng ký biến với cvarsbản đồ toàn cầu ; Điều này khá hữu ích, vì nó cho phép bạn khai báo một biến như vậy:

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

Biến đó được tự động cung cấp trong bản đồ toàn cầu và bạn có thể truy cập nó từ bất kỳ nơi nào khác bằng cách lập chỉ mục bản đồ với tên của biến:

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

Kiên trì:
Khi trò chơi đang tắt, lặp lại bản đồ và lưu tất cả các biến được đánh dấu là CVAR_PERSISTENT, vào một tệp. Lần tiếp theo trò chơi bắt đầu, tải lại chúng.

Trường hợp pháp luật:
Để biết ví dụ cụ thể hơn về hệ thống CVAR mạnh mẽ, hãy xem triển khai được nêu trong Doom 3 .


4

Trước hết, một enum xác định giá trị có thể là gì, không phải giá trị là gì . Do đó, bạn vẫn cần khai báo một biến khác sau khi bạn đã khai báo enum. Ví dụ:

public enum Sound
{
    ON,
    QUIET,
    OFF
}

public Sound soundValue;

Trong ví dụ này, bây giờ bạn có thể đặt soundValuethành BẬT, QUIET hoặc TẮT.


Sau đó, bạn vẫn cần cấu trúc mã của mình để các phần khác trong mã của bạn có thể truy cập vào đối tượng "cài đặt" này. Tôi không biết nếu bạn cũng cần trợ giúp với phần đó, nhưng các mô hình phổ biến để giải quyết vấn đề này bao gồm những người độc thân (những người đang nhăn mặt vào những ngày này) hoặc người định vị dịch vụ hoặc tiêm phụ thuộc.


1

Giải pháp glampert rất đầy đủ, nhưng tôi sẽ thêm kinh nghiệm cá nhân của tôi.

Tôi gặp vấn đề tương tự, và giải pháp của tôi là sử dụng một lớp Biến tĩnh.

Lớp Biến trong nội bộ giữ một bản đồ từ chuỗi này sang chuỗi khác (cho đến nay tất cả các biến của tôi chỉ là các chuỗi) và được truy cập thông qua getters và setters.

Vấn đề là việc truy cập vào các biến toàn cục có thể đưa ra tất cả các loại lỗi tinh vi vì các phần hoàn toàn không liên quan của mã đang đột nhiên can thiệp lẫn nhau.

Để tránh điều này, tôi đã áp đặt các ngữ nghĩa sau: sử dụng setphương thức đưa ra một ngoại lệ nếu một biến có tên đó đã tồn tại trong từ điển và getxóa biến đó khỏi từ điển trước khi trả lại.

Hai phương pháp bổ sung cung cấp những gì bạn mong đợi, setAndOverwritegetAndKeep. Điểm của ngữ nghĩa của các phương thức khác là bạn có thể dễ dàng phát hiện ra các lỗi thuộc loại "phương pháp này được cho là khởi tạo biến này, nhưng phương thức khác đã làm điều đó trước đây".

Để khởi tạo từ điển, các biến ban đầu được lưu trữ trong tệp json, sau đó đọc khi trò chơi bắt đầu.

Đáng buồn là tôi đã không đi quá xa với trò chơi của mình nên tôi không thể làm chứng cho sự mạnh mẽ của phương pháp này. Tuy nhiên, có lẽ nó có thể cung cấp một cái gì đó thú vị trên đầu CVAR.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.