Saya mengkodekan final saya untuk kursus Pemrograman video game, dan saya ingin tahu cara membuat file save untuk game saya, sehingga pengguna dapat bermain, dan kemudian kembali lagi. Tahu bagaimana hal ini dilakukan, setiap hal yang telah saya lakukan sebelumnya adalah program yang dijalankan tunggal.
c++
savegame
serialization
Tucker Morgan
sumber
sumber
Jawaban:
Anda perlu menggunakan serialisasi untuk menyimpan variabel Anda dalam memori ke hard drive Anda. Ada banyak jenis serialisasi, dalam. NET XML adalah format yang umum, meskipun ada serialisator biner dan JSON. Saya bukan programmer C ++, tetapi sebuah pencarian cepat menghasilkan contoh serialisasi dalam C ++:
There are libraries, that offer serializing functionalities. Some are mentioned in other answers.
The variables you will be interested in are going to probably be related to game state. For example, you will probably want to know this type of information
You wont really care what textures are being used (unless your player can change their appearance, that's a special case), because they are usually the same. You need to focus on saving important gamestate data.
When you start your game, you start as normal for a "new" game (this loads your textures, models, etc) but at appropriate time you load the values from your save file back into the game state object replacing the "default" new game state. Then you allow the player to resume playing.
I've greatly simplified it here, but you should get the general idea. If you have a more specific question ask a new question here and we can try to help you with it.
sumber
Typically this is specific to your game. I'm sure you've learned about writing to and reading from files in your classes so far. The basic idea is:
What you write is up to you, it depends on your game. One way of writing is to write out the variables you want in a specific order as a byte stream. Then when loading, read them in to your program in the same order.
For example (in quick pseudo code):
sumber
There are probably a large number of ways to do this, but the simplest that I always found and have used both personally and professionally is to make a structure that contains all of the values I want saved.
I then just fwrite/fread the data to and from a file using the basic File IO values. The inventoryCount is the number of Item structures that are saved after the main SaveGameData structure in the file so I know how many of those to read after fetching that data. The key here is that when I want to save something new, unless its a list of items or the like, all I have ever have to do is add a value to the structure some where. If its a list of items then I will have to add a read pass like I have already implied for the Item objects, a counter in the main header and then the entries.
This does have the downside of making different versions of a save file incompatible with each other with out special handling (even if it is just default values for each entry in the main structure). But overall this makes the system easy to extend just by adding in a new data value and putting a value into it when needed.
Again, quite a few ways to do this and this might lead more towards C than C++, but it has gotten the job done!
sumber
First you need to decide what data needs to be saved. For instance, this could be the location of the character, his score, and the number of coins. Of course, your game will likely be much more complex, and so you will need to save additional data such as the level number and enemy list.
Next, write code to save this to a file (use ofstream). A relatively simple format you can use is as follows:
And so the file would look like:
Which would mean he was at position (14, 96) with a score of 4200 and 100 coins.
You also need to write code to load this file (use ifstream).
Saving enemies can be done by including their position in the file. We can use this format:
First the
number_of_enemies
is read and then each position is read with a simple loop.sumber
One addition/suggestion would to add a level of encryption to your serialization so users cannot text edit their values to "9999999999999999999". One good reason to do this would be to prevent integer overflows (for example).
sumber
I think your best bet is boost::serialization because is easy to propagate down in your hierarchy. You only need to call the top object's save/load function and all your classes are easily created.
See: http://www.boost.org/doc/libs/1_49_0/libs/serialization/doc/index.html
sumber
For completeness sake I want to mention a c++ serialization library, that I personally use and was not mentioned yet: cereal.
It's easy to use and has a nice, clean syntax for serializing. It also offers multiple types of formats you can save to (XML, Json, Binary (including a portable version with respects endianess)). It supports inheritance and is header-only,
sumber
Your game will compromise data structures (hopefully?) that you need to transform into bytes (serialize) so you can store them. In a future, you may load those bytes back and transform them back into your original structure (deserialization). In C++ it is not so tricky since reflection is very limited. But still, some libraries can help you here. I wrote an article about it: https://rubentorresbonet.wordpress.com/2014/08/25/an-overview-of-data-serialization-techniques-in-c/ Basically, I would suggest you to have a look at cereal library if you may target C++ 11 compilers. No need to create intermediate files like with protobuf, so you will save some time there if you want quick results. You may also choose between binary and JSON, so it can quite help debugging here.
On top of that, if security is a concern, you may want to encrypt/decrypt the data you are storing, especially if you are using human-readable formats like JSON. Algorithms like AES are helpful here.
sumber
You need to use
fstream
for input / output files. The syntax is simple EX:Or
Other actions are possible on your file: append, binary, trunc, etc. You would use the same syntax as above instead we put std::ios::(flags), for instance:
ios::out
for output operationios::in
for input operationios::binary
for binary (raw byte) IO operation, instead of character-basedios::app
for to start to write at the end of the fileios::trunc
for if the file already exist replace delete the old content and replace by newios::ate
- position the file pointer "at the end" for input/outputEx:
Here is a more complete but simple example.
sumber
goto
s, you'll get lynched on the public place. Don't usegoto
s.