Image upload and gradual rendering

Hello!
For orientation in game world i use minimap. In Lazarus i create it in 2 steps: download all .bmp/.png files into TBitmap variables, and use Canvas to draw map cells around player location. I can make really big map, but draw only then cells, what player can see. I want to carry this in CGE.
I saw isometric_game example code, but don’t understand, how images download to game before drawing. And i little confused by many types in 2D manual :pensive:
Can i download all files in Pascal code and draw it into Viewport item Plane like texture? I think its easyest and faster method at first development steps.

How it looked in Lazarus:
minmap

Loading image is as simple as Castle Game Engine: CastleGLImages: Class TDrawableImage then you draw them by Castle Game Engine: CastleGLImages: Class TDrawableImage :

procedure TMyState.Create(AOwner: TComponent);
begin
  inherited;
  SomeImage := TDrawableImage.Create('castle-data:/image.png');
end;
...
procedure TMyState.Render;
begin
  inherited;
  SomeImage.Draw(XOnScreen, YOnScreen, WidthOnScreen, HeightOnScreen);
end;

There’s a way to significantly optimize this (using batched rendering - up to 100x drawing speed) and make much more “beautiful” (by creating a specific derivative of TCastleUserInterface for rendering the map or minimap), but let’s do one step at a time :slight_smile:

To add to what @eugeneloza writes, the manual page about using images is Images | Manual | Castle Game Engine (I have just improved that page, to incorporate some advises from this and Eugene’s post).

Indeed we have too many types related to images (with time I hope to hide/unify some of the existing practically-internal types).

But the recommendation on that page hopefully helps :slight_smile: The 3 images types (and drawing methods) that we recommend are:

  1. TCastleImageControl . It’s an image that acts as a UI control and you can set it up using code or using CGE editor. It’s a close analogy to using TImage component to put image on form in LCL / VCL. It’s demonstrated in chapter Designing user interface and handling events (press, update) within the state | Manual | Castle Game Engine , you can put them using code or CGE editor.

  2. TCastleImageTransform. It’s an image within a viewport, where you can shift the camera. See Viewport with scenes, camera, navigation | Manual | Castle Game Engine . You can also place such image in a viewport.

    Then you have the full power to combine it with physics, other TCastleScene instances (that can also use animations in any format, like sprite sheets), even with 3D objects. I recently made a video about viewport on Viewports, cameras and navigation in Castle Game Engine - YouTube .

    You can also place such images in CGE editor. So you even don’t need to write code, you can design map in CGE editor. (Though we don’t yet have “snapping” which would be useful for maps.)

  3. Drawing image yourself, using TDrawableImage.

In your case, using TDrawableImage (AD 3) is indeed the most straightforward path to convert your code to CGE.

Depending on what you will need later, I would recommend trying out option AD 2 too (TCastleImageTransform). If you think of later adding there animations, physics, also designing it using CGE editor – then TCastleImageTransform is a more powerful option for the future.

Note: For 2D map, you can also design it using Tiled, https://www.mapeditor.org/ . You can then load ready map in TCastleTiledMapControl. See 2 examples in examples/tiled/. Since 2 days, you can also load Tiled map into TCastleScene, but for now TCastleTiledMapControl support a few more Tiled options.

Thanks, i try both variants. Really, i want to get smooth scrolling and rotation of minimap.

Seems interesting. Right now I’m using a text file with a matrix of cell information to build the game world. This is convenient, because in percpective it will allow to edit a set of cell parameters - nested objects, images, names. I want to assign to each cell many events, like in strategy game Eador, and personal screen like town view in HoMM… But it’s another story, i thunk.
Thanks for help :slightly_smiling_face:

Good day!
How can i get access to ViewPort from code? I can do it for analogy with TCastleLabel with FPS?
I try to add my ViewPort in private of main game state window, but it doesen’t work.
My target is to add and delete child images in TCastleImageTransform to next work with a camera.
I am in the wrong way?
And can i use downlodable from code image in Viewport, if it doesen’t pre-loaded in *.castle-user-interface?


unit GameStateMain;

interface

uses Classes, CastleFilesUtils, CastleGLImages,
  CastleVectors, CastleUIState, CastleComponentSerialize,
  CastleUIControls, CastleControls, CastleKeysMouse;

type
  { Main state, where most of the application logic takes place. }
  TStateMain = class(TUIState)
  private
    { Components designed using CGE editor, loaded from gamestatemain.castle-user-interface. }
    FPS: TCastleLabel;
    Map: TCastleViewport;
    ExampleImage: TDrawableImage;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Start; override;
    procedure Update(const SecondsPassed: Single; var HandleInput: Boolean); override;
    procedure Render; override;
    function Press(const Event: TInputPressRelease): Boolean; override;
  end;

Screenshot_20220813_211938

First of all, while writing the answer to this, I realized I want to have a CGE example that shows this properly :slight_smile: And I actually already planned to make such example. Recently I moved the old isometric_game (using TDrawableImage drawing) to examples/deprecated_to_upgrade/isometric_game/. Today I have implemented a new examples/isometric_game project that shows how to trivially generate a random terrain by adding TCastleTransformImage instances to TCastleViewport.

I have just committed this, it is in examples/isometric_game/ . You can get it by downloading CGE from GitHub, GitHub - castle-engine/castle-engine: Cross-platform (desktop, mobile, console) 3D and 2D game engine supporting many asset formats (glTF, X3D, Spine...) and using modern Object Pascal .

To answer your questions:

The TCastleLabel, TCastleViewport, TCastleImageTransform and all other components you see in the editor are also regular Pascal classes. So yes, you can access them all from code in the same way:

  • you can get an instance that you can have designed, like MainViewport := DesignedComponent('MainViewport') as TCastleViewport;, and then use this instance to change there anything, to add there new children etc.

  • you can also create an instance of any component using code, and then again change anything of this instance.

The examples/isometric_game/ shows this:

  • In this case, I have placed the TCastleViewport using editor (and just access existing instance from code) and I create new TCastleImageTransform instances from code. Many other combinations are possible :), our important feature is that you can mix stuff created in editor with stuff created in code – because, in the end, they are really just the same things.

  • The design of the example is trivial. I started from “Empty” template, added “Viewport 2D” to the design (and renamed it MainViewport), and removed Plane1. I also added “Navigation 2D” to trivially move / zoom within the map in game.

  • The code does the work in TStateMain.Start. That’s really the only interesting piece of code in that example :slight_smile: See it here: castle-engine/gamestatemain.pas at master · castle-engine/castle-engine · GitHub . It could be much shorter, but I wanted to show and document a few things.

  • You can browse the example code and read the README on https://github.com/castle-engine/castle-engine/tree/master/examples/isometric_game

Yes, just set TCastleImageTransform.Url. It can be any URL – to an image in data, like castle-data:/my_image.png (see Data directory | Manual | Castle Game Engine ) or to any file on disk (if you have a filename, you can convert it to URL using FilenameToURLSafe, see Network, downloading and using URLs | Manual | Castle Game Engine ).

Thanks, this example look very useful for me, will study it.