ebSkola

5.6 Noslēguma projekts: Procedurālais klases labirints

Stundas uzdevums: Pilnvērtīga procedurālā klases labirinta spēle ar procedural generation, save sistēmu un meta-progress.

SR 2.4.1. Problēmu dekompozīcija SR 2.4.16. Datu struktūras SR 2.4.17. Failu I/O SR 2.4.19. Algoritmi

80 min plāns: Ievads un kritēriju pārruna (~10 min) · 1. uzdevums (~20 min) - savieno labirintu ar spēlētāju · 2. uzdevums (~25 min) - pievieno savācamos un šķēršļus · 3. uzdevums (~20 min) - pievieno meta-progresu un saglabāšanu · Iesniegšana (~5 min).

Pirms sāc: šis ir 5. tēmas noslēguma projekts. Izmanto 5.4 labirinta ģeneratoru un 5.3 saglabāšanas sistēmu. Sāc ar TRIM līmeņiem, nevis desmit.

Teorija: Spēles apraksts

Procedurālais klases labirints: spēlētājs iziet cauri nejauši ģenerētiem labirintiem, savāc bonusa materiālus, risina šķēršļus, kļūdas gadījumā zaudē konkrētā mēģinājuma progresu (run), bet meta-progress (kopējie XP, atklātās klases) saglabājas.

Galvenās funkcijas:

  • Procedurāli ģenerēti 10 līmeņu labirinti.
  • 3 spēlētāja klases ar dažādām spējām.
  • 50+ materiālu un šķēršļu tipi.
  • Fināla izaicinājums katram 5. līmenim.
  • Save/load starp sesijām (meta-progress).
  • Procedurāla bonusa materiālu ģenerēšana.

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.6 Noslēguma projekts: Procedurālais klases labirints";
    public bool UsesCSharp = true;
    public bool HandlesMissingFile = true;
    public bool ValidatesData = true;
    public bool DocumentsComplexity = true;
}

Praktiskie uzdevumi

1. uzdevums -

Savieno labirintu ar spēlētāju

Beigās varēsi iziet uzģenerētu labirintu un nokļūt nākamajā.

  1. Ievelc savu 5.4 labirinta ģeneratoru jaunā projektā vai scēnā.
  2. Novieto spēlētāju labirinta sākumā un izeju tālākajā stūrī.
  3. Pievieno izejai Area2D, kas nosaka, ka līmenis pabeigts.
  4. Uzģenerē jaunu labirintu, kad spēlētājs sasniedz izeju.
  5. Pievieno līmeņa numura skaitītāju un parādi to ekrānā.
  6. Izej trīs līmeņus pēc kārtas.
  7. Pārbaudi, ka katrs jaunais labirints ir citāds un izejams.

Gatavs, kad: izejot izeju, uzreiz sākas jauns, atšķirīgs labirints, un numurs ekrānā pieaug.

2. uzdevums -

Pievieno savācamos un šķēršļus

Beigās labirintā būs par ko cīnīties un no kā izvairīties.

  1. Izvieto labirintā nejaušās ejās vismaz piecus savācamos materiālus.
  2. Pievieno katram Area2D, kas palielina XP skaitītāju.
  3. Izvieto arī divus šķēršļus, kas atņem mēģinājumam dzīvību.
  4. Pārliecinies, ka objekti nekad nerodas sienā.
  5. Pievieno HUD ar XP, dzīvībām un līmeņa numuru.
  6. Izspēlē līmeni un savāc visus materiālus.
  7. Pārbaudi, ka pēc dzīvību zaudēšanas mēģinājums beidzas.

Gatavs, kad: visi savācamie ir sasniedzami, neviens nav iesprūdis sienā, un HUD rāda pareizus skaitļus.

3. uzdevums -

Pievieno meta-progresu un saglabāšanu

Beigās tavs progress saglabāsies arī pēc neveiksmīga mēģinājuma.

  1. Sadali datus divās daļās: mēģinājuma dati un pastāvīgie dati.
  2. Pievieno pastāvīgajiem datiem kopējo XP un labāko sasniegto līmeni.
  3. Saglabā tos JSON failā ar 5.3 stundas SaveManager.
  4. Nomet pēc zaudējuma tikai mēģinājuma datus.
  5. Ielādē pastāvīgos datus, palaižot spēli no jauna.
  6. Izspēlē divus mēģinājumus un pārbaudi, ka kopējais XP summējas.
  7. Veic commit un push.

Gatavs, kad: pēc zaudējuma un spēles restarta kopējais XP saglabājas, bet mēģinājuma progress sākas no sākuma.

Papildu uzdevums - Pievieno spēlētāja klases

Ja pamatdarbs ir gatavs, ļauj izvēlēties varoni ar savu spēju.

  1. Izveido bāzes klasi ar kopīgajām īpašībām.
  2. Izveido divas bērna klases ar atšķirīgu ātrumu un dzīvību skaitu.
  3. Pievieno spēles sākumā izvēlni ar abām klasēm.
  4. Saglabā izvēlēto klasi pastāvīgajos datos.
  5. Izspēlē mēģinājumu ar katru klasi un salīdzini.

Gatavs, kad: abas klases jūtas atšķirīgi, un izvēle saglabājas arī pēc spēles restarta.

Ko sagatavo

Stundas mērķis: Tev ir izspēlējams procedurālais labirints: katrs līmenis tiek uzģenerēts un pārbaudīts, ka ir izejams, labirintā ir savācamie un šķēršļi, un kopējais progress saglabājas JSON failā arī pēc neveiksmīga mēģinājuma.

GitHub krātuvē jābūt:

  1. Viss projekts ar C# skriptiem, scēnām un projekta failiem.
  2. README.md ievietota video saite, kurā izej vismaz divus līmeņus un savāc materiālus.
  3. Saglabātā JSON faila paraugs ar meta-progresa datiem.
  4. README.md: kuri dati tavā spēlē ir mēģinājuma dati un kuri pastāvīgie, un kāpēc.

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

  • Save un mēģinājuma beigas: Pārbaudi, ka delete save fails notiek tikai pēc run_end, ne pirms.
  • Performance ar 50+ šķēršļiem: Lieto spatial hash un pool no 4. tēmas.
  • Procedural balance: Pārāk daudz/maz bonusa materiālu - pielāgo varbūtības.

Godot ekrānuzņēmumi

Procedurālais klases labirints spēles aina: top-down labirints ar pelēkām sienām, spēlētājs centrā, 3 šķēršļi, bonusu kaste un eja uz nākamo līmeni.
Procedurālais klases labirints spēles aina: top-down labirints ar pelēkām sienām, spēlētājs centrā, 3 šķēršļi, bonusu kaste un eja uz nākamo līmeni.
Meta-progress menu: 'Atrisināti uzdevumi: 1247', 'Deepest level: 7', 'Classes unlocked: 2/3', 'Best run: Level 8 (Kapteinis)'.
Meta-progress menu: 'Atrisināti uzdevumi: 1247', 'Deepest level: 7', 'Classes unlocked: 2/3', 'Best run: Level 8 (Kapteinis)'.

Koda piemērs (paplašināts)

using Godot;

public partial class GameSession : Node
{
    private int currentLevel = 1;
    private Player player;
    private MazeGenerator generator = new();

    public void StartRun()
    {
        generator.Generate((int)Time.GetUnixTimeFromSystem());
        SpawnPlayer();
        SpawnObstacles();
        SpawnBonusItems();
    }

    public void OnRunFailed()
    {
        // Save meta-progress
        MetaProgress.Instance.AddRun(currentLevel, player.SolvedTasks);
        MetaProgress.Save();
        // Remove run save
        DirAccess.RemoveAbsolute("user://current_run.json");
        GetTree().ChangeSceneToFile("res://menu.tscn");
    }

    public void OnLevelComplete()
    {
        SaveRun();  // autosave
        currentLevel++;
        if (currentLevel > 10) OnGameWon();
        else StartNextLevel();
    }
}
Pilnvērtīgs procedurālais klases labirints: 10 līmeņi, save/load, procedural generation, meta-progress, fināla izaicinājums.