4.1 List un Array
Stundas uzdevums: Saprast atšķirību starp C# List<T> un Godot Array, izvēlēties piemēroto datu struktūru.
80 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~20 min) - izveido ienaidnieku sarakstu ar List<T> · 2. uzdevums (~25 min) - pievieno un izņem elementus droši · 3. uzdevums (~20 min) - salīdzini List<T> ar Godot Array · Iesniegšana (~5 min).
Pirms sāc: atceries no Programmēšanas I sarakstus: materiali.append("x") un materiali.pop(0). C# tas pats parasti ir List<T>, ar Add() un RemoveAt().
Teorija: Sarakstu datu struktūras
Godot C# kontekstā ir divas saraksta opcijas:
| Tips | Lietojums | Piemērs |
|---|---|---|
List<T> | Iekšējais C# kods, tipa-drošs | List<Enemy> enemies = new(); |
Godot.Collections.Array | Komunikācijai ar Godot | Array bullets = new(); |
Godot.Collections.Array<T> | Tipa-droša Godot Array | Godot.Collections.Array<Bullet> bullets = new(); |
using Godot;
using Godot.Collections;
using System.Collections.Generic;
List<Enemy> enemies = new();
enemies.Add(new Enemy());
foreach (Enemy enemy in enemies) enemy.UpdateEnemy();
enemies.RemoveAt(2); // dzēš 3.
// Godot Array
Array bullets = new();
bullets.Add(newBullet);
bullets.Count;
bullets.RemoveAt(bullets.Count - 1);
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# kodā pamatoti izvēlēti List, Dictionary vai HashSet, AI stāvokļi ir skaidri, un sarežģītākas sistēmas var profilēt vai atkļūdot.
public class AiDataCheckpoint
{
public string Lesson = "4.1 List un Array";
public bool UsesCSharp = true;
public bool ChoosesContainer = true;
public bool SeparatesAiState = true;
public bool HandlesRemovalSafely = true;
}
Praktiskie uzdevumi
1. uzdevums -
Izveido ienaidnieku sarakstu ar List
Beigās viens mainīgais glabās visus ienaidniekus.
- Pievieno faila sākumā
using System.Collections.Generic;. - Pievieno klasei lauku
private List<Enemy> enemies = new();. - Pievieno trīs ienaidniekus ar
enemies.Add(enemy);. - Izdrukā to skaitu ar
enemies.Count. - Uzraksti ciklu
foreach (Enemy enemy in enemies) { ... }, kas izdrukā katra nosaukumu. - Pievieno ceturto ienaidnieku un palaid vēlreiz.
- Pārbaudi, vai cikls bija jāmaina.
Gatavs, kad: cikls izdrukā visus ienaidniekus, un pievienojot ceturto, kods nav jāmaina.
2. uzdevums -
Pievieno un izņem elementus droši
Beigās tu zināsi, kāpēc sarakstu nedrīkst mainīt cikla laikā.
- Izņem otro elementu ar
enemies.RemoveAt(1);. - Izdrukā saraksta izmēru pirms un pēc izņemšanas.
- Mēģini piekļūt elementam
enemies[10]un pieraksti, kas notiek. - Nomaini to uz
if (index >= 0 && index < enemies.Count)pārbaudi un salīdzini rezultātu. - Uzraksti ciklu, kas cikla iekšpusē mēģina izdzēst elementu, un palaid to.
- Pārraksti to tā, lai dzēšamos vispirms savāktu otrā sarakstā.
- Pieraksti, kāpēc pirmais variants ir bīstams.
Gatavs, kad: saraksta izmērs pēc dzēšanas ir par vienu mazāks, un droši dzēst izdodas tikai pēc cikla.
3. uzdevums -
Salīdzini List ar Godot Array
Beigās tu zināsi, kuru sarakstu kurā vietā lietot.
- Izveido
Godot.Collections.Array bullets = new();un pievieno tam dažas vērtības. - Izdrukā tā izmēru ar
bullets.Count. - Mēģini ielikt
Arraysarakstā gan skaitli, gan tekstu. - Mēģini to pašu ar
List<int>un izlasi kompilatora kļūdu. - Pieraksti, kurš saraksts pieļauj dažādus tipus.
- Pieraksti, kurš saraksts ir vajadzīgs, lai datus nodotu Godot editoram.
- Izvēlies savam ienaidnieku sarakstam pareizo variantu un pamato izvēli.
Gatavs, kad: tu vari pateikt, ka List<T> ir tipa-drošs un ērts iekšējam C# kodam, bet Array vajadzīgs saziņai ar Godot datiem.
Papildu uzdevums - Atrodi tuvāko ienaidnieku
Ja pamatdarbs ir gatavs, izmanto sarakstu reālam aprēķinam.
- Uzraksti metodi, kas saņem spēlētāja pozīciju.
- Izej ciklā cauri visiem ienaidniekiem.
- Izrēķini katram attālumu ar
Position.DistanceTo(...). - Saglabā mainīgajā to, kuram attālums ir mazākais.
- Izdrukā tuvākā ienaidnieka nosaukumu un attālumu.
Gatavs, kad: metode atgriež tieši to ienaidnieku, kurš ekrānā ir vistuvāk spēlētājam.
Ko sagatavo
Stundas mērķis: Tu proti C# izveidot List<T> sarakstu, droši pievienot un izņemt elementus un izskaidrot, ar ko tas atšķiras no Godot Array.
GitHub krātuvē jābūt:
- C# fails ar ienaidnieku sarakstu un ciklu.
- Ekrānuzņēmums ar Output paneli, kurā redzams saraksta izmērs pirms un pēc dzēšanas.
- README.md: kāpēc sarakstu nedrīkst mainīt cikla laikā un kad lieto
Array, nevisList<T>.
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
- ArgumentOutOfRangeException: sarakstā nav elementa ar tādu indeksu - pārbaudi
index < enemies.Count. - NullReferenceException: sarakstā ielikta tukša reference vai mezgls nav atrasts.
- Collection was modified: pievienojot vai dzēšot no
List<T>foreachlaikā, cikls apstājas ar kļūdu.
Godot ekrānuzņēmumi
Koda piemērs (paplašināts)
using Godot;
using System.Collections.Generic;
public partial class Game : Node2D
{
[Export] public PackedScene EnemyScene;
private readonly List<Enemy> enemies = new();
private double spawnTimer = 0.0;
private void SpawnEnemy()
{
Enemy enemy = EnemyScene.Instantiate<Enemy>();
AddChild(enemy);
enemy.Position = new Vector2((float)GD.RandRange(0.0, 1280.0), 0);
enemies.Add(enemy);
}
public override void _PhysicsProcess(double delta)
{
spawnTimer += delta;
if (spawnTimer >= 2.0)
{
SpawnEnemy();
spawnTimer = 0.0;
}
// Noņem mirušos
enemies.RemoveAll(enemy => !enemy.IsAlive());
}
}