ebSkola

5.1 Failu I/O Godot vidē

Stundas uzdevums: Apgūt FileAccess klasi un Godot failu sistēmu.

SR 2.4.17. Failu un ārējās krātuves SR 2.4.4. Iegūst un apstrādā datus

80 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~20 min) - ieraksti un nolasi failu · 2. uzdevums (~25 min) - saglabā spēles rezultātu · 3. uzdevums (~20 min) - apstrādā trūkstošu failu · Iesniegšana (~5 min).

Pirms sāc: atceries no Programmēšanas I failu darbu: with open("dati.txt", "w"). Godot to dara FileAccess klase. Galvenais jaunums: ceļš user://, nevis parasta mape.

Teorija: FileAccess klase

Godot piedāvā FileAccess klasi failu lasīšanai un rakstīšanai. Tā strādā ar res:// (read-only resources) un user:// (lokālā lietotāja krātuve).

using Godot;

// Rakstīšana
using FileAccess file = FileAccess.Open("user://save.txt", FileAccess.ModeFlags.Write);
if (file != null)
{
    file.StoreString("Hello, file!");
    file.StoreLine("Otrā rinda");
    file.Store32(42);  // binary
}

// Lasīšana
using FileAccess readFile = FileAccess.Open("user://save.txt", FileAccess.ModeFlags.Read);
if (readFile != null)
{
    string content = readFile.GetAsText();
    // vai pa rindām:
    while (!readFile.EofReached())
    {
        string line = readFile.GetLine();
    }
}

Kā šo izmantot projektā

Atceries: ar redzamu efektu editorā nepietiek. Paskaidro, kura C# klase glabā stāvokli, kura metode to maina un kā Godot node struktūra izmanto šo kodu.

Pārbaudi: C# kods pārbauda failu kļūdas, validē datus, izmanto versijas lauku un pamato algoritmu sarežģītību.

public class PersistenceCheckpoint
{
    public string Lesson = "5.1 Failu I/O Godot vidē";
    public bool UsesCSharp = true;
    public bool HandlesMissingFile = true;
    public bool ValidatesData = true;
    public bool DocumentsComplexity = true;
}

Praktiskie uzdevumi

1. uzdevums -

Ieraksti un nolasi failu

Beigās tava spēle pratīs saglabāt tekstu diskā.

  1. Pārliecinies, ka faila sākumā ir using Godot;.
  2. Atver failu ar using FileAccess f = FileAccess.Open("user://save.txt", FileAccess.ModeFlags.Write);.
  3. Pārbaudi if (f != null) pirms rakstīšanas.
  4. Ieraksti tekstu ar f.StoreString("Sveiks, fails!");.
  5. Atver failu no jauna režīmā Read un nolasi ar GetAsText().
  6. Izdrukā nolasīto tekstu.
  7. Atrodi failu diskā: Godot izvēlnē Project -> Open User Data Folder.

Gatavs, kad: Output panelī izdrukājas tas pats teksts, ko ierakstīji, un fails ir atrodams user data mapē.

2. uzdevums -

Saglabā spēles rezultātu

Beigās rezultāts saglabāsies arī pēc spēles aizvēršanas.

  1. Izveido klasi SaveManager ar metodi public void SaveScore(int score).
  2. Ieraksti failā rezultātu ar file.Store32((uint)score);.
  3. Uzraksti metodi public int LoadScore(), kas to nolasa ar (int)file.Get32().
  4. Izsauc saglabāšanu ar vērtību 150.
  5. Aizver spēli pilnībā un palaid no jauna.
  6. Izdrukā ielādēto rezultātu.
  7. Pieraksti, kāpēc user:// ir labāks par res:// saglabāšanai.

Gatavs, kad: pēc spēles aizvēršanas un atvēršanas ielādētais rezultāts joprojām ir 150.

3. uzdevums -

Apstrādā trūkstošu failu

Beigās pirmā spēles palaišana vairs neradīs kļūdu.

  1. Izdzēs saglabāto failu no user data mapes.
  2. Palaid spēli un pieraksti, kas notiek ar LoadScore().
  3. Pievieno pārbaudi if (!FileAccess.FileExists("user://save.txt")).
  4. Atgriez tādā gadījumā noklusējuma vērtību 0.
  5. Palaid vēlreiz ar izdzēstu failu un pārbaudi rezultātu.
  6. Saglabā jaunu rezultātu un pārbaudi, ka tas ielādējas.
  7. Pieraksti, ar ko šī pārbaude līdzinās Python FileNotFoundError apstrādei.

Gatavs, kad: ar izdzēstu failu spēle rāda rezultātu 0 un neizmet kļūdu.

Papildu uzdevums - Saglabā vairākas vērtības

Ja pamatdarbs ir gatavs, saglabā visu spēlētāja stāvokli.

  1. Papildini saglabāšanu ar HP, līmeni un spēlētāja vārdu.
  2. Ieraksti tos noteiktā secībā ar Store32 un StoreString.
  3. Nolasi tos TIEŠI tādā pašā secībā.
  4. Samaini apzināti divas nolasīšanas rindas vietām un palaid.
  5. Pieraksti, kāpēc secība ir tik svarīga.

Gatavs, kad: visas vērtības ielādējas pareizi, bet, samainot nolasīšanas secību, dati sajūk.

Ko sagatavo

Stundas mērķis: Tava spēle saglabā rezultātu failā user:// mapē, ielādē to pēc restarta un neizmet kļūdu, ja saglabāšanas faila vēl nav.

GitHub krātuvē jābūt:

  1. Fails SaveManager.cs.
  2. Divi ekrānuzņēmumi: rezultāts pēc saglabāšanas un tas pats rezultāts pēc spēles restarta.
  3. README.md: ar ko user:// atšķiras no res:// un kā tu apstrādāji trūkstošu failu.

Kā iesniedz: Veic commit un push. Skolotāja norādītajā vietā ievieto tikai GitHub krātuves saiti; visiem prasītajiem failiem, README.md pierakstiem un pierādījumiem jābūt pašā krātuvē.

Biežākās kļūdas

  • file is null: Permission denied vai path nepareizs.
  • Encoding errors: UTF-8 ir noklusējuma, bet pārbaudi ar speciāliem simboliem.
  • res:// ir read-only: Production buildos to nevar rakstīt - lieto user://.

Godot ekrānuzņēmumi

Failu pārvaldnieks ar user:// mapes saturu - redzams test.txt, savegame.json un highscore.dat.
Failu pārvaldnieks ar user:// mapes saturu - redzams test.txt, savegame.json un highscore.dat.

Koda piemērs (paplašināts)

using Godot;

public partial class SaveSystem : Node
{
    public void SaveText(string filename, string content)
    {
        string path = "user://" + filename;
        using FileAccess file = FileAccess.Open(path, FileAccess.ModeFlags.Write);
        if (file != null)
        {
            file.StoreString(content);
            GD.Print("Saglabāts: ", path);
        }
        else
        {
            GD.PrintErr("Neizdevās atvērt: ", path);
        }
    }

    public string LoadText(string filename)
    {
        string path = "user://" + filename;
        if (!FileAccess.FileExists(path)) return "";

        using FileAccess file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
        return file != null ? file.GetAsText() : "";
    }
}
Saglabā 'Mans pirmais save!' failā un to atjauno; user:// mapē redzams test.txt.