TCastleControl
is a component you can drop on a Lazarus (LCL) form. It allows to do all CGE rendering and processing as part of a form, and TCastleControl
can be surrounded on your form by any other components.
Note
|
This feature is right now available only for Lazarus (LCL) users. We plan to add it for Delphi, maybe both VCL and FMX, soon. |
Most of this manual describes the process of using the engine with the TCastleWindow
instead of TCastleControl
. All new projects created from editor templates use TCastleWindow
. We generally advise TCastleWindow
, as:
TCastleWindow
works on all CGE platforms (desktop, mobile - Android, iOS, consoles - Nintendo Switch, upcoming web target). It allows us to have true cross-platform projects, that can be recompiled to any supported platform out-of-the-box.
TCastleWindow
allows us to handle events and message loop on the CGE side, and make it efficient. For example, it makes mouse look work perfectly smooth.
On the other hand, using the TCastleControl
has one big benefit: as you place the control inside a form, you can surround it with all the standard LCL GUI controls. So you can use numerous LCL GUI controls, with native look on all desktop systems, together with Castle Game Engine.
We are committed to supporting both approaches (TCastleControl
and TCastleWindow
) in the foreseeable future.
TCastleWindow
and TCastleControl
in a single applicationYou have to make a choice:
Use TCastleWindow
. Use the Application
singleton from CastleWindow
unit to manage these windows.
Use TCastleControl
. Use the LCL forms, along with LCL Application
singleton in the Forms
unit, to manage your application.
You cannot mix these approaches, as neither LCL (in which our TCastleControl
works) nor TCastleWindow
are prepared to handle the situation that they only handle some application forms, and other library handles the other forms.
That is also why we have separate packages
castle_window.lpk
(with TCastleWindow
) and
castle_components.lpk
(with TCastleControl
; a better name would be castle_lcl.lpk
).
You should not use both of these packages at the same time.
Note that, if you use TCastleControl
, it is OK to have multiple TCastleControl
instances visible at the same time. Similarly, if you use TCastleWindow
, you can have several TCastleWindow
instances visible at the same time (but only on desktop platforms), see examples/window/multi_window.
Install in Lazarus the package castle_components.lpk
. In the package dialog, use the option to "Install" (under the "Use" button).
Note: Installing the castle_components
package will also automatically install the package castle_base
, as a dependency. That’s good.
Once castle_components.lpk
is successfully installed, Lazarus restarts, and you should see the "Castle" tab with our components.
Create a normal new LCL project (using Lazarus "New Project" menu item). Choose "Application".
Pick TCastleControl
from the component palette (tab "Castle") and drop it on a regular Lazarus form.
Done. Press "Run" :)
See the engine examples in examples/lazarus/ subdirectory for various demos of this approach.
You can place a simple CastleEngineManifest.xml within your project, like this:
<?xml version="1.0" encoding="utf-8"?>
<project name="my_project"
lazarus_project="my_project.lpi"
build_using_lazbuild="true"
>
</project>
This way you can open this project in the CGE editor, and compile/run it. The line build_using_lazbuild="true"
means that CGE editor and CGE build tool will invoke lazbuild
under the hood.
Essentially, you can initialize your game resources at any time. Even before any TCastleControl
exists. For example in the OnCreate
event of a main form.
Initializing resources inside the TCastleControl.OnOpen
is also a good choice, in typical cases. Since OpenGL context is available at this point, the engine will be able to initialize also GPU resources for things you instantiate at this point.
But note that TCastleControl.OnOpen
runs each time a form with TCastleControl
is opened. Depending on your LCL application organization, if you allow to open this form many times — then TCastleControl.OnOpen
will happen many times. In this case, to execute something really once, just folow the usual LCL approaches (e.g. initialize from a main form, or even from the main program).
In the simple case, you can load a design (file xxx.castle-user-interface
) using TCastleControl.DesignUrl
, and access loaded components using TCastleControl.DesignedComponent
.
In more involved cases, you should use multiple states within your control. In this case, use TUIState
within the TCastleControl
, and load a design (file xxx.castle-user-interface
) inside the state using TUIState.DesignUrl
. This is analogous to our recommended workflow with TCastleWindow
. You can add new state using CGE editor, or just define a new unit like this:
unit GameStateMain;
interface
uses CastleUIState;
type
TStateMain = class(TUIState)
private
{ Components designed using CGE editor, loaded from gamestatemain.castle-user-interface. }
// ...
public
constructor Create(AOwner: TComponent); override;
procedure Start; override;
end;
var
StateMain: TStateMain;
implementation
constructor TStateMain.Create(AOwner: TComponent);
begin
inherited;
DesignUrl := 'castle-data:/gamestatemain.castle-user-interface';
end;
procedure TStateMain.Start;
begin
inherited;
end;
end.
That’s enough to load gamestatemain.castle-user-interface
design from your data
subdirectory.
To initialize this state in your application, you can use this code in TCastleControl.OnOpen
:
TCastleControl.MainControl := MyCastleControl;
StateMain := TStateMain.Create(Application);
TUIState.Current := StateMain;
Note
|
We have an improvement to this approach coming, in branch uistate-to-view. Setting the singleton TCastleControl.MainControl will not be necessary soon. The example how it will work is in examples/lazarus/model_3d_with_2d_controls in that branch. It is not yet merged to master branch.
|
Note
|
This section is important if your TCastleControl is placed on a form together with other LCL controls that may receive focus (that is, key input), like buttons (TButton ) or edit boxes (TEdit ).
|
Like every LCL control, our TCastleControl
receives the keys only when it has focus. The control does not capture all the keys pressed over the form (this would be bad, as other controls, maybe even other TCastleControl
on the same form, may want to handle them). To make sure that controlling the camera by keys (like AWSD or arrows) works, make sure that your control has a focus.
You can call MyCastleControl.SetFocus;
at any time to explicitly make the MyCastleControl
focused. You can assign this to some menu item, or key shortcut handled by form, to allow user to easily switch focus to the TCastleControl
instance.
You can also use TCastleControl.AutoFocus
to make the control automatically focused when user presses mouse over it.
To improve this documentation just edit the source of this page in AsciiDoctor (simple wiki-like syntax) and create a pull request to Castle Game Engine WWW (cge-www) repository.
Copyright Michalis Kamburelis and Castle Game Engine Contributors.
This webpage is also open-source and we welcome pull requests to improve it.
We use cookies for analytics. See our privacy policy.