I’m reading from the manual in section 10of this page:
https://castle-engine.io/viewport_and_scenes_from_code
The manual says to create multiple instances of a scene with a for loop in TStateMain.Start. When I try to compile, the “I” in " for I := " gives me this error:
gamestatemain.pas(65,5) Error: Identifier not found “I”
gamestatemain.pas(65,5) Error: Ordinal expression expected
gamestatemain.pas(65,5) Error: Illegal counter variable
(…followed by more errors pertaining to the missing indentifier…)
I tried declaring “I” as a variable first:
var
I: integer;
and then I get this error:
gamestatemain.pas(62,1) Error: Illegal expression
gamestatemain.pas(63,4) Fatal: Syntax error, “;” expected but “identifier I” found
I thought declaring counter variables within the syntax of the for loop was generally the proper convention. I don’t know what to do to get it to compile. Here is what my code looks like presently:
{var
I: integer;}
for I := Low(CarTransforms) to High(CarTransforms) do
begin
CarTransforms[I] := TCastleTransform.Create(Application);
CarTransforms[I].Translation := Vector3((Random(4) - 2) * 6, 0, RandomFloatRange(-70, 50));
CarTransforms[I].Add(CarScene);
Viewport.Items.Add(CarTransforms[I]);
end;
Could someone give me some guidance/clarify what is wrong?
In Pascal you have to declare variables in a special place, not just anywhere like in C#. E.g. in your situation it would be something like:
procedure TStateMain.Start;
var
I: Integer; // before "begin"
begin
inherited; // note this thing, it's important to call parent's Start, it's like base.Start() in C#
for I := Low(CarTransforms) to High(CarTransforms) do
begin
CarTransforms[I] := TCastleTransform.Create(Application);
CarTransforms[I].Translation := Vector3((Random(4) - 2) * 6, 0, RandomFloatRange(-70, 50));
CarTransforms[I].Add(CarScene);
Viewport.Items.Add(CarTransforms[I]);
end;
end;
Hi eugeneloza. Thanks for explaining that! I had decided to focus on the CGE tutorials first and then go do some more focused study on learning pascal, but it looks like maybe I should do that first.
I moved the integer declaration up to the position you demonstrated, and now the for loops itself gives no errors, but it appears to have broken everything else.
gamestatemain.pas(65,52) Error: Identifier not found “Application”
gamestatemain.pas(66,72) Error: Identifier not found “RandomFloatRange”
gamestatemain.pas(68,8) Error: Identifier not found “Viewport”
gamestatemain.pas(88,12) Error: Methods can be only in other methods called direct with type identifier of the class
gamestatemain.pas(90,3) Error: Identifier not found “LabelFps”
gamestatemain.pas(90,33) Error: Identifier not found “Container”
gamestatemain.pas(92,16) Error: Identifier not found “CarTransforms”
gamestatemain.pas(92,39) Error: Identifier not found “CarTransforms”
gamestatemain.pas(93,7) Error: Identifier not found “UpdateCarTransform”
gamestatemain.pas(93,26) Error: Identifier not found “CarTransforms”
gamestatemain.pas(94,4) Fatal: Syntax error, “.” expected but “;” found
I’ll take another shot at this when I can write pascal without needing my hand held. Thanks for your help!
The compiler first looks for obvious errors in the code (like using wrong syntax), and if there are none, then tries to look for more complex ones. So, what happened next: 1) your uses
section is not filled in properly and 2) you don’t seem to be working inside of a proper TUiState
class.
It may get a bit confusing if I’ll try to explain those. You’ll need to get acquainted with several principles of programming in Pascal. I’m not sure if you have background in some other programming language (am I correct in guessing it’s C#?), but you might find useful this book by @michalis Modern Object Pascal Introduction for Programmers | Castle Game Engine
Namely your issues are addressed in Modern Object Pascal Introduction for Programmers | Castle Game Engine and Modern Object Pascal Introduction for Programmers | Castle Game Engine
What exactly the errors that you’ve received mean is:
- gamestatemain.pas(65,52) Error: Identifier not found “Application” ----------- means you didn’t include
CastleWindow
unit in uses
section.
- gamestatemain.pas(66,72) Error: Identifier not found “RandomFloatRange” ----------- means you didn’t include
CastleUtils
unit in uses
section.
Next errors mean that you are doing something not inside your “State” class but inside some other procedure, or in method of a class that does not inherit from TUiState
.
- gamestatemain.pas(68,8) Error: Identifier not found “Viewport”
- gamestatemain.pas(90,3) Error: Identifier not found “LabelFps”
- gamestatemain.pas(90,33) Error: Identifier not found “Container”
The next errors mean that you reference some variables/classes/methods that do not exist in the current context. Maybe this is consequence of the previous bug, or maybe you just didn’t declare them yet:
- gamestatemain.pas(92,16) Error: Identifier not found “CarTransforms”
- gamestatemain.pas(92,39) Error: Identifier not found “CarTransforms”
- gamestatemain.pas(93,7) Error: Identifier not found “UpdateCarTransform”
- gamestatemain.pas(93,26) Error: Identifier not found “CarTransforms”
Finally this one means that you have unmatching begin
…end
pairs, or otherwise some other required “end
” is missing.
- gamestatemain.pas(94,4) Fatal: Syntax error, “.” expected but “;” found
Note that the manual has a hint to add units to uses
clause, and how to find them:
Remember to add the necessary units to your uses
clause to have the appropriate identifiers defined. If you follow the reference links, like this one: TCastleScene
, then you will see in which unit is each identifier defined. TCastleScene
class is part of the CastleScene
unit. TCastleViewport
is part of the CastleViewport
unit.
(Read it with links, point 5 of " 5. Refer to the designed components" on Writing code to modify scenes and transformations | Manual | Castle Game Engine ).
In the past, I was writing which units exactly to add to the uses
clause in manual – but occasionally this information was outdated by next engine versions. So I decided to give here a “fishing rod”, not a “fish”, to readers Hopefully you can figure it out (of course let us know if not).
If you get stuck, remember that there’s an example project in engine code ( castle-engine/examples/viewport_and_scenes/cars_demo at master · castle-engine/castle-engine · GitHub , open examples/viewport_and_scenes/cars_demo
if you already have CGE) that does everything described in that manual page. You can just explore code/gamestatemain.pas
inside, https://github.com/castle-engine/castle-engine/blob/master/examples/viewport_and_scenes/cars_demo/code/gamestatemain.pas .