Làm thế nào để bạn lưu trạng thái trò chơi?


27

Các thủ tục tiếp theo của các lập trình viên trò chơi để lưu và tiếp tục trạng thái trò chơi là gì? như tập tin / ánh xạ. Tôi muốn lưu nó cho trò chơi phòng thủ tháp và tôi đang sử dụng công cụ trò chơi unity3D.

Câu trả lời:


16

Nói chung, tôi không nghĩ về ảnh chụp nhanh bộ nhớ, nhưng tôi chỉ lập một danh sách các giá trị cần được lưu giữa các phiên và lưu các giá trị đó vào một tệp bên ngoài.

Tất nhiên điều này phụ thuộc vào nhu cầu của trò chơi cụ thể của bạn, nhưng thông thường tôi chỉ đơn giản là lưu trạng thái của cấp độ hiện tại (ví dụ: tất cả kẻ thù là gì, sức khỏe của chúng là gì, v.v.) và sau đó là cấp độ cao hơn như cấp độ của người chơi đã hoàn thành


3
+1 Đó là cách tôi làm. Tôi viết những gì tôi cần vào một tệp nhị phân. Và, nếu tôi cần thêm một cái gì đó mới, tôi thêm nó vào cuối để tôi không phá vỡ các tệp lưu cũ.
chaosTechnician

Đó là một mẹo hay về việc không phá vỡ các tệp lưu cũ, mặc dù việc thêm dữ liệu vào cuối không liên quan đến cách tôi lưu dữ liệu. Tôi làm điều đó bằng cách tuần tự hóa / giải tuần tự hóa một Từ điển và thứ tự không liên quan trong cấu trúc dữ liệu đó.
jhocking

(về cơ bản, mã trong câu trả lời của jonas, với Đối tượng của tôi là Từ điển)
jhocking

10

Câu trả lời này là Unity3d cụ thể .
Trong Unity, hầu hết các lớp đều được tuần tự hóa, điều này có nghĩa là bạn có thể truyền các đối tượng Unity hoàn chỉnh vào đĩa. Mã follity UnityScript-Code là một cách để tuần tự hóa một đối tượng, lưu nó vào đĩa để tải lại nó (sau khi tải, bạn phải truyền đối tượng):

import System;
import System.IO;
import System.IO.Stream;
import System.Runtime.Serialization;
import System.Runtime.Serialization.Formatters.Binary;

class SaveLoad {
        public static function SaveFile(filename:String, obj:Object):void {
                try {
                        Debug.Log("Writing Stream to Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Create);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        formatter.Serialize(fileStream, obj);
                        fileStream.Close();
                } catch(e:Exception) {
                        Debug.LogWarning("Save.SaveFile(): Failed to serialize object to a file " + filename + " (Reason: " + e.ToString() + ")");
                }
        }

        public static function LoadFile(filename:String):Object {
                try {
                        Debug.Log("Reading Stream from Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Open, FileAccess.Read);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        var obj:Object= formatter.Deserialize(fileStream);
                        fileStream.Close();
                        return obj;
                } catch(e:Exception) {
                        Debug.LogWarning("SaveLoad.LoadFile(): Failed to deserialize a file " + filename + " (Reason: " + e.ToString() + ")");
                        return null;
                }       
        }
}

2
Bên cạnh việc sử dụng C #, bạn cũng muốn sử dụng PlayerPrefs. Chúng là đa nền tảng, bạn không thể làm IO trên Web / iOS / Android. unity3d.com/support/documentation/ScriptReference/, (Mặc dù mẫu đẹp!)
TJHeuvel

PlayerPrefs kém linh hoạt hơn, chúng thực sự đa nền tảng và chúng hoàn hảo để lưu trữ các giá trị đơn lẻ hoặc không liên quan. Nhưng trên Windows PlayerPrefs được lưu trữ trong sổ đăng ký, bản rõ.
jonas

7
Nếu bạn đã tuần tự hóa, tại sao không tuần tự hóa nó thành Chuỗi và lưu trữ nó trong PlayerPrefs. Chắc chắn rằng nó kém linh hoạt, nhưng nó là giải pháp duy nhất cho một trò chơi đa nền tảng.
TJHeuvel

2
PlayerPrefs rất tốt để lưu trữ dữ liệu nhỏ như cài đặt, nhưng đối với toàn bộ các trò chơi lưu trữ, bạn nên sử dụng Application.persistentDataPath docs.unity3d.com/ScriptReference/,
jhocking

2
@TJHeuvel: "bạn không thể làm IO trên Web / iOS / Android" Bạn chắc chắn có thể làm IO trên thiết bị di động
Przemysław Wrzesiński

2

Đối với một TD tôi có thể tiết kiệm độc quyền giữa các sóng. Bằng cách đó, tất cả những gì bạn phải nghĩ là các tòa tháp. Đặt một số điểm lưu tự động trong các cấp độ, không quá 10 phút giữa, nhưng có lẽ ít hơn là tốt hơn.

Tất nhiên, nếu cấp độ của bạn đủ ngắn, bạn chỉ có thể không tiết kiệm được gì ngoài trạng thái chiến dịch.


1

Khi tôi đề cập đến trạng thái hiện tại của trò chơi, tôi đang đề cập đến ảnh chụp nhanh bộ nhớ tại thời điểm lưu. Bạn cần có khả năng tạo lại từ dữ liệu bạn sẽ lưu trữ trên ổ cứng.

Đơn giản nhất là chỉ cần tuần tự hóa tất cả các lớp của bạn có dữ liệu cần phải liên tục và kết xuất nó vào ổ cứng, về cơ bản thực hiện kết xuất bộ nhớ. Vấn đề với điều này là việc thay đổi các lớp của bạn sẽ thay đổi số lượng / loại giá trị được tuần tự hóa và phá vỡ các bản lưu cũ. Cũng bởi vì bạn đang lưu tất cả mọi thứ, nó làm tăng thời gian tải. Hiệu quả hơn để đánh dấu các trường riêng lẻ thực sự cần thiết để xây dựng lại "ảnh chụp nhanh bộ nhớ" hiện tại với bất kỳ hệ thống thuộc tính nào mà serializer / IDE của bạn sử dụng. Sau đó, xây dựng lại "ảnh chụp nhanh bộ nhớ" từ dữ liệu đã lưu đó.

Ngoài ra tôi chưa bao giờ sử dụng Unity trước đây vì vậy nó có thể có một cái gì đó được xây dựng. Tuy nhiên, đây là cách tiếp cận điển hình.


bạn có nghĩa là tôi phải lưu trữ các trạng thái của tôi trong một tập tin?
Syed

1
@ Có, vào cuối ngày, nó phải được ghi vào một loại tệp nào đó vì trạng thái ứng dụng sẽ không được lưu trong bộ nhớ. Với Unity cụ thể, bạn có thể sử dụng lớp PlayerPrefs (mà tôi nghĩ thực sự lưu trữ mọi thứ trong sổ đăng ký trên Windows) nếu bạn muốn tránh toàn bộ nội dung đọc / ghi tệp.
Tetrad
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.