Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Class var


knittel - Do 21.10.10 12:07
Titel: Class var
Hallo allerseits,
Ich hab mal wieder ein Problem mit OOP. Ich bin immernoch dabei ein Spiel zu entwickeln. Dabei gibt es unteranderen folgende Klassen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
TMilitaryUnit = class (TUnit)
  protected
    class var FATK: integer; // The ATK of the Unit
    class var FRange: integer; // A Square around the Unit
    class var FReloadTimeOut: single; // How many Seconds To Reload
  public
    procedure Shoot (ObjectIndex: cardinal);
  end;



Delphi-Quelltext
1:
TBaseUnit = class (TMilitaryUnit)                    


Nun will ich ja mehrere militärische Einheiten haben, mit unterschiedlichem Leben und unterschiedlicher ATK. Es ist klar, dass alle Military Einheiten eine ATK, eine Reichweite und eine RateOfFire haben. Nur ihre Werte darin sind unterschiedlich, allerdings für die gesamte Klasse (z.B. TBaseUnit) gleich. Deswegen habe ich "class var" benutzt. Jetzt meine Frage: Wir werden class vars veerbt. Wenn ich von TBaseUnit aus FATK verändere verändere ich sie dann in TMilitaryUnit also auch für alle anderen Unterklassen von TMilitaryUnit oder nur für TBaseUnit?

Danke im voraus.


Gausi - Do 21.10.10 12:49

Wäre es nicht sinnvoller, privaten Variablen dafür zu nehmen und die im Konstruktor passend zu setzen? Klassenvariablen für ein globales Gleichsetzen finde ich hier irgendwie unangebracht, bzw. am OOP-Konzept vorbei programmiert. :nixweiss:


knittel - Do 21.10.10 15:52

Wenn jede Einheit ihre eigene ATK, RateOfFire und Range speichert. Verbraucht das dann nicht deutlich mehr RAM Speicherplatz und bei jedem Erstellen einer Einheit auch Prozessor Kraft?


Gausi - Do 21.10.10 16:00

Ja. Eine Integer-Variable benötigt 4 Byte Speicher, drei davon also 12 Byte. Wenn du also 100.000 solcher Einheiten erstellst, brauchst du dadurch gut 1 MB mehr Speicher. Das ist dann doch vernachlässigbar, oder? ;-)


jaenicke - Do 21.10.10 16:50

Die einfachste Variante ist aber eine Klasse zu erstellen und einfach eine Referenz darauf an die einzelnen Objekte mitzugeben. Dann kannst du das in dem einen Objekt ändern und alle haben die Änderung auch, wenn sie die Werte dort auslesen.

Das ist performant und du musst dich nicht verbiegen. ;-)


knittel - Fr 22.10.10 16:49

Ich hab das Prinzip irgendwie nur halb verstanden: Wie würdest du diese Referenz aufbauen?

So habe ich es verstanden :

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
// Hierdrin sind alle statischen Werte
type TStaticValues = class
  public
    BaseUnit_MaxSpeed: integer; // Maximale Bewegungsgeschwindigkeit;
    BaseUnit_Range: integer; // Maximale Reichweite;
    IntruderUnit_MaxSpeed: integer;
    IntruderUnit_Range: integer;
  end;

[...] // Verschiedene Klassen werden deklariert

// Der Bewegungsbefehl, der vorher einfach auf den Wert der Einheit zugegriffen hat.
procedure TUnit.MoveTo (AtX, AtY);
begin
// Von hier bis...
FAimX := AimX;
FAimY := AimY;
DeltaX := AimX-Xpos;
DeltaY := AimY-Ypos;
NDistance:=sqrt((DeltaX*DeltaX)+(DeltaY*DeltaY));

// So und hier bin ich mir nicht ganz sicher?
// Da alle Einheiten Gehen können, habe ich logischerweise
// eine Überklasse mit den nötigen Variablen und Procedures gemacht.
// Wie entscheide ich jetzt hier auf welchen Wert zugegriffen werden soll.
StepsNeeded:=NDistance / MaxSpeed ;

DeltaX:=(DeltaX / StepsNeeded);
DeltaY:=(DeltaY / StepsNeeded);
IsMoving := true;
// ...hier ist die Berechnung des Weges
end;


Danke im voraus.

EDIT: Das mit dem nur einmal ändern wäre auf jedenfall sehr gut, weil ich außerdem überlege sowas wie einen Forschungsbaum einzufügen.