Objektorientētā // programmēšana
Apgūsti C# klases, mantošanu un polimorfismu Godot .NET vidē.
Tēma noslēdzas ar RPG klases simulatora izveidi.
6 stundas - tēmas saturs
No C# klases pamata līdz RPG klašu simulatora projektam.
C# klases pamati
Apgūsti C# klases struktūru, private/public sekcijas un dalībnieku deklarācijas.
Mantošana C# un Godot
Veido klašu hierarhiju - Entity bāze ar Player, Enemy un Boss atvasinājumiem.
Signāli un objektu komunikācija
Iepazīsti Godot signālu sistēmu - emit_signal, connect un callable_mp C#.
Custom C# klases
Eksponē C# īpašības Godot inspektoram ar [Export] un PropertyHint.
Statistikas sistēma un struct
Veido RPG statistikas sistēmu ar struct, HP/ATK/DEF/SPD vērtībām un pieredzi.
Noslēguma projekts: Klases turnīra simulators
Izveido rundām balstītu klases turnīra simulatoru ar C# klašu hierarhiju (Participant, Obstacle), struct statistiku un signāliem.
3. tēmas špikeris - klases C# valodā
No pirmās klases līdz signāliem un Inspector īpašībām. Ja klases redzi pirmoreiz, sāc ar pirmo bloku.
3.1 No Python vārdnīcas uz C# klasi
// Python, ko jau zini:
// dalibnieks = {"vards": "Anna", "energija": 100}
// dalibnieks["energija"] -= 20
public class Participant
{
private int energy; // pieejams TIKAI klases iekšienē
private int maxEnergy;
public string Name; // pieejams no ārpuses
public int Level = 1;
public Participant(string name, int energy) // konstruktors
{
Name = name;
this.energy = energy;
maxEnergy = energy;
}
public void ApplyPenalty(int amount) // metode = funkcija klasē
{
energy -= amount;
if (energy < 0) energy = 0;
}
public bool IsActive() => energy > 0;
public int GetEnergy() => energy; // privāto lasa caur metodi
}
Participant p = new Participant("Anna", 100);
p.ApplyPenalty(30);
// p.energy = 9999; <- KOMPILATORA KĻŪDA: energy ir private
C# klases beigās semikolu nevajag, bet katras komandas rindas beigās parasti vajag ;.
3.2 Mantošana: viena bāze, vairākas lomas
using System;
using System.Collections.Generic;
public class Participant
{
private string name;
private int energy;
public Participant(string name, int energy)
{
this.name = name;
this.energy = energy;
}
public virtual void ApplyPenalty(int amount) // virtual = drīkst pārrakstīt
{
energy = Math.Max(0, energy - amount);
}
}
public class Captain : Participant
{
private int stability = 10;
public Captain(string name) : base(name, 150) { } // izsauc VECĀKA konstruktoru
public override void ApplyPenalty(int amount) // override = pārraksta
{
amount = Math.Max(1, amount - stability);
base.ApplyPenalty(amount); // izsauc vecāka versiju
}
}
public class Presenter : Participant
{
public Presenter(string name) : base(name, 100) { }
}
// Polimorfisms: viens cikls apkalpo visas lomas
List<Participant> party = new()
{
new Captain("Anna"),
new Presenter("Jānis")
};
foreach (Participant p in party)
{
p.ApplyPenalty(20); // katrai lomai savs rezultāts
}
Bez : base(name, 150) vecāka konstruktors netiek izsaukts. Bez virtual pārrakstīšana nenostrādā.
3.3 Signāli - objekti sarunājas, viens otru nezinot
// RAIDĪTĀJS
[Signal] public delegate void FinishedEventHandler(string name);
public void ApplyPenalty(int amount)
{
energy -= amount;
if (energy <= 0) EmitSignal(SignalName.Finished, participantName);
}
// KLAUSĪTĀJS
public override void _Ready()
{
participant.Finished += OnFinished;
}
private void OnFinished(string name)
{
GD.Print(name, " izstājās");
}
Dalībnieks nezina, ka menedžeris eksistē. Tāpēc dalībnieku var lietot arī citā spēlē.
3.4 GlobalClass un Inspector īpašības
using Godot;
using System;
[GlobalClass]
public partial class Obstacle : CharacterBody2D
{
private int energy = 50;
private float speed = 100.0f;
[Export]
public string ObstacleName { get; set; } = "PrinterQueue";
[Export(PropertyHint.Range, "0,500")]
public int Energy
{
get => energy;
set => energy = Math.Max(0, value);
}
[Export(PropertyHint.Range, "0,500,0.1")]
public float Speed
{
get => speed;
set => speed = Math.Max(0.0f, value);
}
}
Tagad vienu klasi var lietot daudziem mezgliem, katram Inspector panelī iestatot citu vērtību.
3.5 struct un kompozīcija
using System;
using System.Collections.Generic;
public struct Buff
{
public string Name;
public int FocusBonus;
public int TurnsLeft;
}
public class Stats
{
public int Energy = 100, MaxEnergy = 100;
public int Focus = 10, Calm = 5, Speed = 5;
public List<Buff> Buffs = new();
public void Heal(int amount)
{
Energy = Math.Min(MaxEnergy, Energy + amount); // nepārsniedz max
}
public int GetTotalFocus() // RĒĶINA, nevis glabā atsevišķi
{
int total = Focus;
foreach (Buff buff in Buffs) total += buff.FocusBonus;
return total;
}
}
public class Participant
{
private Stats stats = new(); // kompozīcija: klasei PIEDER stats objekts
public Stats GetStats() => stats;
}
p.GetStats().Heal(30);
Kopējo vērtību rēķini no saraksta. Ja to glabā atsevišķā laukā, tas ātri kļūst nepareizs.