Trying to build a class inherit form TcastleTransform

Hello, as part of my to learn CGE, I started to program a clone of FlappyBird game.
I made a “small” demo, that you can find here:

https://github.com/Blueicaro/FlappyBird-in-Castle-Game-Engine

You can run it, Press space bar to move the bird, and press enter to generate the pipes.

I wrote this code to generate the pipes (Tuberia is a pipe in spanish):

Tuberia := TuberiaFactory.ComponentLoad(FreeAtStop) as TCastleTransform;
Tuberias.Add(Tuberia);
Tuberia.Translation :=Vector3(0,0,0);

Now I want to move the pipes up down. So I thought in make a a class inherit form TCastleTransform, and in this class put a timer and a speed to move up/down the pipe.

I create the class that inherited from TCastleTransform, but the constructor has other parameters, so I don’t know to continue.
Where can I find a demo or code, how to do this.
Thanks
/BlueIcaro

The TCastleTransform is a descendant from the standard TComponent, so it has an additional “AOwner: TComponent” parameter. In your descendant classes, you need to override it:

type
  TMyDescendant = class(TCastleTransform)
  public
    MyNewField: Integer;
    constructor Create(AOwner: TComponent); override;
  end;

constructor TMyDescendant.Create(AOwner: TComponent);
begin
  inherited;
  MyNewField := 123;
  MyInitialization;
end;

An alternative is to define a constructor with new parameters, and use reintroduce, but then be aware that it will not be executed when deserializing the component or when using it through a class reference. See e.g. castle-engine/examples/physics/physics_asteroids/code/gameviewmain.pas at 68edc4699002d3999acf1c5b0a3405084a4488ef · castle-engine/castle-engine · GitHub . Ignore this if it sounds like black magic :slight_smile:

As a general advise, note that extending functionality by making TCastleTransform descendants is often not the best way.

1 Like

Hello, thanks you very much for detailed answers.

Rewrite the constructor has many unwanted consequences.
I going to work with Behaviors as you say is better choice. I think the code is more clean.
I going study the links that you mentioned. I hope back with my flappyBird game finished.
/BlueIcaro

When I need more parameters for the standard class constructor, I sometimes just use additional procedure. Something like this:

procedure CustomTransform.AfterConstruct(Position : TVector3);
begin
  Translation := Position;
end;

and:

NewTransform := CustomTransform.Create(Owner);
NewTransform.AfterConstruct(PositionVector);

It separate setting logic from creation logic. A dumb but working way :hammer:
Maybe this way not so elegant, but I can be sure constructor works as he must. Not busy about things, that somebody already made fine :upside_down_face:
But I don’t know, is it good for use with the Factory.

1 Like

I think what you show - is a completely normal approach :slight_smile: , so I would not call it “dumb”.

As my wife says: “if something is dumb but works, then it’s not dumb” :slight_smile:

When the component is constructed by deserialization (from .castle-user-interface or such files) or using TCastleComponentFactory then naturally only the standard constructor (Create(SomeOwner)) is called, and you have to make sure to call AfterConstruct (because it needs some parameters that cannot be known at construction) on all instances yourself. Which is OK.

( You can also add more published properties and design your component visually, registering it in the editor, Custom Components | Manual | Castle Game Engine . But this is not supposed to be a “solution for everything” :slight_smile:, i.e. it’s not strictly an “alternative to constructor with parameters”. If you really need to call some additional initialization, with some custom parameters, then a method like AfterConstruct makes total sense IMHO. )