Setting Scene coordinates

Standard is X,Y 0 the centre of the scene image (Red dot).
I would like to set it to where I have drawn the green dot.
So Y 0 should be at the “feet” of the image or at least the destination.Y.
Because I want the character to walk to a destination object (with mouse click) and stop as he reaches the object. Not walk over it, which is the case when Y is in the middle of the scene.
How can I set this?

And for instance with walking to the right the X destination should be bottom right so the character stops when his feet touches the object right of him.

You need the Scene internally to have itself scaled properly. I don’t remember exactly how you are loading the scene, but it should be something like:

<Transform
	translation="0 -0.1 0"> <--------------- HERE DIFFERENCE
	<Shape>
		<Appearance>
			<ImageTexture
				repeatS="false"
				repeatT="false"
				url='"bullet-holes.png"'>
				<TextureProperties
					guiTexture="true" />
			</ImageTexture>
		</Appearance>
		<Rectangle2D
			size="0.2 0.2" />
	</Shape>
</Transform>

instead of

<Transform
	translation="0 0 0">
	<Shape>
		<Appearance>
			<ImageTexture
				repeatS="false"
				repeatT="false"
				url='"bullet-holes.png"'>
				<TextureProperties
					guiTexture="true" />
			</ImageTexture>
		</Appearance>
		<Rectangle2D
			size="0.2 0.2" />
	</Shape>
</Transform>

I understand less and less.

The whole ‘World’ coördinate system is confusing.
I want my graphics coordinates to be the same as the screen resolution dimensions, so in my case correspond with a resolution of 2560 x 1440 pixels.
I cannot get the Transform dimensions.
My character sprites are 360 pixels width and 630 pixels heigth. So the scene scales itself to this.
When i want bottom-middle of the sprite-scene to be the destination, X destination has to be 360/2 and Y 0.

When I move mouse scene to bottom left of the screen it should be 0,0.
Now it’s as you can see in the picture (mouse eye icon).

PlayerMouse.Scene.Translation := Vector3(Mainviewport.PositionTo2DWorld(Container.MousePosition, true), 9);
Label1.Caption := floattostr(PlayerMouse.Scene.Translation.X) + ‘,’ + floattostr(PlayerMouse.Scene.Translation.Y);

There should be a way to configure anchor / pivot points in the software you use to generate sprite-sheets, for example in ShoeBox:
image
You can also use the code approach (like eugeneloza’s example), but it requires to understand basic stuff, like local / world coordinates & how the engine’s scene graph works.

I can work around so that Destination.Y is not in the centre of the Scene but ‘at the feet’ if I add 1/2 of the spriteScene Height (630 pixels). But it is still not based on pixel counting.

if Player.Y <= Round(Player.Destination.Y+315) then StandFront;

The simplest way is to wrap your Player around a new TCastleTransform instance and use that instead:

var T: TCastleTransform;

Player.Translation := Vector3(0, 315, 0);
T.Add(Player);
Viewport.Items.Add(T);
// Now you use T instead of Player for position manipulation

1 Like

Ah, indeed, that would be the simplest, safest and thus the best solution.

Ok, but then maybe, because I use scenes as children of the PlayerTransform I can use this just on the direction scenes I already have. Because the Destination ‘point’ has to differ for all directions.
So in my example above: Vector3(0, 315, 0) for just the WalkFrontScene
And Vector3(-180, 315, 0) for WalkRight.

Still I would prefer resolution pixel coördinates as with Windowbase.

image

I am also struggling with scene scaling.
When I put a scene on bottom of viewport (or location scene).

PlayerTransform.Translation := Vector3(0, -750, 1);
PlayerTransform.Scale := Vector3(1, 1, 1);

It is at it’s largest size.

I have:


if Player.WalkBack then
 begin
   Player.Y := Player.Y + 2;
   Player.S := Player.S - 0.003;
   PlayerTransform.Translation := Vector3(Player.X, Player.Y, -Player.Y);
   PlayerTransform.Scale := Vector3(Player.S, Player.S, Player.S);
 end;

So with every Y decrease I think the scaling should be - 0.003/2.
Problem is the scaling has to be relevant to the position on the background scene.

So (roughly)
if Player.Y = -750 then S := 1;
if Player.Y = -749 then S := 1 - 0.003/2;
if Player.Y = - 748 then S := 1 - 0.003;
if Player.Y = - 747 then S := 1 - (0.003 + 0.003/2).

This is plain stupid but you get the intention.
:wink:

So how can I put this in a formula? It even gets more difficult when Y value eventually gets positive values.

Update:
Got it.

 if Player.WalkBack then
 begin
   Player.Y := Player.Y + 1;
   PlayerTransform.Translation := Vector3(Player.X, Player.Y, -Player.Y);
   Player.S := 1 - 0.0015 * (Player.Y + 420);
   PlayerTransform.Scale := Vector3(Player.S, Player.S, Player.S);
 end;

Y has a ‘maximum negative value’ of -419 to have the character bottom down on screen.
With Y 419, Scaling has to be 1, so I add 420.
Walking back will add to Y, but scaling down has to be just 0.001 with every Y.
I would suspect that things would go wrong when Y becomes a positive value (as Y= 0 is in the centre of the background scene) but the scaling is fine.
I will put a picture here when I have succeeded the same with all character scenes.
:slight_smile:

I finetuned the earlier 0.0010 per Y to 0.0015 as I found the scaling too little between the characters.
I think I will make this a variable so the distance can differ per location background.
:slight_smile:

Location.NPC[NR].S := 1 - 0.0015 * (NPCinfo[I].Y + 420); 
NPCScene[NR].Translation := Vector3(NPCinfo[I].X, NPCinfo[I].Y, -NPCinfo[I].Y);
NPCScene[NR].Scale := Vector3(Location.NPC[I].S, Location.NPC[I].S, Location.NPC[I].S);
MainViewport.Items.SortBackToFront2D;

About this sentence: To be clear, you can do this easily, but it’s bad idea.

You can just not use UI scaling (put <ui_scaling mode="None" /> in CastleSettings.xml, see Customize look by CastleSettings.xml | Manual | Castle Game Engine , or even just remove <ui_scaling... element – it is default). Then you just set and see the UI control sizes in actual pixels (MyViewport.Width, MyViewport.EffectiveWidth etc. just reflect actual pixels).

Moreover if you don’t set any projection size, by leaving default MyViewport.Camera.Orthographic.Width and MyViewport.Camera.Orthographic.Height equal to zero, then the distances you see are just the same as UI sizes. So they will reflect actual pixels, if you turned off UI scaling. And you can leave `MyViewport.Camera.Orthographic.Origin at (default) zero to have origin in left-bottom corner.

So you can easily have the case “I just want to operate in device pixels”. That said, it is a bad idea. Other people don’t have 2560 x 1440 screen, they may also want to run game in window mode. Whatever you design will look bad on their systems, as they have smaller or larger screen. That is why we advise UI scaling, and Customize look by CastleSettings.xml | Manual | Castle Game Engine by default sets it up.

Note that you can use reference sizes 2560 x 1440 in CastleSettings.xml, Customize look by CastleSettings.xml | Manual | Castle Game Engine , instead of default 1600 x 900. But it still doesn’t free you from making sure your game works when scaled, i.e. on other resolutions (including other aspect ratios) than 2560 x 1440.

Ok, so it’s not a good idea. The problem I am struggling with is that 0,0 is in the middle / centre of the viewport, so with scene moving left x has negative value and moving down y has negative value. This makes it hard to control scenes as I have to reverse formulas etc.
So when 0,0 is bottom left as in window it would help.
This perhaps is also the problem I have with the moving in 8 directions with tan2 because of the negative values calculated. (see topic).

Could you please also look at the boolean problem when changing scenes that causes hickup (but with string it works okay). See links to the small videos I uploaded. Thanks!

(See topic Scene Exists and Scene Visible)

I think you set it yourself to be in the center of the viewport, by setting Camera.Orthograhic.Origin to (0.5, 0.5), during one of the earlier threads on this forum. By default Camera.Orthograhic.Origin is (0, 0) and it means that position (0, 0) results in the left-bottom corner of the viewport.

You can set Camera.Orthograhic.Origin to whatever is comfortable for you, though also make sure it makes sense for different aspect ratios (what happens when user doesn’t have 16 : 9 but e.g. 16 : 10 screen size). Whether positioning vs center or vs left-bottom corner is better in this viewport – up to a particular game.

That’s right, because the background scene would appear like this:

So I changed back to 0,0 and bottom left is now 0,0 (Great, now we’re getting somewhere :slight_smile:
Background picture placing is now a mess because I had everything set on 0,5 0,5 in code.
Also it is scaled now.

Every scene has it’s own translation but how can I get the background scene placed right?

I tried changing Translation of Location(TCastleTransformDesign) but it has no effect on the size and placement.

Location.Transform := TransformLoad('castle-data:/'+ Location.Name + '.castle-transform', LocationOwner);
   Location.BackgroundScene.Translation := Vector3(1200,700, 1); // does not do anything?
   Location.Transform.Add(Location.BackgroundScene);
   Location.Transform.Translation := Vector3(50, 50, 1); // shows just part of the background scene and it is scaled too high

   MainViewport.Items.Add(Location.Transform);

(This Transformdesign point to designs that has scenes with background picture URL.

(btw: labels are not showing up either; are they placed behind the transform?)

This is too much confusing notes, and things that we cannot help with without knowing the details.

Please, create a small (as small as possible) project to reproduce each problem you have. Then we can resolve them, one by one.

The TCastleTransformDesign translation should work, the labels should be visible on top of your viewport. But is not possible to debug what is wrong in your case just from looking at the screenshots, I’m afraid.

Translation problems.zip (9.9 MB)

Thanks.
Okay, I took away almost everything; see attachment.
Problems:

  • background scene is not fully shown and it is scaled.
  • mouse scene is scaled up also (like the background)
  • label texts are not shown

What at least works :slight_smile: is:
The viewport is now 2560 x 1440, as the original picture.
The player character is scaled allright.

Update:
I just found out that the Label texts are not showing up because of their placement.
It appears that the size of the background is the size of the Viewport.Items Root Transform.
and so the background picture showing part is limited to its size?
Now the scaling is allright and the only old problem is again: placing it fully on screen with Orthographic origin still at 0,0.

Hm, by setting the Translation of the RootTransform I got the full background picture again.
So this maybe good; however now there is a distance between the system mouse coordinates and playerscene mouse.
That’s because I have in code:

PlayerMouse.Scene.Translation := Vector3(Mainviewport.PositionTo2DWorld(Container.MousePosition, true), 10);
But also the PlayerTransform 0,0 is now in the centre of the screen, so this is not good.

Viewport Camera current view all.
0,0 is bottom left, so okay.
But scaling is not (close-up instead of full picture).