Note that all the instance fields are automatically initialized to nil
in Object Pascal, no need to do this explicitly.
type
TMyClass = class
Int: Integer;
AnotherObject: TObject;
end;
var
My: TMyClass.
begin
M := TMyClass.Create;
Writeln(M.Int); // guaranteed zero
Writeln(M.AnotherObject <> nil); // guaranteed false
FreeAndNil(M);
end.
Looking at the source code of @haoshef , I see an additional problem. I hope my comments below will be helpful to learn more about the Pascal
-
You never create any instance of the
TMovement
class, that is: you never callTMovement.Create
. The global variableMovement: TMovement;
has always value ofnil
in your application, from what I can see you never assign anything to it (you never do sthg likeMovement := TMovement.Create
). Calling any method of such class or accessing any field of it is an error. -
Things happen to work because you made all the fields “class fields”, and you don’t use virtual methods, so you have
class var Viewport: TCastleViewport; class var Nav: TCastleWalkNavigation; class var Camera: TCastleCamera;
But in this case, assessing them by (uninitialized) global variable
Movement: TMovement;
is not necessary. -
In your application, you defined a number of other own classes (
TButtons
,TForfeitNav
,TGameRegulation
) but you never create instances of them, and they all work following the above workflow: all fields areclass var
, all methods are non-virtual. The global variablesButtons: TButtons; Regulation: TGameRegulation;
are never initialized, they are always
nil
, but things happen to work because calling non-virtual methods and accessing class fields is OK, nothing actually “deferences” the invalidnil
pointers. -
Recommendation:
-
Either delete the global variables, like
Movement: TMovement;
, and use only class fields and class methods, likeTMovement.Init
. -
Or make the
Viewport
(and other fields inTMovement
) regular fields (notclass var
), and create the class likeMovement := TMovement.Create
and destroy it at the appropriate moment (e.g. in afinalization
of some unit). And instead of inventing your own methodInit
, defineconstructor Create
to initialize the class fields.
Do the above consistently for all of your own classes, like
TButtons
,TForfeitNav
,TGameRegulation
. -
-
Possibly, you are unsure how to do the above, it’s OK! If you’ve never done it, then my advise “create the class” may sound like a black magic incantation
No worries, I also didn’t know how to create classes long time ago
We have resources to learn, please read them and experiment with creating classes in Object Pascal: