# Rotating a scene to simulate turning wheel

I have a picture of a wheel. I used a paint program to rotate it by % and then save it as a sprite screen to use it in a playanimation sequence (12 images).
But it is not rotating equal because there is a little shift in the wheels position. (looks rather funny).
So I thought it would be better if the scene consists of just this picture and then rotate the scene to simulate rotation of the wheel. Is this possible?
(I guess the axe should be perfectly in the middle of the scene to prevent it from shifting position while rotating).
Thanks!

Yes, thatâ€™s exactly the way to go. Just make sure center of the wheel is perfectly at the center of the image.

Use Castle Game Engine: CastleTransform: Class TCastleTransform the example at that page rotates the scene exactly around the Z-axis (that is in your 2D case - as you would expect, along the playerâ€™s line of sight / depth of the view unless you are applying additional transformations in parent).

Great!
Got it working.
Now I was about to ask how to change rotation direction and speed but already figured it out by changing the pi value.

Location.Props[2].Image.Rotation := Location.Props[2].Image.Rotation + Vector4(0, 0, 0, Pi / -50);
Negative value rotates the image clockwise and decreasing or increasing the value affects speed.

1 Like

Note that if you update the rotation every frame, itâ€™s a good idea to also use `SecondsPassed * RotationSpeed` where RotationSpeed is in radians. Here, just as you do for movement. `Pi / -50` actually stands for this rotation per frame but it doesnâ€™t consider `SecondsPassed` and may result in something unexpected.

1 Like

Consider this shorthand, when you have established rotation axis and do not want to be changing it but only the angle.

or as a patch - Wish, tutorials, 2D - more and earlier about coordinates transformations. Â· Issue #370 Â· castle-engine/castle-engine Â· GitHub - the patch is a bit obsolete though, as the record member var names were changed later, but the fix is trivial.

Personally i believe it would make your programs safer by clearly documenting developerâ€™s intention and reducing boilerplate.

``````with Location.Props[2].Image do RotationAngle := RotationAngle + Pi/-50;
``````

Michalis is absolutely against this approach, though.
Yet the good thing about opensource - you can easily have your own branch with any tweaks of your own choice

Such `RotationAngle` is a shortcut, and itâ€™s a shortcut with non-obvious meaning to the reader (does it set rotation axis to something hardcoded or leaves it unmodified?).

To be clear, I am not â€śabsolutely against thisâ€ť. I actually added myself in the past to the engine things that are similar (`TCastleTransform.TranslationXY` being the close analogy). I just donâ€™t see it as justified enough, for now. I may change my mind in the future, depending on the usage of CGE Iâ€™ll observe.

â€¦that is exactly why i called it rotationANGLE to stress that it does NOT change the axis - and it actually looks similar to your exampl with translationXY stressing the only coordinates affected

Granted, it would make yet more syntax sugar to have it as an advancd record with AngleIncrease or RotateCCW methods - but this way we rush into â€śrecord copy modificationâ€ť trap

Good day.
I think, my question similar with question from this topic and ask it here.

I plan to smoothly rotate game map with orientation to players point of view, like in road navigator. This is map class:

``````  { Minimap state }
TMinimap = class(TUIState)
private
MapCanvas: array of TCastleImageTransform;
public
constructor CreateMinimap(var Viewport: TCastleViewport; var Point: THero; var GlobalMap: TWorld);
procedure RedrawMinimap(var Point: THero; var GlobalMap: TWorld);
end;
``````

So i have many map tiles in viewport. Can i work with them like one undivided object (like wheel in this example)?

Or easely use SetView method to 3D camera and change direction?

``````Viewport.Camera.SetView(
Vector3(-11.34, 30.04, 96.07), // position
Vector3(0.10, -0.49, -0.87), // direction
Vector3(0.35, 0.83, -0.43), // up (current)
Vector3(0.00, 1.00, 0.00) // gravity up
);
``````

@Noscow My advised solution would be to add all your images to a common parent `TCastleTransform`, and then rotate everything by rotating that single `TCastleTransform` .

I made a quick demo of in editor, see `img-test.castle-user-interface` . `ParentOfImage` is a parent of 9 images. I can rotate all images as a whole by adjusting `ParentOfImage.Rotation`, like `ParentOfImage.Rotation := Vector4(0, 0, 1, 0.75)`. You can test it in editor, but of course you can do the same arrangement and transformations in code too.

my-new-project-test-bbox-gizmo.zip (22.0 KB)

Why I advise it? Because it accounts for various options in the future This way you can still have some things outside of `ParentOfImage` that will not be rotated.

Alternative solution would be to rotate the camera, you can just rotate `Up` to rotate camera around. Or you can assign to camera rotation.

Note: If gizmo in editor disappears when testing it, fear not â†’ I just pushed a solution to it, it will be build in a few hours by Jenkins.

1 Like

So, if i add my images from code, i must first add in Viewport.Items one TCastleImageTransform variable and next put my array with map pictures inside them?
I try like this:

``````  MapCanvas := TCastleImageTransform.Create(FreeAtStop);
for i := 0 to MinimapWidth - 1 do
begin
for j := 0 to MinimapHeight-1 do
begin
MapTiles[TileNumber] := TCastleImageTransform.Create(FreeAtStop);
``````

but i get error:

MinimapUnit.pas(47,22) Error: identifier idents no member â€śMapCanvasâ€ť

It means, compiler is not know this object is already exist?

Oh, i see my mistake, wrong type. I will try again.

But with type of MapCanvas â€śTCastleTransformâ€ť i get same error

1. `MapCanvas` can (and probably should) be just a `TCastleTransform` type, not `TCastleImageTransform`.

`TCastleImageTransform` is a descendant of `TCastleTransform`.

The `TCastleTransform` is something that can have children, and it has translation, rotation, scale.

The `TCastleImageTransform` is like `TCastleTransform` but additional it can display an image.

So in your case, `MapCanvas` (or `ParentOfImages` in the example I attached) can be just `TCastleTransform`. Making it a `TCastleImageTransform` is allowed but a bit pointless â€“ as you do not plan to set `MapCanvas.URL` to point to any image.

This is all documented I advise to follow manual Viewport with scenes, camera, navigation | Manual | Castle Game Engine and follow links from API docs there. E.g. this is API docs for TCastleTransform Castle Game Engine: CastleTransform: Class TCastleTransform , this for TCastleImageTransform: Castle Game Engine: CastleScene: Class TCastleImageTransform .

2. `Viewport.Items.MapCanvas.Add` is not a valid Pascal. It would mean that `MapCanvas` is a property or variable or `Viewport.Items`. But it is not â€“ it is a variable you declared (either in this routine, or in your class â€“ you didnâ€™t attach full source code so I donâ€™t know which).

What you want is just `MapCanvas.Add(MapTiles[TileNum]);`

I would advise to read our â€śintroduction to modern Pascalâ€ť, Modern Object Pascal Introduction for Programmers | Castle Game Engine , and follow examples there. The mistake `Viewport.Items.MapCanvas.Add` suggests you misunderstand how `.` (dot to access properties/methods/fields inside a class) works â€“ maybe the Modern Object Pascal Introduction for Programmers | Castle Game Engine will help I wrote that book exactly with this goal, to help developers to understand the language better. The dot and classes in Pascal are also similar to how classes work in other OOP languages, like C# and Java.

Hope this helps