To store the player's name along with the score, you'll need to define a structure that holds both the name and the score. You'll also need to decide on a format for storing this data in the file.
Let’s see an example. First, we’ll define a structure:
#include <SDL.h>
#include <iostream>
#include <algorithm>
#include <string>
struct ScoreEntry {
int32_t Score;
// Assuming a maximum name length
// of 49 characters + null terminator
char Name[50];
};
Next, let’s modify UpdateHighScore()
:
void UpdateHighScore(
const char* Path, const ScoreEntry& NewEntry
) {
SDL_RWops* File{SDL_RWFromFile(Path, "w+b")};
if (!File) {
std::cerr << "Error opening file: "
<< SDL_GetError() << "\n";
return;
}
const int NumScores{5};
ScoreEntry HighScores[NumScores];
size_t EntriesRead{SDL_RWread(
File, HighScores,
sizeof(ScoreEntry),
NumScores
)};
if (EntriesRead < NumScores) {
std::cout << "Initializing new high scores\n";
for (size_t i{EntriesRead}; i<NumScores; ++i) {
HighScores[i].Score = 0;
// Initialize name to an empty string
HighScores[i].Name[0] = '\0';
}
}
bool IsHighScore{false};
for (int i{0}; i < NumScores; ++i) {
if (NewEntry.Score > HighScores[i].Score) {
IsHighScore = true;
break;
}
}
if (IsHighScore) {
std::cout << NewEntry.Name
<< " achieved a new high score of "
<< NewEntry.Score
<< "! Updating file\n";
HighScores[NumScores - 1] = NewEntry;
std::sort(HighScores, HighScores + NumScores,
[](const ScoreEntry& a, const ScoreEntry& b) {
return a.Score > b.Score;
});
SDL_RWseek(File, 0, RW_SEEK_SET);
SDL_RWwrite(
File, HighScores,
sizeof(ScoreEntry), NumScores
);
} else {
std::cout << "Not a high score - "
"file not updated\n";
}
SDL_RWclose(File);
}
int main() {
ScoreEntry ScoreOne{500, "Noob"};
UpdateHighScore("highscores.dat", ScoreOne);
ScoreEntry ScoreTwo{5000, "Alice"};
UpdateHighScore("highscores.dat", ScoreTwo);
ScoreEntry ScoreThree{3000, "Bob"};
UpdateHighScore("highscores.dat", ScoreThree);
ScoreEntry ScoreFour{6000, "Charlie"};
UpdateHighScore("highscores.dat", ScoreFour);
ScoreEntry ScoreFive{4000, "David"};
UpdateHighScore("highscores.dat", ScoreFive);
ScoreEntry ScoreSix{5500, "Eve"};
UpdateHighScore("highscores.dat", ScoreSix);
return 0;
}
Initializing new high scores
Noob achieved a new high score of 500! Updating file
Alice achieved a new high score of 5000! Updating file
Bob achieved a new high score of 3000! Updating file
Charlie achieved a new high score of 6000! Updating file
David achieved a new high score of 4000! Updating file
Eve achieved a new high score of 5500! Updating file
ScoreEntry
struct to hold the player's name and score.char Name[50]
) for the name, assuming a maximum length of 49 characters (plus the null terminator).UpdateHighScore()
, we now read and write an array of ScoreEntry
structs.Name
field to an empty string.NewEntry
to the HighScores
array and sort the array based on the Score
member using a lambda function for comparison.HighScores
array back to the file.This example demonstrates a basic way to store both the player's name and score in the high score file. You can adapt this approach to handle more complex data structures or use different file formats based on your specific needs.
Answers to questions are automatically generated and may not have been reviewed.
Learn how to manipulate the read/write offset of an SDL_RWops
object to control stream interactions.