Working with Scenes and Sprites

MainViewport.Camera.Orthographic.Width := 1920; // set resolution
MainViewport.Camera.Orthographic.Height := 1080; // set resolution
MainViewport.Camera.Orthographic.Origin := Vector2(0.5, 0.5);

I have placed a sprite on the Viewport.

Scene.Translation := Vector3(0, 0, 1) puts it at the centre of the background scene.

How can I

  • set the X and Y position of the sprite (so that 0,0 is left bottom of the viewport)
  • move the sprite around
  • scale it so it becomes larger or smaller when changing its Y position?

You can change the Scene.Translation and Scene.Scale at any point in the game. This is how you would move the sprite, and scale the sprite. You need to implement the movement logic yourself (to handle keys etc.)

Test the templates produced by the editor, like “New Project → 2D Game” to see it in action.

Thanks.

How can I use multiple sprite screens in 1 scene?
When I load a second sprite screen it replaces the previous one.
I have 16 sprite screens for the character sprite (walking and standing idle in 8 directions).
Putting all animations in 1 sheet is not really an option because of the dimensions and file size and reloading every time a sheet for changing direction also.

I don’t know if it’s the proper way, but this works:

SpriteScreen[1] := ‘WalkLeft’;
SpriteScreen[2] := ‘WalkRight’;
SpriteScreen[3] := ‘WalkFront’;

for count := 1 to 3 do
begin
Scene := TCastleScene.Create(Application);
Scene.Setup2D;
Scene.Load(‘castle-data:/locations/John’+ SpriteScreen[count] + ‘.starling-xml#fps:45,anim-naming:trailing-number’);
Scene.PlayAnimation(‘John’ + SpriteScreen[count] + ‘-’, true);
Scene.ProcessEvents := true;
Scene.Translation := Vector3(0, 0, 1);

MainViewport.Items.Add(Scene);
end;

But when I try to add control the animations won’t play with this procedure:

procedure WindowPress(Container: TUIContainer; const Event: TInputPressRelease);
begin
if Event.IsKey(keyArrowLeft) then
begin
Scene.PlayAnimation(‘John’ + SpriteScreen[1] + ‘-’, true);
end;

if Event.IsKey(keyArrowRight) then
begin
Scene.PlayAnimation(‘John’ + SpriteScreen[2] + ‘-’, true);
end;
end;

What is wrong here?

I’d have to see the full data and code to tell what’s wrong, the intention of this code is not clear to me. Maybe you use a global Scene variable where you should not? You should instead store references to each scene for each character?

In general, if you need to have a few sprite sheets that represent a single NPC, and switch at runtime between them, then use a TCastleTransform with a few children being TCastleScene. Like this:

MyFirstNpc: TCastleTransform
-> MyFirstNpcWalkAnimation: TCastleScene
-> MyFirstNpcIdleAnimation: TCastleScene

The MyFirstNpcWalkAnimation and MyFirstNpcIdleAnimation would be children of MyFirstNpc, that is added like

...
MyFirstNpc.Add(MyFirstNpcWalkAnimation);
...
MyFirstNpc.Add(MyFirstNpcIdleAnimation);

and only the MyFirstNpc is added to the viewport:

Viewport.Items.Add(MyFirstNpc);

Then you

  • control the NPC position by changing MyFirstNpc.Translation := ...
  • play the animations by MyFirstNpcIdleAnimation.PlayAnimation(...) and making sure that only one child scene has Exists = true.

I emphasize that it can, and should, be setup and tested visually using CGE editor, you will then see what it going on better.

Ok, I got it working, here is the complete code.
But maybe it can be more compact, for instance the procedure StopWalk. I found it cumbersome to
repeatedly have to switch off animations on changing sprite screens so I’m open for suggestions on improvement.

update:
(edited and moved to topic: “Collision Course”