In next chapters you will learn how to add player, creatures and items following our API. But not every game needs to use these high-level concepts, a lot of times your requirements are just I want to add an object to the scene, and be able to move it. You can do it easily in our engine because you can add to your scene manager any 3D object (descendant of T3D), in particular you can add:
TCastleScene: a full-featured 3D or 2D object, you can load it's data from a 3D/2D file (or build it at runtime by building a simple graph of X3D nodes — see examples). It can contain inside animations, interactions, scripting and a lot of other stuff that you can express using VRML / X3D nodes.
Note that it's Ok to add the same instance of TCastleScene (for example, a tree) many times to your scene manager hierarchy. This allows to reuse it's data completely, which is the best for performance/memory!
As a simple example, let's add an animated dragon to our scene. At the beginnig (right after you initialized your 3D world, usually by SceneManager.LoadLevel) you add your 3D objects to the world:
// add to global variables: var DragonTransform: T3DTransform; Dragon: TCastleScene; // ... somewhere after SceneManager.LoadLevel do: DragonTransform := T3DTransform.Create(Application); DragonTransform.Translation := Vector3Single(1, 2, 3); // initial translation SceneManager.Items.Add(DragonTransform); Dragon := TCastleScene.Create(Application); DragonTransform.Add(Dragon); Dragon.Load(ApplicationData('dragon.x3dv')); Dragon.ProcessEvents := true; // enable animations and interactions within dragon.x3dv
procedure WindowUpdate(Container: TUIContainer); // or (in case of Lazarus control): procedure TForm1.CastleControl1Update(Sender: TObject); var SecondsPassed: Single; begin // Note: use CastleControl1.Container.Fps.UpdateSecondsPassed in case of Lazarus control SecondsPassed := Container.Fps.UpdateSecondsPassed; // Move the dragon to the right. // Thanks to multiplying by SecondsPassed, it is a time-based operations, // and will always move 10 units / per second. DragonTransform.Translation := DragonTransform.Translation + Vector3Single(10, 0, 0) * SecondsPassed; end;
That's it, you have a moving 3D object in your world, and the movement in 100% controlled by your code!
For more advanced usage, note that:
You can remove and add these objects during your game freely.
To keep performance, just avoid loading from 3D model files
TCastleScene.Load) during the game,
so you may need to keep some scenes precreated.
Our mechanism of creature/items resources exposes a flexible
approach based on this, but for simple cases you can just do it yourself.
You can override these classes to define your own stuff. These objects can collide and perform AI if you want. Note that every T3D object knows it's World so it knows how to move and collide within the 3D world. That's how AI is implemented. See T3D.Move, T3D.MoveAllowed, T3D.Height and T3D.LineOfSight methods.