I have an array[0…9] of string:
Cursor[1] := 'mouse-hand';
Cursor[2] := 'mouse-talk';
Cursor[3] := 'mouse-walk';
Cursor[4] := 'mouse-inventory';
Cursor[5] := 'mouse-arrowleft';
Cursor[6] := 'mouse-arrowright';
Cursor[7] := 'mouse-arrowup';
Cursor[8] := 'mouse-arrowdown';
Cursor[9] := 'mouse-stopsign';
but would like to replace it with enumeral type like in the pascal introduction manual:
``type
TAnimalKind = (akDuck, akCat, akDog);
TAnimalNames = array [TAnimalKind] of string;
So:
TMouseCursors = (mouse-eye, mouse-hand, mouse-talk, mouse-walk);
TCursor = array(TMouseCursors) of string;
var Cursor: TCursor;
But how can I access this?
Image := Cursor[1];
Gives an error.
You cannot safely mix the two approaches (you can still unsafely mix those).
type
TMyCursor = (mcEye, mcHand, mcTalk, mcWalk); //note, it's a good idea to avoid using minus sign "-" in enum names, I'd be quite surprised if it'd work.
var
MyArray: array [TMyCursor] of TCastleScene; // Note square brackets "[...]" and it may be a better idea to directly reference a TCastleScene in this case, not some string.
...
CursorScene := MyArray[mcEye]; // i.e. you have to reference enum directly.
// You can also reference to TMyCursor by
CursorScene := MyArray[TMyCursor(0)];
// however, be aware that it may end in unexpected result in some situations. As in "not safe". E.g. if you reorder the cursors in TMyCursor - you'll get a weird, hard-to-debug bug.
1 Like
Thanks.
I choose the second option, as the ‘cursor order’ will remain the same.
The idea is to right click mouse through the options.
The array is a string because there is only 1 spritescreen with an xml file containing the names that are accessed by Playanimation.
But now calling the name in the xml it does not work; it appears the contents (mcHand etc) are not read. This is what I have:
type TGamemouse = class(TComponent)
private
Scene: TCastleScene;
NR: integer;
type
TCursor = (mcEye, mcHand, mcTalk, mcWalk);
var
CursorArray: array [TCursor] of string;
end;
PlayerMouse: TGamemouse;
procedure TStatePlay.CreatePlayerMouse;
begin
PlayerMouse := TGamemouse.Create(PlayerMouse);
Scene := DesignedComponent ('Mouse') as TCastleScene;
Scene.Cursor:= mcForceNone;
end;
if Event.IsMouseButton(buttonRight)then
begin
inc(PlayerMouse.NR); // cycle through the options
if PlayerMouse.NR = 4 then PlayerMouse.NR := 0;
PlayerMouse.Scene.PlayAnimation(PlayerMouse.CursorArray[PlayerMouse.TCursor(PlayerMouse.NR)], true);
end;
xml file is:
<?xml version="1.0" encoding="utf-8"?>
<TextureAtlas imagePath="mouse-icons.png">
<SubTexture x="0" y="200" fps="8" name="mcEye" width="50" frameX="0" frameY="0" height="50" frameWidth="50" frameHeight="50"/>
<SubTexture x="50" y="200" fps="8" name="mcHand" width="50" frameX="0" frameY="0" height="50" frameWidth="50" frameHeight="50"/>
<SubTexture x="100" y="200" fps="8" name="mcTalk" width="50" frameX="0" frameY="0" height="50" frameWidth="50" frameHeight="50"/>
<SubTexture x="150" y="200" fps="8" name="mcWalk" width="50" frameX="0" frameY="0" height="50" frameWidth="50" frameHeight="50"/>
<SubTexture x="200" y="200" fps="8" name="mouse-inventory" width="50" frameX="0" frameY="0" height="50" frameWidth="50" frameHeight="50"/>
<SubTexture x="0" y="150" fps="8" name="mcArrowleft" width="50" frameX="0" frameY="0" height="50" frameWidth="50" frameHeight="50"/>
<SubTexture x="50" y="150" fps="8" name="mcArrowright" width="50" height="50"/>
<SubTexture x="100" y="150" fps="8" name="mcArrowup" width="50" height="50"/>
<SubTexture x="150" y="150" fps="8" name="mcArrowdown" width="50" frameX="0" frameY="0" height="50" frameWidth="50" frameHeight="50"/>
<SubTexture x="200" y="150" fps="8" name="mcStopsign" width="50" height="50"/>
</TextureAtlas>
Testing here, the Starling XML you show works, it has the animations you indicated (opening in view3dscene).
( I used a dummy texture, don’t pay attention to it, just see that animation list corresponds to your XML name
s )
As for enums: while you can convent between enum <-> integers back and forth (as mentioned on Modern Object Pascal Introduction for Programmers , TAnimalKind(MyInteger)
or Ord(High(TAnimalKind))
… but this is a bit hacky. If you find yourself constantly converting enum <-> integers, it may mean you don’t really want enums, and instead should just use integers. The point of enums is that they (at least usually) act as “opaque” type and you don’t need to think about their numerical value.
Cycling can be done on enums without any typecasts, use Low
, High
and Succ
standard Pascal constructs:
if MyCursor = High(MyCursor) then
MyCursor := Low(MyCursor)
else
MyCursor := Succ(MyCursor);